diff options
-rw-r--r-- | setup.cfg | 1 | ||||
-rw-r--r-- | src/hydrilla/builder/build.py | 8 | ||||
m--------- | src/hydrilla/schemas | 0 | ||||
-rw-r--r-- | src/hydrilla/util/__init__.py | 2 | ||||
-rw-r--r-- | src/hydrilla/util/_util.py | 28 | ||||
-rw-r--r-- | src/test/test_hydrilla_builder.py | 12 |
6 files changed, 42 insertions, 9 deletions
@@ -34,6 +34,7 @@ packages = find: include_package_data=True install_requires = click + jsonschema importlib; python_version == "2.6" # reuse is optional: # reuse diff --git a/src/hydrilla/builder/build.py b/src/hydrilla/builder/build.py index dae5579..3503f7a 100644 --- a/src/hydrilla/builder/build.py +++ b/src/hydrilla/builder/build.py @@ -35,7 +35,7 @@ import jsonschema from .. import util -index_json_schema = util.load_schema('package_source-1.schema.json') +index_validator = util.validator_for('package_source-1.schema.json') class FileReferenceError(Exception): """ @@ -275,8 +275,8 @@ class Build: item_list.append(new_item_obj) - return dict([(prop, new_item_obj[prop]) - for prop in ('type', 'identifier', 'version')]) + props_in_ref = ('type', 'identifier', 'version', 'long_name') + return dict([(prop, new_item_obj[prop]) for prop in props_in_ref]) def _process_index_json(self, index_obj: dict): """ @@ -285,7 +285,7 @@ class Build: files and computed definitions of the source package and items defined in it. """ - jsonschema.validate(index_obj, index_json_schema) + index_validator.validate(index_obj) self.source_name = index_obj['source_name'] diff --git a/src/hydrilla/schemas b/src/hydrilla/schemas -Subproject ca1de2ed4a69a71f2f75552ade693d04ea1baa8 +Subproject c72c8438875d20b156d22d975523a19bbb407d9 diff --git a/src/hydrilla/util/__init__.py b/src/hydrilla/util/__init__.py index d435c0a..2a69e0d 100644 --- a/src/hydrilla/util/__init__.py +++ b/src/hydrilla/util/__init__.py @@ -5,4 +5,4 @@ # Available under the terms of Creative Commons Zero v1.0 Universal. from ._util import strip_json_comments, normalize_version, parse_version, \ - version_string, load_schema + version_string, validator_for diff --git a/src/hydrilla/util/_util.py b/src/hydrilla/util/_util.py index 0ce62f6..9bebdc1 100644 --- a/src/hydrilla/util/_util.py +++ b/src/hydrilla/util/_util.py @@ -30,6 +30,8 @@ import json from pathlib import Path from typing import Optional +from jsonschema import RefResolver, Draft7Validator + here = Path(__file__).resolve().parent _strip_comment_re = re.compile(r''' @@ -103,7 +105,25 @@ 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}') -def load_schema(schema_filename: str) -> dict: - """Find schema JSON file in '../schemas' and json.load() it.""" - with open(here.parent / 'schemas' / schema_filename, 'rt') as file_handle: - return json.load(file_handle) +schemas = {} +for path in (here.parent / 'schemas').glob('*-1.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 + +resolver = RefResolver( + base_uri=f'file://{str(common_schema_path)}', + referrer=f'https://hydrilla.koszko.org/{common_schema_filename}', + store=schemas +) + +def validator_for(schema_filename: str) -> Draft7Validator: + """ + Prepare a validator for one of the schemas in '../schemas'. + + This function is not thread-safe. + """ + return Draft7Validator(resolver.resolve(schema_filename)[1], + resolver=resolver) diff --git a/src/test/test_hydrilla_builder.py b/src/test/test_hydrilla_builder.py index 605dc31..0b6244f 100644 --- a/src/test/test_hydrilla_builder.py +++ b/src/test/test_hydrilla_builder.py @@ -148,14 +148,17 @@ class CaseSettings: 'definitions': [{ 'type': 'resource', 'identifier': 'helloapple', + 'long_name': 'Hello Apple', 'version': [2021, 11, 10], }, { 'type': 'resource', 'identifier': 'hello-message', + 'long_name': 'Hello Message', 'version': [2021, 11, 10], }, { 'type': 'mapping', 'identifier': 'helloapple', + 'long_name': 'Hello Apple', 'version': [2021, 11, 10], }] } @@ -346,6 +349,9 @@ def test_build(tmpdir, prepare_source_example): with open(subdir / '2021.11.10', 'rt') as file_handle: assert json.load(file_handle) == resource_json + hydrilla_util.validator_for('api_resource_description-1.schema.json')\ + .validate(resource_json) + # Verify files under 'mapping/' mapping_dir = dstdir / 'mapping' assert ['helloapple'] == [path.name for path in mapping_dir.iterdir()] @@ -356,6 +362,9 @@ def test_build(tmpdir, prepare_source_example): with open(subdir / '2021.11.10', 'rt') as file_handle: assert json.load(file_handle) == settings.expected_mapping + hydrilla_util.validator_for('api_mapping_description-1.schema.json')\ + .validate(settings.expected_mapping) + # Verify files under 'source/' source_dir = dstdir / 'source' assert {'hello.json', 'hello.zip'} == \ @@ -377,6 +386,9 @@ def test_build(tmpdir, prepare_source_example): with open(source_dir / 'hello.json', 'rt') as file_handle: assert json.load(file_handle) == settings.expected_source_description + hydrilla_util.validator_for('api_source_description-1.schema.json')\ + .validate(settings.expected_source_description) + def modify_index_missing_file(dummy: CaseSettings, obj: dict) -> None: """ Modify index.json to expect missing report.spdx file and cause an error. |