diff --git a/build.py b/build.py new file mode 100755 index 00000000..3124f4fc --- /dev/null +++ b/build.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +import os +import subprocess +import sys +from linkml.generators.shaclgen import ShaclGenerator +import linkml._version as linkml_version + + +def convert_to_shacl(input_file: str, output_file: str): + # Generate shacl + shacl_shapes = ShaclGenerator(input_file).serialize() + + comment = ( + f"# This SHACL file was auto-generated with LinkML {linkml_version.__version__}.\n" + f"#Changes will be overwritten on install.\n" + f"# Source file: {input_file}\n" + "\n" + ) + + # Run the command and redirect output to the output file + with open(output_file, "w") as outfile: + outfile.write(comment) + outfile.write(shacl_shapes) + + +def convert_folder_recursively(path: str, force: bool = False): + # recursively iterate through subfolders searching for yaml files + for root, _, files, in os.walk(path): + for file in files: + + # skip non-yaml files + if not file.endswith(".yaml"): + continue + + input_file = os.path.join(root, file) + output_file = input_file.replace(".yaml", ".ttl") + if force or not os.path.exists(output_file) or os.path.getmtime(input_file) > os.path.getmtime(output_file): + print("Converting", input_file) + convert_to_shacl(input_file, output_file) + + +if __name__ == "__main__": + convert_folder_recursively("rocrate_validator/profiles", force="--force" in sys.argv) diff --git a/pyproject.toml b/pyproject.toml index a385af64..ccaa42df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,9 +51,13 @@ pytest-xdist = "^3.6.1" max-line-length = 120 [build-system] -requires = ["poetry-core"] +requires = ["poetry-core", "linkml"] build-backend = "poetry.core.masonry.api" +[tool.poetry.build] +generate-setup-file = false +script = "build.py" + [tool.poetry.scripts] rocrate-validator = "rocrate_validator.cli:cli" diff --git a/rocrate_validator/profiles/workflow-ro-crate-linkml/workflow-ro-crate.ttl b/rocrate_validator/profiles/workflow-ro-crate-linkml/workflow-ro-crate.ttl deleted file mode 100644 index e686637d..00000000 --- a/rocrate_validator/profiles/workflow-ro-crate-linkml/workflow-ro-crate.ttl +++ /dev/null @@ -1,40 +0,0 @@ -@prefix rdf: . -@prefix ro-crate: . -@prefix schema1: . -@prefix sh: . -@prefix xsd: . - -ro-crate:RootDataEntity a sh:NodeShape ; - sh:closed false ; - sh:ignoredProperties ( rdf:type ) ; - sh:property [ sh:class schema1:CreativeWork ; - sh:description "Check if the Main Workflow is specified through a `mainEntity` property in the root data entity" ; - sh:maxCount 1 ; - sh:message "The Main Workflow must be specified through a `mainEntity` property in the root data entity"^^xsd:string ; - sh:minCount 1 ; - sh:nodeKind sh:BlankNodeOrIRI ; - sh:order 0 ; - sh:path schema1:mainEntity ] ; - sh:targetClass ro-crate:RootDataEntity . - - a sh:NodeShape ; - sh:closed false ; - sh:description "The Main Workflow must be specified through a `mainEntity` property in the root data entity" ; - sh:ignoredProperties ( rdf:type ) ; - sh:name "Main Workflow entity existence" ; - sh:property [ sh:class schema1:CreativeWork ; - sh:description "Check if the Main Workflow is specified through a `mainEntity` property in the root data entity" ; - sh:maxCount 1 ; - sh:message "The Main Workflow must be specified through a `mainEntity` property in the root data entity"^^xsd:string ; - sh:minCount 1 ; - sh:nodeKind sh:BlankNodeOrIRI ; - sh:order 0 ; - sh:path schema1:mainEntity ] ; - sh:targetClass . - -schema1:CreativeWork a sh:NodeShape ; - sh:closed false ; - sh:ignoredProperties ( rdf:type ) ; - sh:targetClass schema1:CreativeWork . - - diff --git a/tests/conftest.py b/tests/conftest.py index 47a867cf..88cef2d2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,8 +15,9 @@ # calculate the absolute path of the rocrate-validator package # and add it to the system path import os +import subprocess -from pytest import fixture +from pytest import fixture, hookimpl import rocrate_validator.log as logging @@ -37,6 +38,12 @@ PROFILES_PATH = os.path.abspath(f"{CURRENT_PATH}/../rocrate_validator/profiles") +@hookimpl(tryfirst=True) +def pytest_configure(): + # make sure all linkml files are converted to shacl + subprocess.run(["python", "build.py"], check=True) + + @fixture def random_path(): return "/tmp/random_path"