Source code for planemo.linters.biocontainer_registered

"""Ensure a best-practice BioContainer is registered for a tool."""

from typing import (
    List,
    NamedTuple,
    Optional,
    TYPE_CHECKING,
)

from galaxy.tool_util.deps.container_resolvers.mulled import targets_to_mulled_name
from galaxy.tool_util.lint import Linter

from planemo.conda import tool_source_conda_targets
from planemo.linters.util import (
    cached_lint_result,
    xml_node_from_toolsource,
)

if TYPE_CHECKING:
    from galaxy.tool_util.deps.conda_util import CondaTarget
    from galaxy.tool_util.lint import LintContext
    from galaxy.tool_util.parser.interface import ToolSource

MESSAGE_WARN_NO_REQUIREMENTS = "No valid package requirement tags found to infer BioContainer from."
MESSAGE_WARN_NO_CONTAINER = "Failed to find a BioContainer registered for these requirements."
MESSAGE_INFO_FOUND_BIOCONTAINER = "BioContainer best-practice container found [%s]."

lint_tool_types = ["*"]


[docs] class BiocontainerCheck(NamedTuple): targets: List["CondaTarget"] name: Optional[str]
def _biocontainer_check(tool_source: "ToolSource") -> BiocontainerCheck: def calculate() -> BiocontainerCheck: targets = tool_source_conda_targets(tool_source) name = mulled_container_name("biocontainers", targets) if targets else None return BiocontainerCheck(targets, name) return cached_lint_result(tool_source, "biocontainer_registered", calculate)
[docs] class BiocontainerMissing(Linter):
[docs] @classmethod def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"): check = _biocontainer_check(tool_source) if check.targets and not check.name: requirements_node = xml_node_from_toolsource(tool_source, "requirements") lint_ctx.warn(MESSAGE_WARN_NO_CONTAINER, linter=cls.name(), node=requirements_node)
[docs] class BiocontainerRequirementsMissing(Linter):
[docs] @classmethod def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"): if not _biocontainer_check(tool_source).targets: requirements_node = xml_node_from_toolsource(tool_source, "requirements") lint_ctx.warn(MESSAGE_WARN_NO_REQUIREMENTS, linter=cls.name(), node=requirements_node)
[docs] class BiocontainerValid(Linter):
[docs] @classmethod def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"): check = _biocontainer_check(tool_source) if check.name: requirements_node = xml_node_from_toolsource(tool_source, "requirements") lint_ctx.info( MESSAGE_INFO_FOUND_BIOCONTAINER % check.name, linter=cls.name(), node=requirements_node, )
[docs] def mulled_container_name(namespace: str, targets: List["CondaTarget"]) -> Optional[str]: name = targets_to_mulled_name(targets=targets, hash_func="v2", namespace=namespace) if name: return f"quay.io/{namespace}/{name}" return None