Skip to content

Commit 51b8320

Browse files
committed
Log subworkflow dependencies on install (#3871)
Mirror remove.py by logging installed components and their dependencies during subworkflow install, and add a test for the dependency log output.
1 parent cb623e0 commit 51b8320

3 files changed

Lines changed: 42 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
- Add `nf-core modules containers create` to build module containers via Seqera Wave and record them in the `containers:` section of `meta.yml` ([#3954](https://github.com/nf-core/tools/pull/3954))
2626
- Add a log hint in `modules create` for `create containers` and switch `modules bump-versions` to use Seqera containers ([#4374](https://github.com/nf-core/tools/pull/4374))
2727

28+
- Log subworkflow dependencies on install ([#4357](https://github.com/nf-core/tools/pull/4357))
29+
2830
### Template
2931

3032
- New pre-commit hooks blocking large files and merge markers in pipeline template ([#3935](https://github.com/nf-core/tools/pull/3935))

nf_core/components/install.py

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ def __init__(
5252
else:
5353
self.installed_by = [self.component_type]
5454

55-
def install(self, component: str | dict[str, str], silent: bool = False) -> bool:
55+
def install(
56+
self,
57+
component: str | dict[str, str],
58+
silent: bool = False,
59+
) -> bool:
5660
if isinstance(component, dict):
5761
# Override modules_repo when the component to install is a dependency from a subworkflow.
5862
remote_url = component.get("git_remote", self.current_remote.remote_url)
@@ -167,6 +171,7 @@ def install(self, component: str | dict[str, str], silent: bool = False) -> bool
167171
self.component_type, self.modules_repo, component, version, self.installed_by, install_track
168172
)
169173

174+
dependencies: list[str] = []
170175
if self.component_type == "subworkflows":
171176
# Under --skip-deps, don't propagate --force to transitive deps so
172177
# already-installed ones keep their pinned SHAs and just have
@@ -175,11 +180,16 @@ def install(self, component: str | dict[str, str], silent: bool = False) -> bool
175180
original_force = self.force
176181
self.force = False
177182
try:
178-
self.install_included_components(component_dir)
183+
dependencies = self.install_included_components(component_dir)
179184
finally:
180185
self.force = original_force
181186
else:
182-
self.install_included_components(component_dir)
187+
dependencies = self.install_included_components(component_dir)
188+
189+
if dependencies:
190+
log.info(f"Installed files for '{component}' and its dependencies '{', '.join(sorted(dependencies))}'.")
191+
else:
192+
log.info(f"Installed files for '{component}'.")
183193

184194
# Update container configs for the installed module. Subworkflows have no container entries of their
185195
# own; their included modules each trigger this when installed above.
@@ -207,29 +217,42 @@ def install(self, component: str | dict[str, str], silent: bool = False) -> bool
207217
Console().print(
208218
Syntax(f"includeConfig '{subworkflow_config}'", "groovy", theme="ansi_dark", padding=1)
209219
)
220+
210221
return True
211222

212-
def install_included_components(self, subworkflow_dir):
223+
def install_included_components(self, subworkflow_dir) -> list[str]:
213224
"""
214225
Install included modules and subworkflows
215226
"""
227+
installed_components: list[str] = []
216228
ini_modules_repo = self.modules_repo
217229
modules_to_install, subworkflows_to_install = get_components_to_install(subworkflow_dir)
218-
for s_install in subworkflows_to_install:
230+
for subworkflow_to_install in subworkflows_to_install:
219231
original_installed = self.installed_by
220232
self.installed_by = [Path(subworkflow_dir).parts[-1]]
221-
self.install(s_install, silent=True)
233+
dependency_installed = self.install(subworkflow_to_install, silent=True)
222234
self.installed_by = original_installed
223-
for m_install in modules_to_install:
235+
if dependency_installed:
236+
component_name = (
237+
subworkflow_to_install["name"]
238+
if isinstance(subworkflow_to_install, dict)
239+
else subworkflow_to_install
240+
)
241+
installed_components.append(component_name.replace("/", "_"))
242+
for module_to_install in modules_to_install:
224243
original_component_type = self.component_type
225244
self.component_type = "modules"
226245
original_installed = self.installed_by
227246
self.installed_by = [Path(subworkflow_dir).parts[-1]]
228-
self.install(m_install, silent=True)
247+
dependency_installed = self.install(module_to_install, silent=True)
229248
self.component_type = original_component_type
230249
self.installed_by = original_installed
250+
if dependency_installed:
251+
component_name = module_to_install["name"] if isinstance(module_to_install, dict) else module_to_install
252+
installed_components.append(component_name.replace("/", "_"))
231253
# self.install will have modified self.modules_repo. Restore its original value
232254
self.modules_repo = ini_modules_repo
255+
return installed_components
233256

234257
def collect_and_verify_name(
235258
self, component: str | None, modules_repo: "nf_core.modules.modules_repo.ModulesRepo"

tests/subworkflows/test_install.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
from pathlib import Path
23

34
import pytest
@@ -65,6 +66,14 @@ def test_subworkflows_install_bam_sort_stats_samtools(self):
6566
assert samtools_idxstats_path.exists()
6667
assert samtools_flagstat_path.exists()
6768

69+
def test_subworkflows_install_logs_dependencies(self):
70+
"""Installing a subworkflow should log its module dependencies."""
71+
self.caplog.set_level(logging.INFO)
72+
assert self.subworkflow_install.install("bam_sort_stats_samtools") is not False
73+
assert "Installed files for 'bam_sort_stats_samtools' and its dependencies" in self.caplog.text
74+
assert "samtools_index" in self.caplog.text
75+
assert "bam_stats_samtools" in self.caplog.text
76+
6877
def test_subworkflow_install_nopipeline(self):
6978
"""Test installing a subworkflow - no pipeline given"""
7079
assert self.subworkflow_install.directory is not None

0 commit comments

Comments
 (0)