Skip to content

Implement wave container commands#3954

Draft
JulianFlesch wants to merge 127 commits into
nf-core:devfrom
JulianFlesch:feature/3952-create-waveyml
Draft

Implement wave container commands#3954
JulianFlesch wants to merge 127 commits into
nf-core:devfrom
JulianFlesch:feature/3952-create-waveyml

Conversation

@JulianFlesch
Copy link
Copy Markdown
Contributor

@JulianFlesch JulianFlesch commented Dec 2, 2025

Closes #3952

  • nf-core modules containers create [module-name]
  • nf-core modules containers conda-lock [module-name]
  • nf-core modules containers lint [module-name]
  • nf-core modules containers list [module-name]

@ningyuxin1999 ningyuxin1999 self-assigned this Dec 2, 2025
@JulianFlesch JulianFlesch changed the title switch pre-commit to prek for development Implement wave container commands Dec 2, 2025
Comment thread nf_core/components/nfcore_component.py
Comment thread nf_core/components/nfcore_component.py Outdated
Comment thread nf_core/modules/containers.py Outdated
Comment thread nf_core/modules/containers.py Outdated
]
return containers_flat

def _resolve_module_dir(self, module: str | Path) -> Path:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we not have this funciton already somehwere else?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be overlooking something, but not really ... As far as I can tell, we have ModulesInfo, which was used at some point, but it never provides the environment.yml or meta.yml paths, or confirms their existance.

Maybe this should be in ModulesInfo?

Comment thread nf_core/modules/containers.py Outdated
return module_dir

@staticmethod
def _environment_path(module_dir: Path) -> Path:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because we lint for this, I think we should be able to reuse something there.

Comment thread nf_core/utils.py


@contextmanager
def set_wd_tempdir() -> Generator[None, None, None]:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function is for sure created somewhere else already.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, In pipeline downloads! But that version throws Download-specific errors ...
The plan was move it out of the utils.py over there into the general utils.
But now we don't use it at all anymore ...

Should we remove it again?

Comment thread nf_core/modules/containers.py Outdated
Comment thread nf_core/modules/containers.py
Comment thread nf_core/modules/containers.py Outdated
Comment thread nf_core/modules/containers.py Outdated
Comment thread nf_core/modules/containers.py Outdated
Comment thread nf_core/modules/containers.py Outdated
Comment thread nf_core/modules/containers.py Outdated
@JulianFlesch
Copy link
Copy Markdown
Contributor Author

JulianFlesch commented Dec 9, 2025

  • Test still missing ( @ningyuxin1999 )
  • Linting still missing
  • Sorting the resulting meta.yml after running create() still missing
  • Refactoring ModuleInfo to be helpful here -> TODO: ISSUE
  • Decision required: Behavior if modules don't have meta.yml and/or environment.yml

Comment thread nf_core/modules/containers.py Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 14, 2026

Codecov Report

❌ Patch coverage is 61.08374% with 316 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.40%. Comparing base (dfe760d) to head (64d98fb).
⚠️ Report is 2 commits behind head on dev.

Files with missing lines Patch % Lines
nf_core/modules/containers.py 70.10% 116 Missing ⚠️
nf_core/commands_modules.py 5.97% 63 Missing ⚠️
nf_core/modules/lint/module_containers.py 74.21% 41 Missing ⚠️
nf_core/components/nfcore_component.py 18.75% 26 Missing ⚠️
nf_core/modules/modules_utils.py 21.87% 25 Missing ⚠️
nf_core/modules/lint/environment_yml.py 46.15% 21 Missing ⚠️
nf_core/modules/lint/meta_yml.py 68.75% 15 Missing ⚠️
nf_core/__main__.py 84.00% 4 Missing ⚠️
nf_core/modules/bump_versions.py 0.00% 2 Missing ⚠️
nf_core/components/components_command.py 75.00% 1 Missing ⚠️
... and 2 more

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mashehu
Copy link
Copy Markdown
Contributor

mashehu commented Jan 17, 2026

Added the meta_yml sorting now. I also switched the default value of --await to true, because it wouldn't get the singularity https links by default.

Comment thread nf_core/components/lint/__init__.py Outdated
Comment on lines 231 to 232
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should also stay

Comment on lines 231 to 232
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should also stay

sort_by="test",
local=False,
fix_version=False,
):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should stay


corrected_data = mod_io_data.copy()

if io_type == "input":
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we also need to keep this

if skip_file.is_file():
with open(skip_file) as fh:
data = json.load(fh)
for system in CONTAINER_SYSTEMS + ["conda"]:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would first check if the module name is actually in the json file. and then start looping through it

Comment thread nf_core/modules/containers.py Outdated

