From 9f349f045c9eadcadb89a6070d7d38d4a17953e5 Mon Sep 17 00:00:00 2001 From: "Moritz E. Beber" Date: Sun, 12 Mar 2023 18:00:35 +0100 Subject: [PATCH 1/3] refactor: remove the mulled command and all related code --- nf_core/__main__.py | 45 +---------------------- nf_core/modules/__init__.py | 1 - nf_core/modules/mulled.py | 72 ------------------------------------- requirements.txt | 1 - tests/test_mulled.py | 65 --------------------------------- 5 files changed, 1 insertion(+), 183 deletions(-) delete mode 100644 nf_core/modules/mulled.py delete mode 100644 tests/test_mulled.py diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 841cb9f7e7..4df0dd2d93 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -52,7 +52,7 @@ }, { "name": "Developing new modules", - "commands": ["create", "create-test-yml", "lint", "bump-versions", "mulled", "test"], + "commands": ["create", "create-test-yml", "lint", "bump-versions", "test"], }, ], "nf-core subworkflows": [ @@ -875,49 +875,6 @@ def bump_versions(ctx, tool, dir, all, show_all): sys.exit(1) -# nf-core modules mulled -@modules.command() -@click.argument("specifications", required=True, nargs=-1, metavar=" <...>") -@click.option( - "--build-number", - type=int, - default=0, - show_default=True, - metavar="", - help="The build number for this image. This is an incremental value that starts at zero.", -) -def mulled(specifications, build_number): - """ - Generate the name of a BioContainers mulled image version 2. - - When you know the specific dependencies and their versions of a multi-tool container image and you need the name of - that image, this command can generate it for you. - - """ - from nf_core.modules.mulled import MulledImageNameGenerator - - try: - image_name = MulledImageNameGenerator.generate_image_name( - MulledImageNameGenerator.parse_targets(specifications), build_number=build_number - ) - except ValueError as e: - log.error(e) - sys.exit(1) - if not MulledImageNameGenerator.image_exists(image_name): - log.error("The generated multi-tool container image name does not seem to exist yet.") - log.info( - "Please double check that your provided combination of tools and versions exists in the file: " - "[link=https://github.com/BioContainers/multi-package-containers/blob/master/combinations/hash.tsv]BioContainers/multi-package-containers 'combinations/hash.tsv'[/link]" - ) - log.info( - "If it does not, please add your desired combination as detailed at: " - "https://github.com/BioContainers/multi-package-containers" - ) - sys.exit(1) - log.info("Mulled container hash:") - stdout.print(image_name) - - # nf-core modules test @modules.command("test") @click.pass_context diff --git a/nf_core/modules/__init__.py b/nf_core/modules/__init__.py index 060b39124b..47af637d02 100644 --- a/nf_core/modules/__init__.py +++ b/nf_core/modules/__init__.py @@ -8,7 +8,6 @@ from .modules_repo import ModulesRepo from .modules_test import ModulesTest from .modules_utils import ModuleException -from .mulled import MulledImageNameGenerator from .patch import ModulePatch from .remove import ModuleRemove from .test_yml_builder import ModulesTestYmlBuilder diff --git a/nf_core/modules/mulled.py b/nf_core/modules/mulled.py deleted file mode 100644 index fc1d1a3555..0000000000 --- a/nf_core/modules/mulled.py +++ /dev/null @@ -1,72 +0,0 @@ -"""Generate the name of a BioContainers mulled image version 2.""" - - -import logging -import re -from typing import Iterable, List, Tuple - -import requests -from galaxy.tool_util.deps.mulled.util import build_target, v2_image_name -from packaging.version import InvalidVersion, Version - -log = logging.getLogger(__name__) - - -class MulledImageNameGenerator: - """ - Define a service class for generating BioContainers version 2 mulled image names. - - Adapted from https://gist.github.com/natefoo/19cefeedd1942c30f9d88027a61b3f83. - - """ - - _split_pattern = re.compile(r"==?") - - @classmethod - def parse_targets(cls, specifications: Iterable[str]) -> List[Tuple[str, str]]: - """ - Parse tool, version pairs from specification strings. - - Args: - specifications: An iterable of strings that contain tools and their versions. - - """ - result = [] - for spec in specifications: - try: - tool, version = cls._split_pattern.split(spec, maxsplit=1) - except ValueError: - raise ValueError( - f"The specification {spec} does not have the expected format or ." - ) from None - try: - Version(version) - except InvalidVersion: - raise ValueError(f"Not a PEP440 version spec: '{version}' in '{spec}'") from None - result.append((tool.strip(), version.strip())) - return result - - @classmethod - def generate_image_name(cls, targets: Iterable[Tuple[str, str]], build_number: int = 0) -> str: - """ - Generate the name of a BioContainers mulled image version 2. - - Args: - targets: One or more tool, version pairs of the multi-tool container image. - build_number: The build number for this image. This is an incremental value that starts at zero. - - """ - return v2_image_name([build_target(name, version) for name, version in targets], image_build=str(build_number)) - - @classmethod - def image_exists(cls, image_name: str) -> bool: - """Check whether a given BioContainers image name exists via a call to the quay.io API.""" - quay_url = f"https://quay.io/biocontainers/{image_name}/" - response = requests.get(quay_url, allow_redirects=True) - log.debug(f"Got response code '{response.status_code}' for URL {quay_url}") - if response.status_code == 200: - log.info(f"Found [link={quay_url}]docker image[/link] on quay.io! :sparkles:") - return True - else: - log.error(f"Was not able to find [link={quay_url}]docker image[/link] on quay.io") - return False diff --git a/requirements.txt b/requirements.txt index b3d1f251bf..8b85e605ad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ click filetype -galaxy-tool-util GitPython jinja2 jsonschema>=3.0 diff --git a/tests/test_mulled.py b/tests/test_mulled.py deleted file mode 100644 index cf0a4fcfc0..0000000000 --- a/tests/test_mulled.py +++ /dev/null @@ -1,65 +0,0 @@ -"""Test the mulled BioContainers image name generation.""" - -import pytest - -from nf_core.modules import MulledImageNameGenerator - - -@pytest.mark.parametrize( - "specs, expected", - [ - (["foo==0.1.2", "bar==1.1"], [("foo", "0.1.2"), ("bar", "1.1")]), - (["foo=0.1.2", "bar=1.1"], [("foo", "0.1.2"), ("bar", "1.1")]), - ], -) -def test_target_parsing(specs, expected): - """Test that valid specifications are correctly parsed into tool, version pairs.""" - assert MulledImageNameGenerator.parse_targets(specs) == expected - - -@pytest.mark.parametrize( - "specs", - [ - ["foo<0.1.2", "bar==1.1"], - ["foo=0.1.2", "bar>1.1"], - ], -) -def test_wrong_specification(specs): - """Test that unexpected version constraints fail.""" - with pytest.raises(ValueError, match="expected format"): - MulledImageNameGenerator.parse_targets(specs) - - -@pytest.mark.parametrize( - "specs", - [ - ["foo==0a.1.2", "bar==1.1"], - ["foo==0.1.2", "bar==1.b1b"], - ], -) -def test_noncompliant_version(specs): - """Test that version string that do not comply with PEP440 fail.""" - with pytest.raises(ValueError, match="PEP440"): - MulledImageNameGenerator.parse_targets(specs) - - -@pytest.mark.parametrize( - "specs, expected", - [ - ( - [("chromap", "0.2.1"), ("samtools", "1.15")], - "mulled-v2-1f09f39f20b1c4ee36581dc81cc323c70e661633:bd74d08a359024829a7aec1638a28607bbcd8a58-0", - ), - ( - [("pysam", "0.16.0.1"), ("biopython", "1.78")], - "mulled-v2-3a59640f3fe1ed11819984087d31d68600200c3f:185a25ca79923df85b58f42deb48f5ac4481e91f-0", - ), - ( - [("samclip", "0.4.0"), ("samtools", "1.15")], - "mulled-v2-d057255d4027721f3ab57f6a599a2ae81cb3cbe3:13051b049b6ae536d76031ba94a0b8e78e364815-0", - ), - ], -) -def test_generate_image_name(specs, expected): - """Test that a known image name is generated from given targets.""" - assert MulledImageNameGenerator.generate_image_name(specs) == expected From 3a4b67dd890dd4445b75c63f1863edd3b55fbfa9 Mon Sep 17 00:00:00 2001 From: "Moritz E. Beber" Date: Sun, 12 Mar 2023 18:16:21 +0100 Subject: [PATCH 2/3] docs: remove mulled command from readme --- README.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/README.md b/README.md index fa4fc96d0e..284f6d69c6 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,6 @@ A python package with helper tools for the nf-core community. - [`modules lint` - Check a module against nf-core guidelines](#check-a-module-against-nf-core-guidelines) - [`modules test` - Run the tests for a module](#run-the-tests-for-a-module-using-pytest) - [`modules bump-versions` - Bump software versions of modules](#bump-bioconda-and-container-versions-of-modules-in) - - [`modules mulled` - Generate the name for a multi-tool container image](#generate-the-name-for-a-multi-tool-container-image) - [`nf-core subworkflows` - commands for dealing with subworkflows](#subworkflows) - [`subworkflows list` - List available subworkflows](#list-subworkflows) @@ -961,17 +960,6 @@ bump-versions: star/align: "2.6.1d" ``` -### Generate the name for a multi-tool container image - -When you want to use an image of a multi-tool container and you know the specific dependencies and their versions of that container, for example, by looking them up in the [BioContainers hash.tsv](https://github.com/BioContainers/multi-package-containers/blob/master/combinations/hash.tsv), you can use the `nf-core modules mulled` helper tool. This tool generates the name of a BioContainers mulled image. - - - -![`nf-core modules mulled pysam==0.16.0.1 biopython==1.78`](docs/images/nf-core-modules-mulled.svg) - ## Subworkflows After the launch of nf-core modules, we can provide now also nf-core subworkflows to fully utilize the power of DSL2 modularization. From 1bde22236d89b4c40a848b97447f9bd370f0833e Mon Sep 17 00:00:00 2001 From: "Moritz E. Beber" Date: Sun, 12 Mar 2023 18:19:16 +0100 Subject: [PATCH 3/3] docs: describe removal in changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34276b0321..386f097f97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ ### Modules - Add an `--empty-template` option to create a module without TODO statements or examples ([#2175](https://github.com/nf-core/tools/pull/2175) & [#2177](https://github.com/nf-core/tools/pull/2177)) +- Removed the `nf-core modules mulled` command and all its code dependencies ([2199](https://github.com/nf-core/tools/pull/2199)). ### Subworkflows