70 lines
2.1 KiB
Python
70 lines
2.1 KiB
Python
from typesystem import (
|
|
Schema, SchemaDefinitions,
|
|
String, Text, Boolean, Choice,
|
|
Array, Reference,
|
|
)
|
|
|
|
definitions = SchemaDefinitions()
|
|
|
|
|
|
class Tag(Schema, definitions=definitions):
|
|
name = String(min_length=1)
|
|
description = Text(allow_null=True)
|
|
|
|
|
|
class Alias(Schema, definitions=definitions):
|
|
name = String(min_length=1)
|
|
description = Text(allow_null=True)
|
|
type = Choice(choices=[
|
|
('alias', 'A shell alias'),
|
|
('git', 'A Git alias'),
|
|
('function', 'A shell function'),
|
|
], default='alias')
|
|
value = Text(min_length=1)
|
|
private = Boolean(
|
|
default=False,
|
|
description='Exclude this alias from public templates.',
|
|
)
|
|
hosts = Array(
|
|
items=String(min_length=1, pattern=r'^[A-Za-z0-9-_]+$'),
|
|
unique_items=True,
|
|
default=list,
|
|
description='Restrict this alias to a specific list of hosts '
|
|
'when synchronizing.',
|
|
)
|
|
tag = String(allow_null=True)
|
|
|
|
|
|
class Document(Schema, definitions=definitions):
|
|
tags = Array(items=Reference(to=Tag), default=list)
|
|
aliases = Array(items=Reference(to=Alias), min_items=1)
|
|
|
|
@classmethod
|
|
def validate(cls, value, *, strict=False):
|
|
doc = super().validate(value=value, strict=strict)
|
|
|
|
tag_names = set()
|
|
for tag in doc.tags:
|
|
if tag.name in tag_names:
|
|
raise ValidationError(
|
|
'Tag name {!r} is defined multiple times'.format(tag.name)
|
|
)
|
|
tag_names.add(tag.name)
|
|
|
|
alias_names = set()
|
|
for alias in doc.aliases:
|
|
if alias.name in alias_names:
|
|
raise ValidationError(
|
|
'Alias name {!r} '
|
|
'is defined multiple times'.format(alias.name)
|
|
)
|
|
alias_names.add(alias.name)
|
|
|
|
if alias.tag and alias.tag not in tag_names:
|
|
raise ValidationError(
|
|
'Alias {!r} refers to unknown tag {!r}'.format(
|
|
alias.name, alias.tag)
|
|
)
|
|
|
|
return doc
|