diff --git a/nf_core/pipelines/lint/version_consistency.py b/nf_core/pipelines/lint/version_consistency.py index a02b06ac2b..e344d25e5d 100644 --- a/nf_core/pipelines/lint/version_consistency.py +++ b/nf_core/pipelines/lint/version_consistency.py @@ -1,4 +1,7 @@ import os +from pathlib import Path + +from ruamel.yaml import YAML def version_consistency(self): @@ -7,7 +10,7 @@ def version_consistency(self): .. note:: This test only runs when the ``--release`` flag is set for ``nf-core pipelines lint``, or ``$GITHUB_REF`` is equal to ``main``. - This lint fetches the pipeline version number from three possible locations: + This lint fetches the pipeline version number from four possible locations: * The pipeline config, ``manifest.version`` * The docker container in the pipeline config, ``process.container`` @@ -15,6 +18,7 @@ def version_consistency(self): Some pipelines may not have this set on a pipeline level. If it is not found, it is ignored. * ``$GITHUB_REF``, if it looks like a release tag (``refs/tags/``) + * The YAML file .nf-core.yml The test then checks that: @@ -45,6 +49,12 @@ def version_consistency(self): ): versions["GITHUB_REF"] = os.path.basename(os.environ["GITHUB_REF"].strip(" '\"")) + # Get version from the .nf-core.yml template + yaml = YAML() + nfcore_yml = yaml.load(Path(self.wf_path) / ".nf-core.yml") + if nfcore_yml["template"] and "version" in nfcore_yml["template"]: + versions["nfcore_yml.version"] = nfcore_yml["template"]["version"].strip(" '\"") + # Check if they are all numeric for v_type, version in versions.items(): if not version.replace(".", "").isdigit(): @@ -57,7 +67,7 @@ def version_consistency(self): ", ".join([f"{k} = {v}" for k, v in versions.items()]) ) ) - - passed.append("Version tags are numeric and consistent between container, release tag and config.") + else: + passed.append("Version tags are consistent: {}".format(", ".join([f"{k} = {v}" for k, v in versions.items()]))) return {"passed": passed, "failed": failed} diff --git a/tests/pipelines/lint/test_version_consistency.py b/tests/pipelines/lint/test_version_consistency.py index c5a2cc74f1..32f24fa2d0 100644 --- a/tests/pipelines/lint/test_version_consistency.py +++ b/tests/pipelines/lint/test_version_consistency.py @@ -1,19 +1,82 @@ +import re +from pathlib import Path + +from ruamel.yaml import YAML + import nf_core.pipelines.create.create import nf_core.pipelines.lint +from nf_core.utils import NFCoreYamlConfig from ..test_lint import TestLint class TestLintVersionConsistency(TestLint): - def test_version_consistency(self): - """Tests that config variable existence test fails with bad pipeline name""" - new_pipeline = self._make_pipeline_copy() - lint_obj = nf_core.pipelines.lint.PipelineLint(new_pipeline) + def setUp(self) -> None: + super().setUp() + self.new_pipeline = self._make_pipeline_copy() + self.nf_core_yml_path = Path(self.new_pipeline) / ".nf-core.yml" + self.yaml = YAML() + self.nf_core_yml: NFCoreYamlConfig = self.yaml.load(self.nf_core_yml_path) + + def test_version_consistency_pass(self): + """Tests that pipeline version consistency test passes with good pipeline version""" + # Declare the pipeline version in the .nf-core.yml file + self.nf_core_yml["template"]["version"] = "1.0.0" + self.yaml.dump(self.nf_core_yml, self.nf_core_yml_path) + + # Set the version in the nextflow.config file + nf_conf_file = Path(self.new_pipeline, "nextflow.config") + with open(nf_conf_file) as f: + content = f.read() + pass_content = re.sub(r"(?m)^(?P\s*version\s*=\s*)'[^']+'", rf"\g'{'1.0.0'}'", content) + with open(nf_conf_file, "w") as f: + f.write(pass_content) + + lint_obj = nf_core.pipelines.lint.PipelineLint(self.new_pipeline) lint_obj.load_pipeline_config() lint_obj.nextflow_config() + # Set the version for the container + lint_obj.nf_config["process.container"] = "nfcore/pipeline:1.0.0" + result = lint_obj.version_consistency() + assert result["passed"] == [ + "Version tags are consistent: manifest.version = 1.0.0, process.container = 1.0.0, nfcore_yml.version = 1.0.0", + ] + assert result["failed"] == [] + + def test_version_consistency_not_numeric(self): + """Tests that pipeline version consistency test fails with non-numeric version numbers""" + self.nf_core_yml["template"]["version"] = "1.0.0dev" + self.yaml.dump(self.nf_core_yml, self.nf_core_yml_path) + lint_obj = nf_core.pipelines.lint.PipelineLint(self.new_pipeline) + lint_obj.load_pipeline_config() + lint_obj.nextflow_config() result = lint_obj.version_consistency() assert result["passed"] == [ - "Version tags are numeric and consistent between container, release tag and config." + "Version tags are consistent: manifest.version = 1.0.0dev, nfcore_yml.version = 1.0.0dev" + ] + assert result["failed"] == [ + "manifest.version was not numeric: 1.0.0dev!", + "nfcore_yml.version was not numeric: 1.0.0dev!", + ] + + def test_version_consistency_not_consistent(self): + """Tests that pipeline version consistency test fails with inconsistent version numbers""" + self.nf_core_yml["template"]["version"] = "0.0.0" + self.yaml.dump(self.nf_core_yml, self.nf_core_yml_path) + nf_conf_file = Path(self.new_pipeline, "nextflow.config") + with open(nf_conf_file) as f: + content = f.read() + fail_content = re.sub(r"(?m)^(?P\s*version\s*=\s*)'[^']+'", rf"\g'{'1.0.0'}'", content) + with open(nf_conf_file, "w") as f: + f.write(fail_content) + lint_obj = nf_core.pipelines.lint.PipelineLint(self.new_pipeline) + lint_obj.load_pipeline_config() + lint_obj.nextflow_config() + + lint_obj.nf_config["process.container"] = "nfcore/pipeline:0.1" + result = lint_obj.version_consistency() + assert len(result["passed"]) == 0 + assert result["failed"] == [ + "The versioning is not consistent between container, release tag and config. Found manifest.version = 1.0.0, process.container = 0.1, nfcore_yml.version = 0.0.0", ] - assert result["failed"] == ["manifest.version was not numeric: 1.0.0dev!"]