Skip to content

Commit

Permalink
Use nodejs to further validate JSON-LD contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
avillar committed Dec 19, 2023
1 parent 5141502 commit aa669ea
Show file tree
Hide file tree
Showing 7 changed files with 285 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
__pycache__
.idea
node_modules/
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ WORKDIR /src
COPY requirements.txt /

RUN apk update && \
apk add git rsync && \
apk add git rsync nodejs npm && \
python -m venv /venv && \
/venv/bin/python -m pip install --upgrade pip && \
git config --global --add safe.directory '*'
git config --global --add safe.directory '*' && \
npm install jsonld

RUN /venv/bin/python -m pip install -r /requirements.txt

ENV PYTHONPATH /src/
ENV PYTHONUNBUFFERED 1
ENV NODE_PATH=/src/node_modules

COPY ogc/ /src/ogc/

Expand Down
20 changes: 15 additions & 5 deletions ogc/bblocks/postprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def postprocess(registered_items_path: str | Path = 'registereditems',
github_base_url: str | None = None,
imported_registers: list[str] | None = None,
bb_filter: str | None = None,
steps: list[str] | None = None) -> list[BuildingBlock]:
steps: list[str] | None = None) -> list[dict]:

cwd = Path().resolve()

Expand Down Expand Up @@ -124,7 +124,7 @@ def do_postprocess(bblock: BuildingBlock, light: bool = False) -> bool:
if base_url:
bblock.metadata['sourceFiles'] = f"{base_url}{rel_files_path}/"
else:
bblock.metadata['sourceFiles'] = f"./{os.path.relpath(rel_files_path, output_file_root)}/"
bblock.metadata['sourceFiles'] = f"./{os.path.relpath(str(rel_files_path), str(output_file_root))}/"

if not light:
if not steps or 'tests' in steps:
Expand Down Expand Up @@ -170,9 +170,6 @@ def do_postprocess(bblock: BuildingBlock, light: bool = False) -> bool:
doc_generator.generate_doc(bblock)
return True

if not isinstance(registered_items_path, Path):
registered_items_path = Path(registered_items_path)

filter_id = None
if bb_filter:
filter_id = False
Expand Down Expand Up @@ -243,6 +240,19 @@ def do_postprocess(bblock: BuildingBlock, light: bool = False) -> bool:
try:
written_context = write_jsonld_context(building_block.annotated_schema)
if written_context:
try:
nodejsrun = subprocess.run([
'node',
str(Path(__file__).parent.joinpath('validation/validate-jsonld.js')),
str(written_context),
], capture_output=True)
if nodejsrun.returncode == 26: # validation error
raise ValueError(nodejsrun.stdout.decode())
elif nodejsrun.returncode == 0:
written_context = f"{written_context} (validated)"
except FileNotFoundError:
# node not installed
pass
print(f" - {written_context}", file=sys.stderr)
except Exception as e:
if fail_on_error:
Expand Down
6 changes: 4 additions & 2 deletions ogc/bblocks/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,11 +467,13 @@ def ref_updater(ref):
return result


def write_jsonld_context(annotated_schema: Path) -> Path | None:
def write_jsonld_context(annotated_schema: Path | str) -> Path | None:
if not isinstance(annotated_schema, Path):
annotated_schema = Path(annotated_schema)
ctx_builder = ContextBuilder(annotated_schema)
if not ctx_builder.context.get('@context'):
return None
context_fn = annotated_schema.parent / 'context.jsonld'
context_fn = annotated_schema.resolve().parent / 'context.jsonld'
with open(context_fn, 'w') as f:
json.dump(ctx_builder.context, f, indent=2)
with open(context_fn.parent / '_visited_properties.tsv', 'w', newline='') as f:
Expand Down
23 changes: 23 additions & 0 deletions ogc/bblocks/validation/validate-jsonld.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const jsonld = require('jsonld');
const util = require('util');
const fs = require('fs');

if (process.argv.length !== 3) {
console.error('File name to validate required');
process.exit(25);
}

const filename = process.argv[2];
const readFile = util.promisify(fs.readFile);
readFile(filename, 'utf-8')
.then(data => JSON.parse(data))
.then(context => jsonld.toRDF(context, {format: 'application/n-quads'}))
.catch(e => {
if (e?.details?.code) {
console.log(`${e.message} (${e.details.code})`);
} else {
console.log(e.message);
}
process.exit(26);
});

233 changes: 233 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"jsonld": "^8.3.2"
}
}

0 comments on commit aa669ea

Please sign in to comment.