From fe714f66a50bf76be392b04cc19bdbedff0e4212 Mon Sep 17 00:00:00 2001 From: simleo Date: Fri, 19 May 2023 16:10:56 +0200 Subject: [PATCH 1/3] remove version from ComputerLanguage --- rocrate/model/computerlanguage.py | 64 +++++++++---------------------- rocrate/rocrate.py | 5 ++- test/test_workflow_ro_crate.py | 19 +++++++-- 3 files changed, 37 insertions(+), 51 deletions(-) diff --git a/rocrate/model/computerlanguage.py b/rocrate/model/computerlanguage.py index fdb5872..9032570 100644 --- a/rocrate/model/computerlanguage.py +++ b/rocrate/model/computerlanguage.py @@ -59,46 +59,24 @@ def url(self): def url(self, url): self["url"] = url - # Not listed as a property in "https://schema.org/ComputerLanguage" - @property - def version(self): - return self.get("version") - - @version.setter - def version(self, version): - self["version"] = version - - -# For workflow ro-crates. Note that -# https://about.workflowhub.eu/Workflow-RO-Crate/ does not specify versions. -CWL_DEFAULT_VERSION = "1.2" -# https://github.com/galaxyproject/gxformat2 has some info on gxformat2 versions -# version can probably be simply ignored for "native" *.ga workflows -GALAXY_DEFAULT_VERSION = "21.09" -KNIME_DEFAULT_VERSION = "4.5.0" -NEXTFLOW_DEFAULT_VERSION = "21.10" -SNAKEMAKE_DEFAULT_VERSION = "6.13" -COMPSS_DEFAULT_VERSION = "2.10" -AUTOSUBMIT_DEFAULT_VERSION = "3.14" +# See https://w3id.org/workflowhub/workflow-ro-crate/1.0 - -def cwl(crate, version=CWL_DEFAULT_VERSION): +def cwl(crate): id_ = "https://w3id.org/workflowhub/workflow-ro-crate#cwl" return ComputerLanguage(crate, identifier=id_, properties={ "name": "Common Workflow Language", "alternateName": "CWL", "identifier": { - "@id": f"https://w3id.org/cwl/{version}/" + "@id": "https://w3id.org/cwl/" }, "url": { "@id": "https://www.commonwl.org/" - }, - "version": version + } }) -def galaxy(crate, version=GALAXY_DEFAULT_VERSION): +def galaxy(crate): id_ = "https://w3id.org/workflowhub/workflow-ro-crate#galaxy" return ComputerLanguage(crate, identifier=id_, properties={ "name": "Galaxy", @@ -107,12 +85,11 @@ def galaxy(crate, version=GALAXY_DEFAULT_VERSION): }, "url": { "@id": "https://galaxyproject.org/" - }, - "version": version + } }) -def knime(crate, version=KNIME_DEFAULT_VERSION): +def knime(crate): id_ = "https://w3id.org/workflowhub/workflow-ro-crate#knime" return ComputerLanguage(crate, identifier=id_, properties={ "name": "KNIME", @@ -121,12 +98,11 @@ def knime(crate, version=KNIME_DEFAULT_VERSION): }, "url": { "@id": "https://www.knime.com/" - }, - "version": version + } }) -def nextflow(crate, version=NEXTFLOW_DEFAULT_VERSION): +def nextflow(crate): id_ = "https://w3id.org/workflowhub/workflow-ro-crate#nextflow" return ComputerLanguage(crate, identifier=id_, properties={ "name": "Nextflow", @@ -135,12 +111,11 @@ def nextflow(crate, version=NEXTFLOW_DEFAULT_VERSION): }, "url": { "@id": "https://www.nextflow.io/" - }, - "version": version + } }) -def snakemake(crate, version=SNAKEMAKE_DEFAULT_VERSION): +def snakemake(crate): id_ = "https://w3id.org/workflowhub/workflow-ro-crate#snakemake" return ComputerLanguage(crate, identifier=id_, properties={ "name": "Snakemake", @@ -149,28 +124,25 @@ def snakemake(crate, version=SNAKEMAKE_DEFAULT_VERSION): }, "url": { "@id": "https://snakemake.readthedocs.io" - }, - "version": version + } }) -def compss(crate, version=COMPSS_DEFAULT_VERSION): +def compss(crate): return ComputerLanguage(crate, identifier="#compss", properties={ "name": "COMPSs Programming Model", "alternateName": "COMPSs", "url": "http://compss.bsc.es/", - "citation": "https://doi.org/10.1007/s10723-013-9272-5", - "version": version + "citation": "https://doi.org/10.1007/s10723-013-9272-5" }) -def autosubmit(crate, version=AUTOSUBMIT_DEFAULT_VERSION): +def autosubmit(crate): return ComputerLanguage(crate, identifier="#autosubmit", properties={ "name": "Autosubmit", "alternateName": "AS", "url": "https://autosubmit.readthedocs.io/", - "citation": "https://doi.org/10.1109/HPCSim.2016.7568429", - "version": version + "citation": "https://doi.org/10.1109/HPCSim.2016.7568429" }) @@ -185,9 +157,9 @@ def autosubmit(crate, version=AUTOSUBMIT_DEFAULT_VERSION): } -def get_lang(crate, name, version=None): +def get_lang(crate, name): try: func = LANG_MAP[name.lower()] except KeyError: raise ValueError(f"Unknown language: {name}") - return func(crate, version=version) if version else func(crate) + return func(crate) diff --git a/rocrate/rocrate.py b/rocrate/rocrate.py index 79a5955..c541302 100644 --- a/rocrate/rocrate.py +++ b/rocrate/rocrate.py @@ -438,8 +438,11 @@ def add_workflow( if isinstance(lang, ComputerLanguage): assert lang.crate is self else: - kwargs = {"version": lang_version} if lang_version else {} + kwargs = {} + lang_str = lang lang = get_lang(self, lang, **kwargs) + if lang_str.lower() == "cwl" and lang_version: + lang["identifier"] = f"https://w3id.org/cwl/{lang_version}/" self.add(lang) lang_str = lang.id.rsplit("#", 1)[1] workflow.lang = lang diff --git a/test/test_workflow_ro_crate.py b/test/test_workflow_ro_crate.py index 13d232e..8a5b77a 100644 --- a/test/test_workflow_ro_crate.py +++ b/test/test_workflow_ro_crate.py @@ -16,8 +16,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +import pytest + from rocrate.rocrate import ROCrate, make_workflow_rocrate -from rocrate.model.computerlanguage import CWL_DEFAULT_VERSION, GALAXY_DEFAULT_VERSION WF_CRATE = "https://w3id.org/workflowhub/workflow-ro-crate" @@ -33,7 +34,6 @@ def test_galaxy_wf_crate(test_data_dir, tmpdir, helpers): assert wf_crate.mainEntity is wf lang = wf_crate.dereference(f"{WF_CRATE}#galaxy") assert hasattr(lang, "name") - assert lang.version == GALAXY_DEFAULT_VERSION assert wf.get("programmingLanguage") is lang assert wf.get("subjectOf") is not None assert helpers.WORKFLOW_DESC_TYPES.issubset(wf["subjectOf"].type) @@ -68,7 +68,6 @@ def test_cwl_wf_crate(test_data_dir, tmpdir, helpers): assert wf_crate.mainEntity is wf lang = wf_crate.dereference(f"{WF_CRATE}#cwl") assert hasattr(lang, "name") - assert lang.version == CWL_DEFAULT_VERSION assert wf.get("programmingLanguage") is lang assert "subjectOf" not in wf @@ -99,7 +98,6 @@ def test_create_wf_include(test_data_dir, tmpdir, helpers): assert wf_crate.mainEntity is wf lang = wf_crate.dereference(f"{WF_CRATE}#galaxy") assert hasattr(lang, "name") - assert lang.version == GALAXY_DEFAULT_VERSION assert wf.get("programmingLanguage") is lang assert wf.get("subjectOf") is not None assert helpers.WORKFLOW_DESC_TYPES.issubset(wf["subjectOf"].type) @@ -124,3 +122,16 @@ def test_create_wf_include(test_data_dir, tmpdir, helpers): assert file2.exists() with open(extra_file2) as f1, open(file2) as f2: assert f1.read() == f2.read() + + +@pytest.mark.parametrize("lang_version", [None, "1.2"]) +def test_cwl_lang_version(test_data_dir, lang_version): + wf_id = 'sample_cwl_wf.cwl' + wf_path = test_data_dir / wf_id + crate = ROCrate() + workflow = crate.add_workflow(wf_path, wf_id, lang_version=lang_version) + lang_id = workflow["programmingLanguage"]["identifier"] + if lang_version is None: + assert lang_id == "https://w3id.org/cwl/" + else: + assert lang_id == "https://w3id.org/cwl/1.2/" From bae7b42dd92e1647fb5fc95bcd9fba026b8aeb90 Mon Sep 17 00:00:00 2001 From: simleo Date: Mon, 29 May 2023 12:07:44 +0200 Subject: [PATCH 2/3] ComputerLanguage: remove only version defaults --- rocrate/model/computerlanguage.py | 85 ++++++++++++++++++++++--------- rocrate/rocrate.py | 6 +-- test/test_workflow_ro_crate.py | 8 ++- 3 files changed, 68 insertions(+), 31 deletions(-) diff --git a/rocrate/model/computerlanguage.py b/rocrate/model/computerlanguage.py index 9032570..a7c7260 100644 --- a/rocrate/model/computerlanguage.py +++ b/rocrate/model/computerlanguage.py @@ -59,26 +59,43 @@ def url(self): def url(self, url): self["url"] = url + # Not listed as a property in "https://schema.org/ComputerLanguage" + @property + def version(self): + return self.get("version") + + @version.setter + def version(self, version): + self["version"] = version + # See https://w3id.org/workflowhub/workflow-ro-crate/1.0 +# (note that it does not specify "version") -def cwl(crate): + +def cwl(crate, version=None): id_ = "https://w3id.org/workflowhub/workflow-ro-crate#cwl" - return ComputerLanguage(crate, identifier=id_, properties={ + identifier = "https://w3id.org/cwl/" + if version: + identifier = f"{identifier}{version}/" + properties = { "name": "Common Workflow Language", "alternateName": "CWL", "identifier": { - "@id": "https://w3id.org/cwl/" + "@id": identifier }, "url": { "@id": "https://www.commonwl.org/" - } - }) + }, + } + if version: + properties["version"] = version + return ComputerLanguage(crate, identifier=id_, properties=properties) -def galaxy(crate): +def galaxy(crate, version=None): id_ = "https://w3id.org/workflowhub/workflow-ro-crate#galaxy" - return ComputerLanguage(crate, identifier=id_, properties={ + properties = { "name": "Galaxy", "identifier": { "@id": "https://galaxyproject.org/" @@ -86,12 +103,15 @@ def galaxy(crate): "url": { "@id": "https://galaxyproject.org/" } - }) + } + if version: + properties["version"] = version + return ComputerLanguage(crate, identifier=id_, properties=properties) -def knime(crate): +def knime(crate, version=None): id_ = "https://w3id.org/workflowhub/workflow-ro-crate#knime" - return ComputerLanguage(crate, identifier=id_, properties={ + properties = { "name": "KNIME", "identifier": { "@id": "https://www.knime.com/" @@ -99,12 +119,15 @@ def knime(crate): "url": { "@id": "https://www.knime.com/" } - }) + } + if version: + properties["version"] = version + return ComputerLanguage(crate, identifier=id_, properties=properties) -def nextflow(crate): +def nextflow(crate, version=None): id_ = "https://w3id.org/workflowhub/workflow-ro-crate#nextflow" - return ComputerLanguage(crate, identifier=id_, properties={ + properties = { "name": "Nextflow", "identifier": { "@id": "https://www.nextflow.io/" @@ -112,12 +135,15 @@ def nextflow(crate): "url": { "@id": "https://www.nextflow.io/" } - }) + } + if version: + properties["version"] = version + return ComputerLanguage(crate, identifier=id_, properties=properties) -def snakemake(crate): +def snakemake(crate, version=None): id_ = "https://w3id.org/workflowhub/workflow-ro-crate#snakemake" - return ComputerLanguage(crate, identifier=id_, properties={ + properties = { "name": "Snakemake", "identifier": { "@id": "https://doi.org/10.1093/bioinformatics/bts480" @@ -125,25 +151,34 @@ def snakemake(crate): "url": { "@id": "https://snakemake.readthedocs.io" } - }) + } + if version: + properties["version"] = version + return ComputerLanguage(crate, identifier=id_, properties=properties) -def compss(crate): - return ComputerLanguage(crate, identifier="#compss", properties={ +def compss(crate, version=None): + properties = { "name": "COMPSs Programming Model", "alternateName": "COMPSs", "url": "http://compss.bsc.es/", "citation": "https://doi.org/10.1007/s10723-013-9272-5" - }) + } + if version: + properties["version"] = version + return ComputerLanguage(crate, identifier="#compss", properties=properties) -def autosubmit(crate): - return ComputerLanguage(crate, identifier="#autosubmit", properties={ +def autosubmit(crate, version=None): + properties = { "name": "Autosubmit", "alternateName": "AS", "url": "https://autosubmit.readthedocs.io/", "citation": "https://doi.org/10.1109/HPCSim.2016.7568429" - }) + } + if version: + properties["version"] = version + return ComputerLanguage(crate, identifier="#autosubmit", properties=properties) LANG_MAP = { @@ -157,9 +192,9 @@ def autosubmit(crate): } -def get_lang(crate, name): +def get_lang(crate, name, version=None): try: func = LANG_MAP[name.lower()] except KeyError: raise ValueError(f"Unknown language: {name}") - return func(crate) + return func(crate, version=version) diff --git a/rocrate/rocrate.py b/rocrate/rocrate.py index c541302..e209495 100644 --- a/rocrate/rocrate.py +++ b/rocrate/rocrate.py @@ -438,11 +438,7 @@ def add_workflow( if isinstance(lang, ComputerLanguage): assert lang.crate is self else: - kwargs = {} - lang_str = lang - lang = get_lang(self, lang, **kwargs) - if lang_str.lower() == "cwl" and lang_version: - lang["identifier"] = f"https://w3id.org/cwl/{lang_version}/" + lang = get_lang(self, lang, version=lang_version) self.add(lang) lang_str = lang.id.rsplit("#", 1)[1] workflow.lang = lang diff --git a/test/test_workflow_ro_crate.py b/test/test_workflow_ro_crate.py index 8a5b77a..0c3b2f1 100644 --- a/test/test_workflow_ro_crate.py +++ b/test/test_workflow_ro_crate.py @@ -34,6 +34,7 @@ def test_galaxy_wf_crate(test_data_dir, tmpdir, helpers): assert wf_crate.mainEntity is wf lang = wf_crate.dereference(f"{WF_CRATE}#galaxy") assert hasattr(lang, "name") + assert "version" not in lang assert wf.get("programmingLanguage") is lang assert wf.get("subjectOf") is not None assert helpers.WORKFLOW_DESC_TYPES.issubset(wf["subjectOf"].type) @@ -68,6 +69,7 @@ def test_cwl_wf_crate(test_data_dir, tmpdir, helpers): assert wf_crate.mainEntity is wf lang = wf_crate.dereference(f"{WF_CRATE}#cwl") assert hasattr(lang, "name") + assert "version" not in lang assert wf.get("programmingLanguage") is lang assert "subjectOf" not in wf @@ -98,6 +100,7 @@ def test_create_wf_include(test_data_dir, tmpdir, helpers): assert wf_crate.mainEntity is wf lang = wf_crate.dereference(f"{WF_CRATE}#galaxy") assert hasattr(lang, "name") + assert "version" not in lang assert wf.get("programmingLanguage") is lang assert wf.get("subjectOf") is not None assert helpers.WORKFLOW_DESC_TYPES.issubset(wf["subjectOf"].type) @@ -130,8 +133,11 @@ def test_cwl_lang_version(test_data_dir, lang_version): wf_path = test_data_dir / wf_id crate = ROCrate() workflow = crate.add_workflow(wf_path, wf_id, lang_version=lang_version) - lang_id = workflow["programmingLanguage"]["identifier"] + lang = workflow["programmingLanguage"] + lang_id = lang["identifier"] if lang_version is None: assert lang_id == "https://w3id.org/cwl/" + assert "version" not in lang else: assert lang_id == "https://w3id.org/cwl/1.2/" + assert lang["version"] == "1.2" From 71ad688c4a19186a2e6bdef821a15dbbace1a5b6 Mon Sep 17 00:00:00 2001 From: simleo Date: Mon, 29 May 2023 12:18:32 +0200 Subject: [PATCH 3/3] fix CWL versioned URL --- rocrate/model/computerlanguage.py | 2 +- test/test_workflow_ro_crate.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rocrate/model/computerlanguage.py b/rocrate/model/computerlanguage.py index a7c7260..014bdc0 100644 --- a/rocrate/model/computerlanguage.py +++ b/rocrate/model/computerlanguage.py @@ -77,7 +77,7 @@ def cwl(crate, version=None): id_ = "https://w3id.org/workflowhub/workflow-ro-crate#cwl" identifier = "https://w3id.org/cwl/" if version: - identifier = f"{identifier}{version}/" + identifier = f"{identifier}v{version}/" properties = { "name": "Common Workflow Language", "alternateName": "CWL", diff --git a/test/test_workflow_ro_crate.py b/test/test_workflow_ro_crate.py index 0c3b2f1..6deed65 100644 --- a/test/test_workflow_ro_crate.py +++ b/test/test_workflow_ro_crate.py @@ -139,5 +139,5 @@ def test_cwl_lang_version(test_data_dir, lang_version): assert lang_id == "https://w3id.org/cwl/" assert "version" not in lang else: - assert lang_id == "https://w3id.org/cwl/1.2/" + assert lang_id == "https://w3id.org/cwl/v1.2/" assert lang["version"] == "1.2"