Skip to content

Commit

Permalink
Merge pull request #2874 from nf-core/2741-add-the-template-version-t…
Browse files Browse the repository at this point in the history
…o-the-pipeline-nf-coreyml-file

Add nf_core_version to .nf-core.yml
  • Loading branch information
Joon-Klaps authored Mar 26, 2024
2 parents 928fe53 + 1fc8080 commit 221b683
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
- Fix topic extraction step for hashtags in toots ([#2810](https://github.com/nf-core/tools/pull/2810))
- Update modules and subworkflows in the template ([#2811](https://github.com/nf-core/tools/pull/2811))
- Unpin setup-nextflow and action-tower-launch ([#2806](https://github.com/nf-core/tools/pull/2806))
- Add nf-core-version to `.nf-core.yml` ([#2874](https://github.com/nf-core/tools/pull/2874))

### Download

Expand Down
5 changes: 5 additions & 0 deletions docs/api/_src/pipeline_lint_tests/nfcore_yml.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# nfcore_yml

```{eval-rst}
.. automethod:: nf_core.lint.PipelineLint.nfcore_yml
```
2 changes: 2 additions & 0 deletions nf_core/lint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ class PipelineLint(nf_core.utils.Pipeline):
from .modules_structure import modules_structure # type: ignore[misc]
from .multiqc_config import multiqc_config # type: ignore[misc]
from .nextflow_config import nextflow_config # type: ignore[misc]
from .nfcore_yml import nfcore_yml # type: ignore[misc]
from .pipeline_name_conventions import ( # type: ignore[misc]
pipeline_name_conventions,
)
Expand Down Expand Up @@ -264,6 +265,7 @@ def _get_all_lint_tests(release_mode):
"modules_json",
"multiqc_config",
"modules_structure",
"nfcore_yml",
] + (["version_consistency"] if release_mode else [])

def _load(self):
Expand Down
75 changes: 75 additions & 0 deletions nf_core/lint/nfcore_yml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import re
from pathlib import Path
from typing import Dict, List

from nf_core import __version__

REPOSITORY_TYPES = ["pipeline", "modules"]


def nfcore_yml(self) -> Dict[str, List[str]]:
"""Repository ``.nf-core.yml`` tests
The ``.nf-core.yml`` contains metadata for nf-core tools to correctly apply its features.
* repository type:
* Check that the repository type is set.
* nf core version:
* Check if the nf-core version is set to the latest version.
"""
passed: List[str] = []
warned: List[str] = []
failed: List[str] = []
ignored: List[str] = []

# Remove field that should be ignored according to the linting config
ignore_configs = self.lint_config.get(".nf-core", [])

try:
with open(Path(self.wf_path, ".nf-core.yml")) as fh:
content = fh.read()
except FileNotFoundError:
with open(Path(self.wf_path, ".nf-core.yaml")) as fh:
content = fh.read()

if "repository_type" not in ignore_configs:
# Check that the repository type is set in the .nf-core.yml
repo_type_re = r"repository_type: (.+)"
match = re.search(repo_type_re, content)
if match:
repo_type = match.group(1)
if repo_type not in REPOSITORY_TYPES:
failed.append(
f"Repository type in `.nf-core.yml` is not valid. "
f"Should be one of `[{', '.join(REPOSITORY_TYPES)}]` but was `{repo_type}`"
)
else:
passed.append(f"Repository type in `.nf-core.yml` is valid: `{repo_type}`")
else:
warned.append("Repository type not set in `.nf-core.yml`")
else:
ignored.append("`.nf-core.yml` variable ignored 'repository_type'")

if "nf_core_version" not in ignore_configs:
# Check that the nf-core version is set in the .nf-core.yml
nf_core_version_re = r"nf_core_version: (.+)"
match = re.search(nf_core_version_re, content)
if match:
nf_core_version = match.group(1).strip('"')
if nf_core_version != __version__ and "dev" not in nf_core_version:
warned.append(
f"nf-core version in `.nf-core.yml` is not set to the latest version. "
f"Should be `{__version__}` but was `{nf_core_version}`"
)
else:
passed.append(f"nf-core version in `.nf-core.yml` is set to the latest version: `{nf_core_version}`")
else:
warned.append("nf-core version not set in `.nf-core.yml`")
else:
ignored.append("`.nf-core.yml` variable ignored 'nf_core_version'")

return {"passed": passed, "warned": warned, "failed": failed, "ignored": ignored}
1 change: 1 addition & 0 deletions nf_core/pipeline-template/.nf-core.yml
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
repository_type: pipeline
nf_core_version: "{{ nf_core_version }}"
53 changes: 53 additions & 0 deletions tests/lint/nfcore_yml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import re
from pathlib import Path

import nf_core.create
import nf_core.lint


def test_nfcore_yml_pass(self):
"""Lint test: nfcore_yml - PASS"""
self.lint_obj._load()
results = self.lint_obj.nfcore_yml()

assert "Repository type in `.nf-core.yml` is valid" in str(results["passed"])
assert "nf-core version in `.nf-core.yml` is set to the latest version" in str(results["passed"])
assert len(results.get("warned", [])) == 0
assert len(results.get("failed", [])) == 0
assert len(results.get("ignored", [])) == 0


def test_nfcore_yml_fail_repo_type(self):
"""Lint test: nfcore_yml - FAIL - repository type not set"""
new_pipeline = self._make_pipeline_copy()
nf_core_yml = Path(new_pipeline) / ".nf-core.yml"
with open(nf_core_yml) as fh:
content = fh.read()
new_content = content.replace("repository_type: pipeline", "repository_type: foo")
with open(nf_core_yml, "w") as fh:
fh.write(new_content)
lint_obj = nf_core.lint.PipelineLint(new_pipeline)
lint_obj._load()
results = lint_obj.nfcore_yml()
assert "Repository type in `.nf-core.yml` is not valid." in str(results["failed"])
assert len(results.get("warned", [])) == 0
assert len(results.get("passed", [])) >= 0
assert len(results.get("ignored", [])) == 0


def test_nfcore_yml_fail_nfcore_version(self):
"""Lint test: nfcore_yml - FAIL - nf-core version not set"""
new_pipeline = self._make_pipeline_copy()
nf_core_yml = Path(new_pipeline) / ".nf-core.yml"
with open(nf_core_yml) as fh:
content = fh.read()
new_content = re.sub(r"nf_core_version:.+", "nf_core_version: foo", content)
with open(nf_core_yml, "w") as fh:
fh.write(new_content)
lint_obj = nf_core.lint.PipelineLint(new_pipeline)
lint_obj._load()
results = lint_obj.nfcore_yml()
assert "nf-core version in `.nf-core.yml` is not set to the latest version." in str(results["warned"])
assert len(results.get("failed", [])) == 0
assert len(results.get("passed", [])) >= 0
assert len(results.get("ignored", [])) == 0
5 changes: 5 additions & 0 deletions tests/test_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,11 @@ def test_sphinx_md_files(self):
test_nextflow_config_example_pass,
test_nextflow_config_missing_test_profile_failed,
)
from .lint.nfcore_yml import ( # type: ignore[misc]
test_nfcore_yml_fail_nfcore_version,
test_nfcore_yml_fail_repo_type,
test_nfcore_yml_pass,
)
from .lint.template_strings import ( # type: ignore[misc]
test_template_strings,
test_template_strings_ignore_file,
Expand Down

0 comments on commit 221b683

Please sign in to comment.