Project

General

Profile

« Previous | Next » 

Revision 73a443f5

Added by koszko over 1 year ago

improve loading of schema files

View differences:

src/hydrilla/builder/build.py
51 51

  
52 52
_ = util.translation(here / 'locales').gettext
53 53

  
54
def index_validator(major_schema_version):
55
    """
56
    Create an index.json schema validator specific to the requested schema
57
    version series.
58
    """
59
    exact_version = {1: '1.0.1', 2: '2'}[major_schema_version]
60

  
61
    return util.validator_for(f'package_source-{exact_version}.schema.json')
62

  
63 54
schemas_root = 'https://hydrilla.koszko.org/schemas'
64 55

  
65 56
generated_by = {
......
365 356
        files and computed definitions of the source package and items defined
366 357
        in it.
367 358
        """
368
        index_validator(major_schema_version).validate(index_obj)
359
        schema_name = f'package_source-{major_schema_version}.schema.json';
360

  
361
        util.validator_for(schema_name).validate(index_obj)
369 362

  
370 363
        match = re.match(r'.*-((([1-9][0-9]*|0)\.)+)schema\.json$',
371 364
                         index_obj['$schema'])
src/hydrilla/util/_util.py
117 117
    """
118 118
    return '.'.join([str(n) for n in ver]) + ('' if rev is None else f'-{rev}')
119 119

  
120
_schema_name_re = re.compile(r'''
121
(?P<name_base>[^/]*)
122
-
123
(?P<ver>
124
  (?P<major>[1-9][0-9]*)
125
  (?: # this repeated group matches the remaining version numbers
126
    \.
127
    (?:[1-9][0-9]*|0)
128
  )*
129
)
130
\.schema\.json
131
$
132
''', re.VERBOSE)
133

  
134
schema_paths = {}
135
for path in (here.parent / 'schemas').rglob('*.schema.json'):
136
    match = _schema_name_re.search(path.name)
137
    schema_name_base = match.group('name_base')
138
    schema_ver_list = match.group('ver').split('.')
139

  
140
    for i in range(len(schema_ver_list)):
141
        schema_ver = '.'.join(schema_ver_list[:i+1])
142
        schema_paths[f'{schema_name_base}-{schema_ver}.schema.json'] = path
143

  
144
for name, path in [*schema_paths.items()]:
145
    schema_paths[f'https://hydrilla.koszko.org/schemas/{name}'] = path
146

  
120 147
schemas = {}
121
for series_dir in (here.parent / 'schemas').glob('*.x'):
122
    for path in series_dir.glob("*.schema.json"):
123
        schema = json.loads(path.read_text())
124
        schemas[schema['$id']] = schema
125 148

  
126
common_schema_filename = 'common_definitions-1.schema.json'
127
common_schema_path = here.parent / "schemas" / common_schema_filename
149
def _get_schema(schema_name: str) -> dict:
150
    """Return loaded JSON of the requested schema. Cache results."""
151
    path = schema_paths[schema_name]
152

  
153
    if path not in schemas:
154
        schemas[path] = json.loads(path.read_text())
155

  
156
    return schemas[path]
128 157

  
129 158
def validator_for(schema: Union[str, dict]) -> Draft7Validator:
130 159
    """
......
133 162
    Other schemas under '../schemas' can be referenced.
134 163
    """
135 164
    if isinstance(schema, str):
136
        schema = schemas[f'https://hydrilla.koszko.org/schemas/{schema}']
165
        schema = _get_schema(schema)
137 166

  
138 167
    resolver = RefResolver(
139 168
        base_uri=schema['$id'],
140 169
        referrer=schema,
141
        handlers={'https': lambda uri: schemas[uri]}
170
        handlers={'https': _get_schema}
142 171
    )
143 172

  
144 173
    return Draft7Validator(schema, resolver=resolver)
145 174

  
146
_major_version_re = re.compile(r'''
147
-
148
(?P<major>[1-9][0-9]*)
149
(?: # this repeated group matches the remaining version numbers
150
  \.
151
  (?:[1-9][0-9]*|0)
152
)*
153
\.schema\.json
154
$
155
''', re.VERBOSE)
156

  
157 175
def load_instance_from_file(path: Path) -> tuple[dict, Optional[int]]:
158 176
    """
159 177
    Open a file and load its contents as a JSON document (with additional
......
167 185
    major = None
168 186

  
169 187
    if type(instance) is dict and type(instance.get('$schema')) is str:
170
        match = _major_version_re.search(instance.get('$schema'))
188
        match = _schema_name_re.search(instance.get('$schema'))
171 189
        major = match and int(match.group('major'))
172 190

  
173 191
    return instance, major
tests/test_build.py
20 20
from jsonschema import ValidationError
21 21

  
22 22
from hydrilla import util as hydrilla_util
23
from hydrilla.util._util import _major_version_re
23
from hydrilla.util._util import _schema_name_re
24 24
from hydrilla.builder import build, _version, local_apt
25 25
from hydrilla.builder.common_errors import *
26 26

  
......
595 595
    Select the right JSON schema. Return without errors only if the instance
596 596
    validates against it.
597 597
    """
598
    major = _major_version_re.search(instance['$schema']).group('major')
598
    major = _schema_name_re.search(instance['$schema']).group('major')
599 599
    exact_schema_version = {'1': '1.0.1', '2': '2'}[major]
600 600
    schema_filename = f'{as_what}-{exact_schema_version}.schema.json'
601 601
    hydrilla_util.validator_for(schema_filename).validate(instance)

Also available in: Unified diff