diff --git a/CHANGELOG.md b/CHANGELOG.md index a5ed171c5c..99e7478219 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ ### Linting +* Added lint check for merge markers [[#321]](https://github.com/nf-core/tools/issues/321) * Added new option `--fix` to automatically correct some problems detected by linting * Added validation of default params to `nf-core schema lint` [[#823](https://github.com/nf-core/tools/issues/823)] * Added schema validation of GitHub action workflows to lint function [[#795](https://github.com/nf-core/tools/issues/795)] diff --git a/docs/api/_src/lint_tests/merge_markers.rst b/docs/api/_src/lint_tests/merge_markers.rst new file mode 100644 index 0000000000..ea5e3be84b --- /dev/null +++ b/docs/api/_src/lint_tests/merge_markers.rst @@ -0,0 +1,4 @@ +merge_markers +============== + +.. automethod:: nf_core.lint.PipelineLint.merge_markers diff --git a/nf_core/lint/__init__.py b/nf_core/lint/__init__.py index 264e115233..1fc0f9fab9 100644 --- a/nf_core/lint/__init__.py +++ b/nf_core/lint/__init__.py @@ -113,6 +113,7 @@ class PipelineLint(nf_core.utils.Pipeline): from .schema_lint import schema_lint from .schema_params import schema_params from .actions_schema_validation import actions_schema_validation + from .merge_markers import merge_markers def __init__(self, wf_path, release_mode=False, fix=()): """ Initialise linting object """ @@ -144,6 +145,7 @@ def __init__(self, wf_path, release_mode=False, fix=()): "schema_lint", "schema_params", "actions_schema_validation", + "merge_markers", ] if self.release_mode: self.lint_tests.extend(["version_consistency"]) diff --git a/nf_core/lint/merge_markers.py b/nf_core/lint/merge_markers.py new file mode 100644 index 0000000000..f15e76130b --- /dev/null +++ b/nf_core/lint/merge_markers.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +import logging +import os +import io +import fnmatch + +log = logging.getLogger(__name__) + + +def merge_markers(self): + """Check for remaining merge markers. + + This test looks for remaining merge markers in the code, e.g.: + >>>>>>> or <<<<<<< + + + """ + passed = [] + failed = [] + + ignore = [".git"] + if os.path.isfile(os.path.join(self.wf_path, ".gitignore")): + with io.open(os.path.join(self.wf_path, ".gitignore"), "rt", encoding="latin1") as fh: + for l in fh: + ignore.append(os.path.basename(l.strip().rstrip("/"))) + for root, dirs, files in os.walk(self.wf_path): + # Ignore files + for i in ignore: + dirs = [d for d in dirs if not fnmatch.fnmatch(os.path.join(root, d), i)] + files = [f for f in files if not fnmatch.fnmatch(os.path.join(root, f), i)] + for fname in files: + try: + with io.open(os.path.join(root, fname), "rt", encoding="latin1") as fh: + for l in fh: + if ">>>>>>>" in l: + failed.append(f"Merge marker in `{fname}`: {l}") + if "<<<<<<<" in l: + failed.append(f"Merge marker in `{fname}`: {l}") + except FileNotFoundError: + log.debug(f"Could not open file {fname} in merge_markers lint test") + if len(failed) == 0: + passed.append("No merge markers found in pipeline files") + return {"passed": passed, "failed": failed} diff --git a/tests/lint/merge_markers.py b/tests/lint/merge_markers.py new file mode 100644 index 0000000000..b235979485 --- /dev/null +++ b/tests/lint/merge_markers.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +import os +import yaml +import nf_core.lint + + +def test_merge_markers_found(self): + """Missing 'jobs' field should result in failure""" + new_pipeline = self._make_pipeline_copy() + + with open(os.path.join(new_pipeline, "main.nf"), "r") as fh: + main_nf_content = fh.read() + main_nf_content = ">>>>>>>\n" + main_nf_content + with open(os.path.join(new_pipeline, "main.nf"), "w") as fh: + fh.write(main_nf_content) + + lint_obj = nf_core.lint.PipelineLint(new_pipeline) + lint_obj._load() + + results = lint_obj.merge_markers() + assert len(results["failed"]) > 0 + assert len(results["passed"]) == 0 + assert "Merge marker in `main.nf`: >>>>>>>\n" == results["failed"][0] diff --git a/tests/test_lint.py b/tests/test_lint.py index 9c3015a9b3..6a2aadea87 100644 --- a/tests/test_lint.py +++ b/tests/test_lint.py @@ -200,6 +200,8 @@ def test_sphinx_rst_files(self): test_actions_schema_validation_missing_on, ) + from lint.merge_markers import test_merge_markers_found + # def test_critical_missingfiles_example(self): # """Tests for missing nextflow config and main.nf files"""