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

handle float values correctly in default value comparison #2711

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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 @@ -16,6 +16,7 @@
### General

- Update pre-commit hook astral-sh/ruff-pre-commit to v0.1.15 ([#2705](https://github.com/nf-core/tools/pull/2705))
- handle float values correctly in default value comparison ([#2711](https://github.com/nf-core/tools/pull/2711))
- fix changelog titles ([#2708](https://github.com/nf-core/tools/pull/2708))
- Print relative path not absolute path in logo cmd log output ([#2709](https://github.com/nf-core/tools/pull/2709))

Expand Down
21 changes: 15 additions & 6 deletions nf_core/lint/nextflow_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,18 +388,27 @@ def nextflow_config(self):
ignored.append(f"Config default ignored: {param}")
elif param in self.nf_config.keys():
if str(self.nf_config[param]) == schema_default:
passed.append(f"Config default value correct: {param}")
passed.append(f"Config default value correct: {param}= {schema_default}")
else:
# Handle "number" type
if schema_default.endswith(".0") and str(self.nf_config[param]) == schema_default[:-2]:
passed.append(f"Config default value correct: {param}")
passed.append(f"Config default value correct: {param}= {schema_default}")
else:
failed.append(
f"Config default value incorrect: `{param}` is set as {self._wrap_quotes(schema_default)} in `nextflow_schema.json` but is {self._wrap_quotes(self.nf_config[param])} in `nextflow.config`."
)
# try to convert to float
try:
if float(self.nf_config[param]) == float(schema_default):
passed.append(f"Config default value correct: {param}= {schema_default}")
else:
failed.append(
f"Config default value incorrect: `{param}` is set as {self._wrap_quotes(schema_default)} in `nextflow_schema.json` but is {self._wrap_quotes(self.nf_config[param])} in `nextflow.config`."
)
except ValueError:
failed.append(
f"Config default value incorrect: `{param}` is set as {self._wrap_quotes(schema_default)} in `nextflow_schema.json` but is {self._wrap_quotes(self.nf_config[param])} in `nextflow.config`."
)
else:
failed.append(
f"Default value from the Nextflow schema '{param} = {self._wrap_quotes(schema_default)}' not found in `nextflow.config`."
f"Default value from the Nextflow schema `{param} = {self._wrap_quotes(schema_default)}` not found in `nextflow.config`."
)

return {"passed": passed, "warned": warned, "failed": failed, "ignored": ignored}
2 changes: 1 addition & 1 deletion nf_core/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def list_workflows(filter_by=None, sort_by="release", as_json=False, show_archiv
return wfs.print_summary()


def get_local_wf(workflow, revision=None):
def get_local_wf(workflow, revision=None) -> str:
"""
Check if this workflow has a local copy and use nextflow to pull it if not
"""
Expand Down
73 changes: 68 additions & 5 deletions tests/lint/nextflow_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ def test_default_values_match(self):
result = lint_obj.nextflow_config()
assert len(result["failed"]) == 0
assert len(result["warned"]) == 0
assert "Config default value correct: params.max_cpus" in result["passed"]
assert "Config default value correct: params.validate_params" in result["passed"]
assert "Config default value correct: params.max_cpus" in str(result["passed"])
assert "Config default value correct: params.validate_params" in str(result["passed"])


def test_default_values_fail(self):
Expand All @@ -75,7 +75,7 @@ def test_default_values_fail(self):
nf_conf_file = Path(new_pipeline) / "nextflow.config"
with open(nf_conf_file) as f:
content = f.read()
fail_content = re.sub(r"\bmax_cpus = 16\b", "max_cpus = 0", content)
fail_content = re.sub(r"\bmax_cpus\s*=\s*16\b", "max_cpus = 0", content)
with open(nf_conf_file, "w") as f:
f.write(fail_content)
# Change the default value of max_memory in nextflow_schema.json
Expand Down Expand Up @@ -115,5 +115,68 @@ def test_default_values_ignored(self):
result = lint_obj.nextflow_config()
assert len(result["failed"]) == 0
assert len(result["ignored"]) == 1
assert "Config default value correct: params.max_cpus" not in result["passed"]
assert "Config default ignored: params.max_cpus" in result["ignored"]
assert "Config default value correct: params.max_cpu" not in str(result["passed"])
assert "Config default ignored: params.max_cpus" in str(result["ignored"])


def test_default_values_float(self):
"""Test comparing two float values."""
new_pipeline = self._make_pipeline_copy()
# Add a float value `dummy=0.0001` to the nextflow.config below `validate_params`
nf_conf_file = Path(new_pipeline) / "nextflow.config"
with open(nf_conf_file) as f:
content = f.read()
fail_content = re.sub(
r"validate_params\s*=\s*true", "params.validate_params = true\ndummy = 0.000000001", content
)
with open(nf_conf_file, "w") as f:
f.write(fail_content)
# Add a float value `dummy` to the nextflow_schema.json
nf_schema_file = Path(new_pipeline) / "nextflow_schema.json"
with open(nf_schema_file) as f:
content = f.read()
fail_content = re.sub(
r'"validate_params": {',
' "dummy": {"type": "float","default":0.000000001},\n"validate_params": {',
content,
)
with open(nf_schema_file, "w") as f:
f.write(fail_content)

lint_obj = nf_core.lint.PipelineLint(new_pipeline)
lint_obj._load_pipeline_config()
result = lint_obj.nextflow_config()
assert len(result["failed"]) == 0
assert len(result["warned"]) == 0
assert "Config default value correct: params.dummy" in str(result["passed"])


def test_default_values_float_fail(self):
"""Test comparing two float values."""
new_pipeline = self._make_pipeline_copy()
# Add a float value `dummy=0.0001` to the nextflow.config below `validate_params`
nf_conf_file = Path(new_pipeline) / "nextflow.config"
with open(nf_conf_file) as f:
content = f.read()
fail_content = re.sub(
r"validate_params\s*=\s*true", "params.validate_params = true\ndummy = 0.000000001", content
)
with open(nf_conf_file, "w") as f:
f.write(fail_content)
# Add a float value `dummy` to the nextflow_schema.json
nf_schema_file = Path(new_pipeline) / "nextflow_schema.json"
with open(nf_schema_file) as f:
content = f.read()
fail_content = re.sub(
r'"validate_params": {', ' "dummy": {"type": "float","default":0.000001},\n"validate_params": {', content
)
with open(nf_schema_file, "w") as f:
f.write(fail_content)

lint_obj = nf_core.lint.PipelineLint(new_pipeline)
lint_obj._load_pipeline_config()
result = lint_obj.nextflow_config()

assert len(result["failed"]) == 1
assert len(result["warned"]) == 0
assert "Config default value incorrect: `params.dummy" in str(result["failed"])
2 changes: 2 additions & 0 deletions tests/test_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ def test_sphinx_md_files(self):
)
from .lint.nextflow_config import ( # type: ignore[misc]
test_default_values_fail,
test_default_values_float,
test_default_values_float_fail,
test_default_values_ignored,
test_default_values_match,
test_nextflow_config_bad_name_fail,
Expand Down
Loading