diff --git a/CHANGELOG.md b/CHANGELOG.md index ac67ab7bf2..67e6ada896 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ ### General +- `nf-core modules/subworkflows info` now prints the include statement for the module/subworkflow ([#2182](https://github.com/nf-core/tools/pull/2182)). + ## [v2.7.2 - Mercury Eagle Patch](https://github.com/nf-core/tools/releases/tag/2.7.2) - [2022-12-19] ### Template diff --git a/nf_core/components/info.py b/nf_core/components/info.py index b89baaf99e..e4d8038b87 100644 --- a/nf_core/components/info.py +++ b/nf_core/components/info.py @@ -8,6 +8,7 @@ from rich.console import Group from rich.markdown import Markdown from rich.panel import Panel +from rich.syntax import Syntax from rich.table import Table from rich.text import Text @@ -128,6 +129,19 @@ def init_mod_name(self, component): choices=components, style=nf_core.utils.nfcore_question_style, ).unsafe_ask() + else: + if self.repo_type == "pipeline": + # check if the module is locally installed + local_paths = self.modules_json.get_all_components(self.component_type).get( + self.modules_repo.remote_url, {} + ) + for directory, comp in local_paths: + if comp == component: + component_base_path = Path(self.dir, self.component_type) + self.local_path = Path(component_base_path, directory, component) + break + if self.local_path: + self.local = True return component @@ -283,7 +297,7 @@ def generate_component_info_help(self): renderables.append(outputs_table) # Installation command - if self.remote_location: + if self.remote_location and not self.local: cmd_base = f"nf-core {self.component_type}" if self.remote_location != NF_CORE_MODULES_REMOTE: cmd_base = f"nf-core {self.component_type} --git-remote {self.remote_location}" @@ -291,4 +305,29 @@ def generate_component_info_help(self): Text.from_markup(f"\n :computer: Installation command: [magenta]{cmd_base} install {self.component}\n") ) + # Print include statement + if self.local_path: + install_folder = Path(self.dir, self.component_type, self.modules_repo.repo_path) + component_name = "_".join(self.component.upper().split("/")) + renderables.append( + Text.from_markup(f"\n [blue]Use the following statement to include this {self.component_type[:-1]}:") + ) + renderables.append( + Syntax( + f"include {{ {component_name} }} from '../{Path(install_folder, self.component).relative_to(self.dir)}/main'", + "groovy", + theme="ansi_dark", + padding=1, + ) + ) + if self.component_type == "subworkflows": + subworkflow_config = Path(install_folder, self.component, "nextflow.config").relative_to(self.dir) + if os.path.isfile(subworkflow_config): + renderables.append( + Text.from_markup("\n [blue]Add the following config statement to use this subworkflow:") + ) + renderables.append( + Syntax(f"includeConfig '{subworkflow_config}'", "groovy", theme="ansi_dark", padding=1) + ) + return Group(*renderables) diff --git a/nf_core/components/install.py b/nf_core/components/install.py index cb6c59aec3..850cc9d60f 100644 --- a/nf_core/components/install.py +++ b/nf_core/components/install.py @@ -1,6 +1,5 @@ import logging import os -import re from pathlib import Path import questionary @@ -74,10 +73,10 @@ def install(self, component, silent=False): ) # Set the install folder based on the repository name - install_folder = os.path.join(self.dir, self.component_type, self.modules_repo.repo_path) + install_folder = Path(self.dir, self.component_type, self.modules_repo.repo_path) # Compute the component directory - component_dir = os.path.join(install_folder, component) + component_dir = Path(install_folder, component) # Check that the component is not already installed component_not_installed = self.check_component_installed( diff --git a/tests/modules/info.py b/tests/modules/info.py index 6c5b1063f1..2dbd48b240 100644 --- a/tests/modules/info.py +++ b/tests/modules/info.py @@ -38,7 +38,6 @@ def test_modules_info_local(self): """Test getting info about a locally installed module""" self.mods_install.install("trimgalore") mods_info = nf_core.modules.ModuleInfo(self.pipeline_dir, "trimgalore") - mods_info.local = True mods_info_output = mods_info.get_component_info() console = Console(record=True) console.print(mods_info_output) @@ -47,6 +46,7 @@ def test_modules_info_local(self): assert "Module: trimgalore" in output assert "Inputs" in output assert "Outputs" in output + assert "Location" in output def test_modules_info_in_modules_repo(self):