Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nf_core_version to .nf-core.yml #2874

Merged
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,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
Loading