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

Remove nfcore_external_java_deps.jar from lib directory in pipeline template #2675

Merged
merged 11 commits into from
Jan 26, 2024
Merged
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
- switch to new image syntax in readme ([#2645](https://github.com/nf-core/tools/pull/2645))
- Add conda channel order to nextflow.config ([#2094](https://github.com/nf-core/tools/pull/2094))
- Fix tyop in pipeline nextflow.config ([#2664](https://github.com/nf-core/tools/pull/2664))
- add function to check `-profile` is well formatted ([#2678](https://github.com/nf-core/tools/pull/2678))
- Remove `nfcore_external_java_deps.jar` from lib directory in pipeline template ([#2675](https://github.com/nf-core/tools/pull/2675))

### Download

Expand Down Expand Up @@ -40,6 +40,7 @@
- Add new subcommand: `nf-core logo-create` to output an nf-core logo for a pipeline (instead of going through the website) ([#2662](https://github.com/nf-core/tools/pull/2662))
- Update actions/cache action to v4 ([#2666](https://github.com/nf-core/tools/pull/2666))
- Remove redundanct v in pipeline version for emails ([#2667](https://github.com/nf-core/tools/pull/2667))
- add function to check `-profile` is well formatted ([#2678](https://github.com/nf-core/tools/pull/2678))

# [v2.11.1 - Magnesium Dragon Patch](https://github.com/nf-core/tools/releases/tag/2.11) - [2023-12-20]

Expand Down
27 changes: 24 additions & 3 deletions nf_core/lint/files_exist.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ def files_exist(self):
docs/output.md
docs/README.md
docs/usage.md
lib/nfcore_external_java_deps.jar
lib/NfcoreTemplate.groovy
lib/Utils.groovy
lib/WorkflowMain.groovy
Expand Down Expand Up @@ -98,6 +97,12 @@ def files_exist(self):

.travis.yml

Files that *must not* be present if a certain entry is present in ``nextflow.config``:

.. code-block:: bash

lib/nfcore_external_java_deps.jar # if "nf-validation" is in nextflow.config

.. tip:: You can configure the ``nf-core lint`` tests to ignore any of these checks by setting
the ``files_exist`` key as follows in your ``.nf-core.yml`` config file. For example:

Expand Down Expand Up @@ -160,7 +165,6 @@ def files_exist(self):
[os.path.join("docs", "README.md")],
[os.path.join("docs", "README.md")],
[os.path.join("docs", "usage.md")],
[os.path.join("lib", "nfcore_external_java_deps.jar")],
[os.path.join("lib", "NfcoreTemplate.groovy")],
[os.path.join("lib", "Utils.groovy")],
[os.path.join("lib", "WorkflowMain.groovy")],
Expand Down Expand Up @@ -197,6 +201,7 @@ def files_exist(self):
os.path.join("lib", "Workflow.groovy"),
]
files_warn_ifexists = [".travis.yml"]
files_fail_ifinconfig = [[os.path.join("lib", "nfcore_external_java_deps.jar"), "nf-validation"]]

# Remove files that should be ignored according to the linting config
ignore_files = self.lint_config.get("files_exist", [])
Expand Down Expand Up @@ -235,7 +240,23 @@ def pf(file_path):
failed.append(f"File must be removed: {self._wrap_quotes(file)}")
else:
passed.append(f"File not found check: {self._wrap_quotes(file)}")

# Files that cause an error if they exists together with a certain entry in nextflow.config
for file in files_fail_ifinconfig:
if file[0] in ignore_files:
continue
nextflow_config = pf("nextflow.config")
in_config = False
with open(nextflow_config) as f:
if file[1] in f.read():
in_config = True
if os.path.isfile(pf(file[0])) and in_config:
mashehu marked this conversation as resolved.
Show resolved Hide resolved
failed.append(f"File must be removed: {self._wrap_quotes(file[0])}")
elif os.path.isfile(pf(file[0])) and not in_config:
passed.append(f"File not found check: {self._wrap_quotes(file[0])}")
mashehu marked this conversation as resolved.
Show resolved Hide resolved
elif not os.path.isfile(pf(file[0])) and in_config:
failed.append(f"File not found check: {self._wrap_quotes(file[0])}")
mashehu marked this conversation as resolved.
Show resolved Hide resolved
else:
passed.append(f"File not found check: {self._wrap_quotes(file[0])}")
mashehu marked this conversation as resolved.
Show resolved Hide resolved
# Files that cause a warning if they exist
for file in files_warn_ifexists:
if file in ignore_files:
Expand Down
96 changes: 68 additions & 28 deletions nf_core/lint/files_unchanged.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import filecmp
import logging
import os
import shutil
import tempfile
from pathlib import Path
from typing import Union

import yaml

Expand Down Expand Up @@ -39,7 +40,6 @@ def files_unchanged(self):
docs/images/nf-core-PIPELINE_logo_light.png
docs/images/nf-core-PIPELINE_logo_dark.png
docs/README.md'
lib/nfcore_external_java_deps.jar
lib/NfcoreTemplate.groovy
['LICENSE', 'LICENSE.md', 'LICENCE', 'LICENCE.md'], # NB: British / American spelling

Expand All @@ -49,6 +49,10 @@ def files_unchanged(self):
.prettierignore
pyproject.toml

Files that need to be there or not based on a entry in nextflow config::

lib/nfcore_external_java_deps.jar # if config doesn't mention nf-validation

.. tip:: You can configure the ``nf-core lint`` tests to ignore any of these checks by setting
the ``files_unchanged`` key as follows in your ``.nf-core.yml`` config file. For example:

Expand Down Expand Up @@ -87,28 +91,30 @@ def files_unchanged(self):
[".prettierrc.yml"],
["CODE_OF_CONDUCT.md"],
["LICENSE", "LICENSE.md", "LICENCE", "LICENCE.md"], # NB: British / American spelling
[os.path.join(".github", ".dockstore.yml")],
[os.path.join(".github", "CONTRIBUTING.md")],
[os.path.join(".github", "ISSUE_TEMPLATE", "bug_report.yml")],
[os.path.join(".github", "ISSUE_TEMPLATE", "config.yml")],
[os.path.join(".github", "ISSUE_TEMPLATE", "feature_request.yml")],
[os.path.join(".github", "PULL_REQUEST_TEMPLATE.md")],
[os.path.join(".github", "workflows", "branch.yml")],
[os.path.join(".github", "workflows", "linting_comment.yml")],
[os.path.join(".github", "workflows", "linting.yml")],
[os.path.join("assets", "email_template.html")],
[os.path.join("assets", "email_template.txt")],
[os.path.join("assets", "sendmail_template.txt")],
[os.path.join("assets", f"nf-core-{short_name}_logo_light.png")],
[os.path.join("docs", "images", f"nf-core-{short_name}_logo_light.png")],
[os.path.join("docs", "images", f"nf-core-{short_name}_logo_dark.png")],
[os.path.join("docs", "README.md")],
[os.path.join("lib", "nfcore_external_java_deps.jar")],
[os.path.join("lib", "NfcoreTemplate.groovy")],
[Path(".github", ".dockstore.yml")],
[Path(".github", "CONTRIBUTING.md")],
[Path(".github", "ISSUE_TEMPLATE", "bug_report.yml")],
[Path(".github", "ISSUE_TEMPLATE", "config.yml")],
[Path(".github", "ISSUE_TEMPLATE", "feature_request.yml")],
[Path(".github", "PULL_REQUEST_TEMPLATE.md")],
[Path(".github", "workflows", "branch.yml")],
[Path(".github", "workflows", "linting_comment.yml")],
[Path(".github", "workflows", "linting.yml")],
[Path("assets", "email_template.html")],
[Path("assets", "email_template.txt")],
[Path("assets", "sendmail_template.txt")],
[Path("assets", f"nf-core-{short_name}_logo_light.png")],
[Path("docs", "images", f"nf-core-{short_name}_logo_light.png")],
[Path("docs", "images", f"nf-core-{short_name}_logo_dark.png")],
[Path("docs", "README.md")],
[Path("lib", "NfcoreTemplate.groovy")],
]
files_partial = [
[".gitignore", ".prettierignore", "pyproject.toml"],
]
files_conditional = [
[Path("lib", "nfcore_external_java_deps.jar"), {"plugins": "nf_validation"}],
]

# Only show error messages from pipeline creation
logging.getLogger("nf_core.create").setLevel(logging.ERROR)
Expand All @@ -124,24 +130,24 @@ def files_unchanged(self):
"prefix": prefix,
}

template_yaml_path = os.path.join(tmp_dir, "template.yaml")
template_yaml_path = Path(tmp_dir, "template.yaml")
with open(template_yaml_path, "w") as fh:
yaml.dump(template_yaml, fh, default_flow_style=False)

test_pipeline_dir = os.path.join(tmp_dir, f"{prefix}-{short_name}")
test_pipeline_dir = Path(tmp_dir, f"{prefix}-{short_name}")
create_obj = nf_core.create.PipelineCreate(
None, None, None, no_git=True, outdir=test_pipeline_dir, template_yaml_path=template_yaml_path
)
create_obj.init_pipeline()

# Helper functions for file paths
def _pf(file_path):
def _pf(file_path: Union[str, Path]) -> Path:
"""Helper function - get file path for pipeline file"""
return os.path.join(self.wf_path, file_path)
return Path(self.wf_path, file_path)

def _tf(file_path):
def _tf(file_path: Union[str, Path]) -> Path:
"""Helper function - get file path for template file"""
return os.path.join(test_pipeline_dir, file_path)
return Path(test_pipeline_dir, file_path)

# Files that must be completely unchanged from template
for files in files_exact:
Expand All @@ -151,7 +157,7 @@ def _tf(file_path):
ignored.append(f"File ignored due to lint config: {self._wrap_quotes(files)}")

# Ignore if we can't find the file
elif not any([os.path.isfile(_pf(f)) for f in files]):
elif not any([_pf(f).is_file() for f in files]):
ignored.append(f"File does not exist: {self._wrap_quotes(files)}")

# Check that the file has an identical match
Expand Down Expand Up @@ -180,7 +186,7 @@ def _tf(file_path):
ignored.append(f"File ignored due to lint config: {self._wrap_quotes(files)}")

# Ignore if we can't find the file
elif not any([os.path.isfile(_pf(f)) for f in files]):
elif not any([_pf(f).is_file() for f in files]):
ignored.append(f"File does not exist: {self._wrap_quotes(files)}")

# Check that the file contains the template file contents
Expand Down Expand Up @@ -208,6 +214,40 @@ def _tf(file_path):
except FileNotFoundError:
pass

# Files that should be there only if an entry in nextflow config is not set
for files in files_conditional:
# Ignore if file specified in linting config
ignore_files = self.lint_config.get("files_unchanged", [])
if any([files[0] in ignore_files]):
ignored.append(f"File ignored due to lint config: {self._wrap_quotes(files)}")

# Ignore if we can't find the file
elif not any([_pf(files[0]).is_file()]):
ignored.append(f"File does not exist: {self._wrap_quotes(files[0])}")

# Check that the file has an identical match
else:
config_key, config_value = list(files[1].items())[0]
if config_key in self.nf_config and self.nf_config[config_key] == config_value:
mashehu marked this conversation as resolved.
Show resolved Hide resolved
# Ignore if the config key is set to the expected value
ignored.append(f"File ignored due to config: {self._wrap_quotes(files)}")
else:
for f in files:
try:
if filecmp.cmp(_pf(f), _tf(f), shallow=True):
passed.append(f"`{f}` matches the template")
else:
if "files_unchanged" in self.fix:
# Try to fix the problem by overwriting the pipeline file
shutil.copy(_tf(f), _pf(f))
passed.append(f"`{f}` matches the template")
fixed.append(f"`{f}` overwritten with template file")
else:
failed.append(f"`{f}` does not match the template")
could_fix = True
except FileNotFoundError:
pass

# cleaning up temporary dir
shutil.rmtree(tmp_dir)

Expand Down
Binary file not shown.
2 changes: 1 addition & 1 deletion nf_core/pipeline-template/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Config file for Python. Mostly used to configure linting of bin/check_samplesheet.py with Ruff.
# Config file for Python. Mostly used to configure linting of bin/*.py with Ruff.
# Should be kept the same as nf-core/tools to avoid fighting with template synchronisation.
[tool.ruff]
line-length = 120
Expand Down
Loading