# Load containers from meta.yml into the component before linting
meta_path = Path(self.nfcore_component.component_dir, "meta.yml")
if meta_path.exists():
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for this if clause, we already check that in read_meta_yml()

Comment thread nf_core/modules/modules_utils.py Outdated
Comment thread nf_core/pipelines/lint/__init__.py
Comment thread tests/subworkflows/test_lint.py Outdated
Comment thread pyproject.toml
@mashehu mashehu force-pushed the feature/3952-create-waveyml branch 3 times, most recently from 47ed327 to b71b250 Compare March 30, 2026 08:33
log.error("No modules found to build containers for")
sys.exit(1)

log.info(f"Building containers for {len(manager.available_modules)} module(s)")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make this another progress bar (not a spinner this time)

Comment thread nf_core/modules/containers.py Outdated
sys.exit(1)


def modules_containers_conda_lock(ctx, module, platform=CONTAINER_PLATFORMS[0]):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we actually want this externalized? it is part of nf-core m container c anyway

maintainers:
- "{{ author }}"

# TODO container-conversion: Add "containers" section
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will be automatically generated.

Suggested change
# TODO container-conversion: Add "containers" section

Comment thread nf_core/utils.py
mod.get_inputs_from_main_nf()
mod.get_outputs_from_main_nf()
mod.get_topics_from_main_nf()
# TODO container-conversion: get_containers from main_nf
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use module_containers.list.containers here

Comment thread nf_core/modules/lint/main_nf.py Outdated
@mashehu mashehu force-pushed the feature/3952-create-waveyml branch from 5d3a49b to 3e6859d Compare May 21, 2026 12:10
Comment thread nf_core/modules/lint/main_nf.py Outdated
# Get latest build
build = _get_build(response)
def _fix_module_version(self, current_version, latest_version, response):
"""Updates the module conda version in main.nf."""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should look into environment.yml not main.nf

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and then need to run containers.create on it

Comment on lines +300 to +302
from nf_core.modules.lint.main_nf import _fix_module_version

fixed = _fix_module_version(module, bioconda_version, last_ver, response)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rewrite this part to not touch main.nf but enviroment.yml

if skip_file.is_file():
with open(skip_file) as fh:
data = json.load(fh)
for system in CONTAINER_SYSTEMS + ["conda"]:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rewrite CONTAINER_SYSTEMS+ ["conda"] to something like SYSTEMS

return formatted_topics


def obtain_containers(_, containers: dict) -> dict:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace with get_containers_from_meta or pydantic model

Comment thread nf_core/modules/lint/module_containers.py Outdated
Comment thread nf_core/modules/lint/module_containers.py Outdated
name_hash = tag.rsplit("--", 1)[1]
else:
tag_lower = tag.lower()
if len(tag_lower) >= 8 and all(c in "0123456789abcdef" for c in tag_lower):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't there a better way to check for hexadecimal characters?

(
"meta_yml",
"containers_build_id_hash",
f"Build ID hash does not match {system} container tag for {platform}",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
f"Build ID hash does not match {system} container tag for {platform}",
f"Build ID `{build_hash}` hash does not match {system} container tag `{name_hash}` for {platform}",

(
"meta_yml",
"containers_build_id_hash",
f"Could not compare build ID hash with {system} container tag for {platform}",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
f"Could not compare build ID hash with {system} container tag for {platform}",
f"Could not compare build ID hash with {system} container tag for {platform}, because either build_hash:`{build_hash}` or name_hash:`{name_hash}` is `None`.",

pass


def get_container_with_regex(main_nf_path: Path, component_name: str | None = None) -> str:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add test for this function

)
_, success = manager.create(await_build, progress_bar=progress_bar, task_id=module_task_id, force=force)
if success:
manager.update_containers_in_meta()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if in pipline repo, this should also generate pipeline container configs, I think try_generate_container_configs

Comment thread nf_core/utils.py
from ..test_modules import TestModules


class TestModuleContainers:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class TestModuleContainers:
class TestModuleContainers(TestModules):

I think

def _write_meta(self, module_dir: Path, meta: dict) -> None:
(module_dir / "meta.yml").write_text(yaml.safe_dump(meta), encoding="utf-8")

def _containers_by_system(self, prefix: str = "testC") -> dict:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace with pydantic model

assert manager.module_directory == module_dir
assert manager.environment_yml == module_dir / "environment.yml"
assert manager.meta_yml == module_dir / "meta.yml"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add one integration test to check that the wave logic actually works and doesn't change in the background. maybe with --dry-run

Comment on lines +320 to +321
with mock.patch.object(manager, "get_containers_from_meta", return_value=containers):
listed = manager.list_containers()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't mock this, run this against the gitlab test repo with one specific module

mashehu and others added 2 commits May 21, 2026 15:42
Co-authored-by: Matthias Hörtenhuber <mashehu@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

3 participants