Skip to content

Commit

Permalink
Merge branch 'dev' into version-badges
Browse files Browse the repository at this point in the history
  • Loading branch information
mirpedrol authored Feb 12, 2025
2 parents 191d211 + 38813b0 commit e411c65
Show file tree
Hide file tree
Showing 60 changed files with 598 additions and 236 deletions.
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.6
rev: v0.9.5
hooks:
- id: ruff # linter
args: [--fix, --exit-non-zero-on-fix] # sort imports and fix
Expand All @@ -10,16 +10,16 @@ repos:
hooks:
- id: prettier
additional_dependencies:
- prettier@3.3.3
- prettier@3.5.0

- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
rev: "3.0.3"
rev: "3.1.2"
hooks:
- id: editorconfig-checker
alias: ec

- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.14.1"
rev: "v1.15.0"
hooks:
- id: mypy
additional_dependencies:
Expand Down
35 changes: 34 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,52 @@
# nf-core/tools: Changelog

## v3.2.0dev
## v3.3.0dev

### Template

- Remove the on `pull_request_target` trigger and `pull_request` types from the download test. Also drop `push` triggers on other CI tests. ([#3399](https://github.com/nf-core/tools/pull/3399))
- Add nf-core template version badges to README ([#3396](https://github.com/nf-core/tools/pull/3396))

### Linting

- Add linting for ifEmpty(null) ([#3411](https://github.com/nf-core/tools/pull/3411))

### Modules

### Subworkflows

### General

- output passed to write_params_file as Path object ([#3435](https://github.com/nf-core/tools/pull/3435))
- chore(deps): update python:3.12-slim docker digest to 69ce3ae ([#3433](https://github.com/nf-core/tools/pull/3433))
- chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.4 ([#3438](https://github.com/nf-core/tools/pull/3438))
- format name/value with YAML syntax ([#3442](https://github.com/nf-core/tools/pull/3442))
- chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.5 ([#3445](https://github.com/nf-core/tools/pull/3445))
- chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.15.0 ([#3447](https://github.com/nf-core/tools/pull/3447))
- Update prettier to 3.5.0 ([#3448](https://github.com/nf-core/tools/pull/3448))
- chore(deps): update python:3.12-slim docker digest to 34656cd ([#3450](https://github.com/nf-core/tools/pull/3450))

## [v3.2.0 - Pewter Pangolin](https://github.com/nf-core/tools/releases/tag/3.2.0) - [2025-01-27]

### Template

- Remove automated release tweets ([#3419](https://github.com/nf-core/tools/pull/3419))
- Update template components ([#3426](https://github.com/nf-core/tools/pull/3426))
- Fix `process.shell` in `nextflow.config` ([#3416](https://github.com/nf-core/tools/pull/3416)) and split into new lines ([#3425](https://github.com/nf-core/tools/pull/3425))

### Modules

- Modules created in pipelines "local" dir now use the full template ([#3256](https://github.com/nf-core/tools/pull/3256))

### Subworkflows

- Subworkflows created in pipelines "local" dir now use the full template ([#3256](https://github.com/nf-core/tools/pull/3256))

### General

- Update pre-commit hook editorconfig-checker/editorconfig-checker.python to v3.1.2 ([#3414](https://github.com/nf-core/tools/pull/3414))
- Update python:3.12-slim Docker digest to 123be56 ([#3421](https://github.com/nf-core/tools/pull/3421))

## [v3.1.2 - Brass Boxfish Patch](https://github.com/nf-core/tools/releases/tag/3.1.2) - [2025-01-20]

### Template
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.12-slim@sha256:10f3aaab98db50cba827d3b33a91f39dc9ec2d02ca9b85cbc5008220d07b17f3
FROM python:3.12-slim@sha256:34656cd90456349040784165b9decccbcee4de66f3ead0a1168ba893455afd1e
LABEL authors="[email protected],[email protected]" \
description="Docker image containing requirements for nf-core/tools"

Expand Down
1 change: 1 addition & 0 deletions docs/api/_src/pipeline_lint_tests/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- [nfcore_yml](./nfcore_yml/)
- [pipeline_name_conventions](./pipeline_name_conventions/)
- [pipeline_todos](./pipeline_todos/)
- [pipeline_if_empty_null](./pipeline_if_empty_null/)
- [plugin_includes](./plugin_includes/)
- [readme](./readme/)
- [schema_description](./schema_description/)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# modules_structure

```{eval-rst}
.. automethod:: nf_core.pipelines.lint.PipelineLint.local_component_structure
```
5 changes: 5 additions & 0 deletions docs/api/_src/pipeline_lint_tests/pipeline_if_empty_null.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# pipeline_if_empty_null

```{eval-rst}
.. automethod:: nf_core.pipelines.lint.PipelineLint.pipeline_if_empty_null
```
1 change: 1 addition & 0 deletions docs/api/_src/subworkflow_lint_tests/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
- [subworkflow_changes](./subworkflow_changes/)
- [subworkflow_tests](./subworkflow_tests/)
- [subworkflow_todos](./subworkflow_todos/)
- [subworkflow_if_empty_null](./subworkflow_if_empty_null/)
- [subworkflow_version](./subworkflow_version/)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# subworkflow_if_empty_null

```{eval-rst}
.. automethod:: nf_core.subworkflows.lint.SubworkflowLint.subworkflow_if_empty_null
```
2 changes: 1 addition & 1 deletion nf_core/commands_pipelines.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ def pipelines_create_params_file(ctx, pipeline, revision, output, force, show_hi
"""
builder = ParamsFileBuilder(pipeline, revision)

if not builder.write_params_file(output, show_hidden=show_hidden, force=force):
if not builder.write_params_file(Path(output), show_hidden=show_hidden, force=force):
sys.exit(1)


Expand Down
4 changes: 4 additions & 0 deletions nf_core/components/components_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ def get_local_components(self) -> List[str]:
"""
local_component_dir = Path(self.directory, self.component_type, "local")
return [
str(Path(directory).relative_to(local_component_dir))
for directory, _, files in os.walk(local_component_dir)
if "main.nf" in files
] + [
str(path.relative_to(local_component_dir)) for path in local_component_dir.iterdir() if path.suffix == ".nf"
]

Expand Down
4 changes: 1 addition & 3 deletions nf_core/components/components_differ.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,7 @@ def print_diff(
console = Console(force_terminal=nf_core.utils.rich_force_colors())
if current_version is not None and new_version is not None:
log.info(
f"Changes in component '{Path(repo_path, component)}' between"
f" ({current_version}) and"
f" ({new_version})"
f"Changes in component '{Path(repo_path, component)}' between ({current_version}) and ({new_version})"
)
else:
log.info(f"Changes in component '{Path(repo_path, component)}'")
Expand Down
96 changes: 36 additions & 60 deletions nf_core/components/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ def create(self) -> bool:
e.g bam_sort or bam_sort_samtools, respectively.
If <directory> is a pipeline, this function creates a file called:
'<directory>/modules/local/tool.nf'
'<directory>/modules/local/tool/main.nf'
OR
'<directory>/modules/local/tool_subtool.nf'
'<directory>/modules/local/tool/subtool/main.nf'
OR for subworkflows
'<directory>/subworkflows/local/subworkflow_name.nf'
'<directory>/subworkflows/local/subworkflow_name/main.nf'
If <directory> is a clone of nf-core/modules, it creates or modifies the following files:
Expand Down Expand Up @@ -355,70 +355,46 @@ def _get_component_dirs(self) -> Dict[str, Path]:
"""
file_paths = {}
if self.repo_type == "pipeline":
local_component_dir = Path(self.directory, self.component_type, "local")
# Check whether component file already exists
component_file = local_component_dir / f"{self.component_name}.nf"
if component_file.exists() and not self.force_overwrite:
raise UserWarning(
f"{self.component_type[:-1].title()} file exists already: '{component_file}'. Use '--force' to overwrite"
)

if self.component_type == "modules":
# If a subtool, check if there is a module called the base tool name already
if self.subtool and (local_component_dir / f"{self.component}.nf").exists():
raise UserWarning(
f"Module '{self.component}' exists already, cannot make subtool '{self.component_name}'"
)

# If no subtool, check that there isn't already a tool/subtool
tool_glob = glob.glob(f"{local_component_dir}/{self.component}_*.nf")
if not self.subtool and tool_glob:
raise UserWarning(
f"Module subtool '{tool_glob[0]}' exists already, cannot make tool '{self.component_name}'"
)

# Set file paths
file_paths["main.nf"] = component_file
component_dir = Path(self.directory, self.component_type, "local", self.component_dir)

elif self.repo_type == "modules":
component_dir = Path(self.directory, self.component_type, self.org, self.component_dir)
# Check if module/subworkflow directories exist already
if component_dir.exists() and not self.force_overwrite and not self.migrate_pytest:
raise UserWarning(
f"{self.component_type[:-1]} directory exists: '{component_dir}'. Use '--force' to overwrite"
)
else:
raise ValueError("`repo_type` not set correctly")

if self.component_type == "modules":
# If a subtool, check if there is a module called the base tool name already
parent_tool_main_nf = Path(
self.directory,
self.component_type,
self.org,
self.component,
"main.nf",
# Check if module/subworkflow directories exist already
if component_dir.exists() and not self.force_overwrite and not self.migrate_pytest:
raise UserWarning(
f"{self.component_type[:-1]} directory exists: '{component_dir}'. Use '--force' to overwrite"
)

if self.component_type == "modules":
# If a subtool, check if there is a module called the base tool name already
parent_tool_main_nf = Path(
self.directory,
self.component_type,
self.org,
self.component,
"main.nf",
)
if self.subtool and parent_tool_main_nf.exists() and not self.migrate_pytest:
raise UserWarning(
f"Module '{parent_tool_main_nf}' exists already, cannot make subtool '{self.component_name}'"
)
if self.subtool and parent_tool_main_nf.exists() and not self.migrate_pytest:
raise UserWarning(
f"Module '{parent_tool_main_nf}' exists already, cannot make subtool '{self.component_name}'"
)

# If no subtool, check that there isn't already a tool/subtool
tool_glob = glob.glob(
f"{Path(self.directory, self.component_type, self.org, self.component)}/*/main.nf"
# If no subtool, check that there isn't already a tool/subtool
tool_glob = glob.glob(f"{Path(self.directory, self.component_type, self.org, self.component)}/*/main.nf")
if not self.subtool and tool_glob and not self.migrate_pytest:
raise UserWarning(
f"Module subtool '{tool_glob[0]}' exists already, cannot make tool '{self.component_name}'"
)
if not self.subtool and tool_glob and not self.migrate_pytest:
raise UserWarning(
f"Module subtool '{tool_glob[0]}' exists already, cannot make tool '{self.component_name}'"
)
# Set file paths
# For modules - can be tool/ or tool/subtool/ so can't do in template directory structure
file_paths["main.nf"] = component_dir / "main.nf"
file_paths["meta.yml"] = component_dir / "meta.yml"
if self.component_type == "modules":
file_paths["environment.yml"] = component_dir / "environment.yml"
file_paths["tests/main.nf.test.j2"] = component_dir / "tests" / "main.nf.test"
else:
raise ValueError("`repo_type` not set correctly")
# Set file paths
# For modules - can be tool/ or tool/subtool/ so can't do in template directory structure
file_paths["main.nf"] = component_dir / "main.nf"
file_paths["meta.yml"] = component_dir / "meta.yml"
if self.component_type == "modules":
file_paths["environment.yml"] = component_dir / "environment.yml"
file_paths["tests/main.nf.test.j2"] = component_dir / "tests" / "main.nf.test"

return file_paths

Expand Down
4 changes: 2 additions & 2 deletions nf_core/components/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,9 @@ def generate_component_info_help(self):
intro_text.append(
Text.from_markup(
":globe_with_meridians: Repository: "
f"{ '[link={self.remote_location}]' if self.remote_location.startswith('http') else ''}"
f"{'[link={self.remote_location}]' if self.remote_location.startswith('http') else ''}"
f"{self.remote_location}"
f"{'[/link]' if self.remote_location.startswith('http') else '' }"
f"{'[/link]' if self.remote_location.startswith('http') else ''}"
"\n"
)
)
Expand Down
17 changes: 14 additions & 3 deletions nf_core/components/lint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def __init__(
continue
if isinstance(components, str):
raise LookupError(
f"Error parsing modules.json: {components}. " f"Please check the file for errors or try again."
f"Error parsing modules.json: {components}. Please check the file for errors or try again."
)
for org, comp in components:
self.all_remote_components.append(
Expand Down Expand Up @@ -162,6 +162,10 @@ def _set_registry(self, registry) -> None:
self.registry = registry
log.debug(f"Registry set to {self.registry}")

@property
def local_module_exclude_tests(self):
return ["module_version", "module_changes", "modules_patch"]

@staticmethod
def get_all_module_lint_tests(is_pipeline):
if is_pipeline:
Expand All @@ -181,9 +185,16 @@ def get_all_module_lint_tests(is_pipeline):
@staticmethod
def get_all_subworkflow_lint_tests(is_pipeline):
if is_pipeline:
return ["main_nf", "meta_yml", "subworkflow_changes", "subworkflow_todos", "subworkflow_version"]
return [
"main_nf",
"meta_yml",
"subworkflow_changes",
"subworkflow_todos",
"subworkflow_if_empty_null",
"subworkflow_version",
]
else:
return ["main_nf", "meta_yml", "subworkflow_todos", "subworkflow_tests"]
return ["main_nf", "meta_yml", "subworkflow_todos", "subworkflow_if_empty_null", "subworkflow_tests"]

def set_up_pipeline_files(self):
self.load_lint_config()
Expand Down
30 changes: 19 additions & 11 deletions nf_core/components/nfcore_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ def __init__(
repo_dir = self.component_dir.parts[:name_index][-1]

self.org = repo_dir
self.nftest_testdir = Path(self.component_dir, "tests")
self.nftest_main_nf = Path(self.nftest_testdir, "main.nf.test")
self.nftest_testdir: Optional[Path] = Path(self.component_dir, "tests")
self.nftest_main_nf: Optional[Path] = Path(self.nftest_testdir, "main.nf.test")

if self.repo_type == "pipeline":
patch_fn = f"{self.component_name.replace('/', '-')}.diff"
Expand All @@ -85,15 +85,23 @@ def __init__(
self.patch_path = patch_path
else:
# The main file is just the local module
self.main_nf = self.component_dir
self.component_name = self.component_dir.stem
# These attributes are only used by nf-core modules
# so just initialize them to None
self.meta_yml = None
self.environment_yml = None
self.test_dir = None
self.test_yml = None
self.test_main_nf = None
if self.component_dir.is_dir():
self.main_nf = Path(self.component_dir, "main.nf")
self.component_name = self.component_dir.stem
# These attributes are only required by nf-core modules
# so just set them to None if they don't exist
self.meta_yml = p if (p := Path(self.component_dir, "meta.yml")).exists() else None
self.environment_yml = p if (p := Path(self.component_dir, "environment.yml")).exists() else None
self.nftest_testdir = p if (p := Path(self.component_dir, "tests")).exists() else None
if self.nftest_testdir is not None:
self.nftest_main_nf = p if (p := Path(self.nftest_testdir, "main.nf.test")).exists() else None
else:
self.main_nf = self.component_dir
self.component_dir = self.component_dir.parent
self.meta_yml = None
self.environment_yml = None
self.nftest_testdir = None
self.nftest_main_nf = None

self.process_name: str = self._get_process_name()

Expand Down
2 changes: 1 addition & 1 deletion nf_core/components/remove.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,6 @@ def remove(self, component, removed_by=None, removed_components=None, force=Fals
f"Did not remove '{component}', because it was also manually installed. Only updated 'installed_by' entry in modules.json."
)
log.info(
f"""Did not remove {self.component_type[:-1]} '{component}', because it was also installed by {', '.join(f"'{d}'" for d in installed_by)}. Only updated the 'installed_by' entry in modules.json."""
f"""Did not remove {self.component_type[:-1]} '{component}', because it was also installed by {", ".join(f"'{d}'" for d in installed_by)}. Only updated the 'installed_by' entry in modules.json."""
)
return removed
Loading

0 comments on commit e411c65

Please sign in to comment.