aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWojtek Kosior <koszko@koszko.org>2022-05-31 16:52:14 +0200
committerWojtek Kosior <koszko@koszko.org>2022-05-31 16:52:14 +0200
commit73a443f518be29a50981e7e137e2b4c2c37552dd (patch)
tree31388ae094278b7284c825a940ab57b5113077be
parent2a22a0c8bb692647798ca3874b1c08533307ed96 (diff)
downloadhydrilla-builder-73a443f518be29a50981e7e137e2b4c2c37552dd.tar.gz
hydrilla-builder-73a443f518be29a50981e7e137e2b4c2c37552dd.zip
improve loading of schema files
-rw-r--r--src/hydrilla/builder/build.py13
-rw-r--r--src/hydrilla/util/_util.py58
-rw-r--r--tests/test_build.py4
3 files changed, 43 insertions, 32 deletions
diff --git a/src/hydrilla/builder/build.py b/src/hydrilla/builder/build.py
index 33838f3..a3c55a7 100644
--- a/src/hydrilla/builder/build.py
+++ b/src/hydrilla/builder/build.py
@@ -51,15 +51,6 @@ here = Path(__file__).resolve().parent
_ = util.translation(here / 'locales').gettext
-def index_validator(major_schema_version):
- """
- Create an index.json schema validator specific to the requested schema
- version series.
- """
- exact_version = {1: '1.0.1', 2: '2'}[major_schema_version]
-
- return util.validator_for(f'package_source-{exact_version}.schema.json')
-
schemas_root = 'https://hydrilla.koszko.org/schemas'
generated_by = {
@@ -365,7 +356,9 @@ class Build:
files and computed definitions of the source package and items defined
in it.
"""
- index_validator(major_schema_version).validate(index_obj)
+ schema_name = f'package_source-{major_schema_version}.schema.json';
+
+ util.validator_for(schema_name).validate(index_obj)
match = re.match(r'.*-((([1-9][0-9]*|0)\.)+)schema\.json$',
index_obj['$schema'])
diff --git a/src/hydrilla/util/_util.py b/src/hydrilla/util/_util.py
index 815b7fd..de7435d 100644
--- a/src/hydrilla/util/_util.py
+++ b/src/hydrilla/util/_util.py
@@ -117,14 +117,43 @@ def version_string(ver: list[int], rev: Optional[int]=None) -> str:
"""
return '.'.join([str(n) for n in ver]) + ('' if rev is None else f'-{rev}')
+_schema_name_re = re.compile(r'''
+(?P<name_base>[^/]*)
+-
+(?P<ver>
+ (?P<major>[1-9][0-9]*)
+ (?: # this repeated group matches the remaining version numbers
+ \.
+ (?:[1-9][0-9]*|0)
+ )*
+)
+\.schema\.json
+$
+''', re.VERBOSE)
+
+schema_paths = {}
+for path in (here.parent / 'schemas').rglob('*.schema.json'):
+ match = _schema_name_re.search(path.name)
+ schema_name_base = match.group('name_base')
+ schema_ver_list = match.group('ver').split('.')
+
+ for i in range(len(schema_ver_list)):
+ schema_ver = '.'.join(schema_ver_list[:i+1])
+ schema_paths[f'{schema_name_base}-{schema_ver}.schema.json'] = path
+
+for name, path in [*schema_paths.items()]:
+ schema_paths[f'https://hydrilla.koszko.org/schemas/{name}'] = path
+
schemas = {}
-for series_dir in (here.parent / 'schemas').glob('*.x'):
- for path in series_dir.glob("*.schema.json"):
- schema = json.loads(path.read_text())
- schemas[schema['$id']] = schema
-common_schema_filename = 'common_definitions-1.schema.json'
-common_schema_path = here.parent / "schemas" / common_schema_filename
+def _get_schema(schema_name: str) -> dict:
+ """Return loaded JSON of the requested schema. Cache results."""
+ path = schema_paths[schema_name]
+
+ if path not in schemas:
+ schemas[path] = json.loads(path.read_text())
+
+ return schemas[path]
def validator_for(schema: Union[str, dict]) -> Draft7Validator:
"""
@@ -133,27 +162,16 @@ def validator_for(schema: Union[str, dict]) -> Draft7Validator:
Other schemas under '../schemas' can be referenced.
"""
if isinstance(schema, str):
- schema = schemas[f'https://hydrilla.koszko.org/schemas/{schema}']
+ schema = _get_schema(schema)
resolver = RefResolver(
base_uri=schema['$id'],
referrer=schema,
- handlers={'https': lambda uri: schemas[uri]}
+ handlers={'https': _get_schema}
)
return Draft7Validator(schema, resolver=resolver)
-_major_version_re = re.compile(r'''
--
-(?P<major>[1-9][0-9]*)
-(?: # this repeated group matches the remaining version numbers
- \.
- (?:[1-9][0-9]*|0)
-)*
-\.schema\.json
-$
-''', re.VERBOSE)
-
def load_instance_from_file(path: Path) -> tuple[dict, Optional[int]]:
"""
Open a file and load its contents as a JSON document (with additional
@@ -167,7 +185,7 @@ def load_instance_from_file(path: Path) -> tuple[dict, Optional[int]]:
major = None
if type(instance) is dict and type(instance.get('$schema')) is str:
- match = _major_version_re.search(instance.get('$schema'))
+ match = _schema_name_re.search(instance.get('$schema'))
major = match and int(match.group('major'))
return instance, major
diff --git a/tests/test_build.py b/tests/test_build.py
index c2d8ced..7fedbd5 100644
--- a/tests/test_build.py
+++ b/tests/test_build.py
@@ -20,7 +20,7 @@ from contextlib import contextmanager
from jsonschema import ValidationError
from hydrilla import util as hydrilla_util
-from hydrilla.util._util import _major_version_re
+from hydrilla.util._util import _schema_name_re
from hydrilla.builder import build, _version, local_apt
from hydrilla.builder.common_errors import *
@@ -595,7 +595,7 @@ def try_validate(as_what, instance):
Select the right JSON schema. Return without errors only if the instance
validates against it.
"""
- major = _major_version_re.search(instance['$schema']).group('major')
+ major = _schema_name_re.search(instance['$schema']).group('major')
exact_schema_version = {'1': '1.0.1', '2': '2'}[major]
schema_filename = f'{as_what}-{exact_schema_version}.schema.json'
hydrilla_util.validator_for(schema_filename).validate(instance)