Skip to content

Commit 52e8109

Browse files
authored
Merge pull request #3428 from nf-core/dev
dev -> main for 3.2.0 release
2 parents 34bc338 + 0355435 commit 52e8109

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+434
-209
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/astral-sh/ruff-pre-commit
3-
rev: v0.8.6
3+
rev: v0.9.3
44
hooks:
55
- id: ruff # linter
66
args: [--fix, --exit-non-zero-on-fix] # sort imports and fix
@@ -13,7 +13,7 @@ repos:
1313
1414

1515
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
16-
rev: "3.0.3"
16+
rev: "3.1.2"
1717
hooks:
1818
- id: editorconfig-checker
1919
alias: ec

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# nf-core/tools: Changelog
22

3+
## [v3.2.0 - Pewter Pangolin](https://github.com/nf-core/tools/releases/tag/3.2.0) - [2025-01-27]
4+
5+
### Template
6+
7+
- Remove automated release tweets ([#3419](https://github.com/nf-core/tools/pull/3419))
8+
- Update template components ([#3426](https://github.com/nf-core/tools/pull/3426))
9+
- 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))
10+
11+
### Modules
12+
13+
- Modules created in pipelines "local" dir now use the full template ([#3256](https://github.com/nf-core/tools/pull/3256))
14+
15+
### Subworkflows
16+
17+
- Subworkflows created in pipelines "local" dir now use the full template ([#3256](https://github.com/nf-core/tools/pull/3256))
18+
19+
### General
20+
21+
- Update pre-commit hook editorconfig-checker/editorconfig-checker.python to v3.1.2 ([#3414](https://github.com/nf-core/tools/pull/3414))
22+
- Update python:3.12-slim Docker digest to 123be56 ([#3421](https://github.com/nf-core/tools/pull/3421))
23+
324
## [v3.1.2 - Brass Boxfish Patch](https://github.com/nf-core/tools/releases/tag/3.1.2) - [2025-01-20]
425

526
### Template

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM python:3.12-slim@sha256:10f3aaab98db50cba827d3b33a91f39dc9ec2d02ca9b85cbc5008220d07b17f3
1+
FROM python:3.12-slim@sha256:123be5684f39d8476e64f47a5fddf38f5e9d839baff5c023c815ae5bdfae0df7
22
33
description="Docker image containing requirements for nf-core/tools"
44

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# modules_structure
2+
3+
```{eval-rst}
4+
.. automethod:: nf_core.pipelines.lint.PipelineLint.local_component_structure
5+
```

nf_core/components/components_command.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ def get_local_components(self) -> List[str]:
7171
"""
7272
local_component_dir = Path(self.directory, self.component_type, "local")
7373
return [
74+
str(Path(directory).relative_to(local_component_dir))
75+
for directory, _, files in os.walk(local_component_dir)
76+
if "main.nf" in files
77+
] + [
7478
str(path.relative_to(local_component_dir)) for path in local_component_dir.iterdir() if path.suffix == ".nf"
7579
]
7680

nf_core/components/components_differ.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,9 +271,7 @@ def print_diff(
271271
console = Console(force_terminal=nf_core.utils.rich_force_colors())
272272
if current_version is not None and new_version is not None:
273273
log.info(
274-
f"Changes in component '{Path(repo_path, component)}' between"
275-
f" ({current_version}) and"
276-
f" ({new_version})"
274+
f"Changes in component '{Path(repo_path, component)}' between ({current_version}) and ({new_version})"
277275
)
278276
else:
279277
log.info(f"Changes in component '{Path(repo_path, component)}'")

nf_core/components/create.py

Lines changed: 36 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ def create(self) -> bool:
7575
e.g bam_sort or bam_sort_samtools, respectively.
7676
7777
If <directory> is a pipeline, this function creates a file called:
78-
'<directory>/modules/local/tool.nf'
78+
'<directory>/modules/local/tool/main.nf'
7979
OR
80-
'<directory>/modules/local/tool_subtool.nf'
80+
'<directory>/modules/local/tool/subtool/main.nf'
8181
OR for subworkflows
82-
'<directory>/subworkflows/local/subworkflow_name.nf'
82+
'<directory>/subworkflows/local/subworkflow_name/main.nf'
8383
8484
If <directory> is a clone of nf-core/modules, it creates or modifies the following files:
8585
@@ -355,70 +355,46 @@ def _get_component_dirs(self) -> Dict[str, Path]:
355355
"""
356356
file_paths = {}
357357
if self.repo_type == "pipeline":
358-
local_component_dir = Path(self.directory, self.component_type, "local")
359-
# Check whether component file already exists
360-
component_file = local_component_dir / f"{self.component_name}.nf"
361-
if component_file.exists() and not self.force_overwrite:
362-
raise UserWarning(
363-
f"{self.component_type[:-1].title()} file exists already: '{component_file}'. Use '--force' to overwrite"
364-
)
365-
366-
if self.component_type == "modules":
367-
# If a subtool, check if there is a module called the base tool name already
368-
if self.subtool and (local_component_dir / f"{self.component}.nf").exists():
369-
raise UserWarning(
370-
f"Module '{self.component}' exists already, cannot make subtool '{self.component_name}'"
371-
)
372-
373-
# If no subtool, check that there isn't already a tool/subtool
374-
tool_glob = glob.glob(f"{local_component_dir}/{self.component}_*.nf")
375-
if not self.subtool and tool_glob:
376-
raise UserWarning(
377-
f"Module subtool '{tool_glob[0]}' exists already, cannot make tool '{self.component_name}'"
378-
)
379-
380-
# Set file paths
381-
file_paths["main.nf"] = component_file
358+
component_dir = Path(self.directory, self.component_type, "local", self.component_dir)
382359

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

391-
if self.component_type == "modules":
392-
# If a subtool, check if there is a module called the base tool name already
393-
parent_tool_main_nf = Path(
394-
self.directory,
395-
self.component_type,
396-
self.org,
397-
self.component,
398-
"main.nf",
365+
# Check if module/subworkflow directories exist already
366+
if component_dir.exists() and not self.force_overwrite and not self.migrate_pytest:
367+
raise UserWarning(
368+
f"{self.component_type[:-1]} directory exists: '{component_dir}'. Use '--force' to overwrite"
369+
)
370+
371+
if self.component_type == "modules":
372+
# If a subtool, check if there is a module called the base tool name already
373+
parent_tool_main_nf = Path(
374+
self.directory,
375+
self.component_type,
376+
self.org,
377+
self.component,
378+
"main.nf",
379+
)
380+
if self.subtool and parent_tool_main_nf.exists() and not self.migrate_pytest:
381+
raise UserWarning(
382+
f"Module '{parent_tool_main_nf}' exists already, cannot make subtool '{self.component_name}'"
399383
)
400-
if self.subtool and parent_tool_main_nf.exists() and not self.migrate_pytest:
401-
raise UserWarning(
402-
f"Module '{parent_tool_main_nf}' exists already, cannot make subtool '{self.component_name}'"
403-
)
404384

405-
# If no subtool, check that there isn't already a tool/subtool
406-
tool_glob = glob.glob(
407-
f"{Path(self.directory, self.component_type, self.org, self.component)}/*/main.nf"
385+
# If no subtool, check that there isn't already a tool/subtool
386+
tool_glob = glob.glob(f"{Path(self.directory, self.component_type, self.org, self.component)}/*/main.nf")
387+
if not self.subtool and tool_glob and not self.migrate_pytest:
388+
raise UserWarning(
389+
f"Module subtool '{tool_glob[0]}' exists already, cannot make tool '{self.component_name}'"
408390
)
409-
if not self.subtool and tool_glob and not self.migrate_pytest:
410-
raise UserWarning(
411-
f"Module subtool '{tool_glob[0]}' exists already, cannot make tool '{self.component_name}'"
412-
)
413-
# Set file paths
414-
# For modules - can be tool/ or tool/subtool/ so can't do in template directory structure
415-
file_paths["main.nf"] = component_dir / "main.nf"
416-
file_paths["meta.yml"] = component_dir / "meta.yml"
417-
if self.component_type == "modules":
418-
file_paths["environment.yml"] = component_dir / "environment.yml"
419-
file_paths["tests/main.nf.test.j2"] = component_dir / "tests" / "main.nf.test"
420-
else:
421-
raise ValueError("`repo_type` not set correctly")
391+
# Set file paths
392+
# For modules - can be tool/ or tool/subtool/ so can't do in template directory structure
393+
file_paths["main.nf"] = component_dir / "main.nf"
394+
file_paths["meta.yml"] = component_dir / "meta.yml"
395+
if self.component_type == "modules":
396+
file_paths["environment.yml"] = component_dir / "environment.yml"
397+
file_paths["tests/main.nf.test.j2"] = component_dir / "tests" / "main.nf.test"
422398

423399
return file_paths
424400

nf_core/components/info.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,9 @@ def generate_component_info_help(self):
265265
intro_text.append(
266266
Text.from_markup(
267267
":globe_with_meridians: Repository: "
268-
f"{ '[link={self.remote_location}]' if self.remote_location.startswith('http') else ''}"
268+
f"{'[link={self.remote_location}]' if self.remote_location.startswith('http') else ''}"
269269
f"{self.remote_location}"
270-
f"{'[/link]' if self.remote_location.startswith('http') else '' }"
270+
f"{'[/link]' if self.remote_location.startswith('http') else ''}"
271271
"\n"
272272
)
273273
)

nf_core/components/lint/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def __init__(
102102
continue
103103
if isinstance(components, str):
104104
raise LookupError(
105-
f"Error parsing modules.json: {components}. " f"Please check the file for errors or try again."
105+
f"Error parsing modules.json: {components}. Please check the file for errors or try again."
106106
)
107107
for org, comp in components:
108108
self.all_remote_components.append(
@@ -162,6 +162,10 @@ def _set_registry(self, registry) -> None:
162162
self.registry = registry
163163
log.debug(f"Registry set to {self.registry}")
164164

165+
@property
166+
def local_module_exclude_tests(self):
167+
return ["module_version", "module_changes", "modules_patch"]
168+
165169
@staticmethod
166170
def get_all_module_lint_tests(is_pipeline):
167171
if is_pipeline:

nf_core/components/nfcore_component.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ def __init__(
7474
repo_dir = self.component_dir.parts[:name_index][-1]
7575

7676
self.org = repo_dir
77-
self.nftest_testdir = Path(self.component_dir, "tests")
78-
self.nftest_main_nf = Path(self.nftest_testdir, "main.nf.test")
77+
self.nftest_testdir: Optional[Path] = Path(self.component_dir, "tests")
78+
self.nftest_main_nf: Optional[Path] = Path(self.nftest_testdir, "main.nf.test")
7979

8080
if self.repo_type == "pipeline":
8181
patch_fn = f"{self.component_name.replace('/', '-')}.diff"
@@ -85,15 +85,23 @@ def __init__(
8585
self.patch_path = patch_path
8686
else:
8787
# The main file is just the local module
88-
self.main_nf = self.component_dir
89-
self.component_name = self.component_dir.stem
90-
# These attributes are only used by nf-core modules
91-
# so just initialize them to None
92-
self.meta_yml = None
93-
self.environment_yml = None
94-
self.test_dir = None
95-
self.test_yml = None
96-
self.test_main_nf = None
88+
if self.component_dir.is_dir():
89+
self.main_nf = Path(self.component_dir, "main.nf")
90+
self.component_name = self.component_dir.stem
91+
# These attributes are only required by nf-core modules
92+
# so just set them to None if they don't exist
93+
self.meta_yml = p if (p := Path(self.component_dir, "meta.yml")).exists() else None
94+
self.environment_yml = p if (p := Path(self.component_dir, "environment.yml")).exists() else None
95+
self.nftest_testdir = p if (p := Path(self.component_dir, "tests")).exists() else None
96+
if self.nftest_testdir is not None:
97+
self.nftest_main_nf = p if (p := Path(self.nftest_testdir, "main.nf.test")).exists() else None
98+
else:
99+
self.main_nf = self.component_dir
100+
self.component_dir = self.component_dir.parent
101+
self.meta_yml = None
102+
self.environment_yml = None
103+
self.nftest_testdir = None
104+
self.nftest_main_nf = None
97105

98106
self.process_name: str = self._get_process_name()
99107

0 commit comments

Comments
 (0)