Source code for planemo.tools

"""Planemo-specific wrappers around galaxy-tool-util tool functionality."""

import os
import sys
import traceback
from typing import (
    Iterable,
    Iterator,
    List,
    Optional,
    Tuple,
    TYPE_CHECKING,
    Union,
)

from galaxy.tool_util import loader_directory
from galaxy.tool_util.fetcher import ToolLocationFetcher
from galaxy.tool_util.loader_directory import is_tool_load_error
from galaxy.tool_util.parser.interface import ToolSource

from planemo.io import (
    error,
    info,
)

if TYPE_CHECKING:
    from planemo.cli import PlanemoCliContext

SKIP_XML_MESSAGE = "Skipping XML file - does not appear to be a tool %s."
SHED_FILES = ["tool_dependencies.xml", "repository_dependencies.xml"]
LOAD_ERROR_MESSAGE = "Error loading tool with path %s"


def uri_to_path(ctx: "PlanemoCliContext", uri: str) -> str:
    """Fetch URI to a local path."""
    fetcher = ToolLocationFetcher()
    return fetcher.to_tool_path(uri)


def uris_to_paths(ctx, uris):
    """Fetch multiple URIs to a local path."""
    fetcher = ToolLocationFetcher()
    paths = []
    for uri in uris:
        path = fetcher.to_tool_path(uri)
        paths.append(path)
    return paths


[docs]def yield_tool_sources_on_paths( ctx: Optional["PlanemoCliContext"], paths: Iterable[str], recursive: bool = False, yield_load_errors: bool = True, exclude_deprecated: bool = False, ) -> Iterator[Tuple[str, Union[ToolSource, object]]]: """Walk paths and yield ToolSource objects discovered.""" for path in paths: for (tool_path, tool_source) in yield_tool_sources(ctx, path, recursive, yield_load_errors): if exclude_deprecated and "deprecated" in tool_path: continue yield (tool_path, tool_source)
[docs]def yield_tool_sources( ctx: Optional["PlanemoCliContext"], path: str, recursive: bool = False, yield_load_errors: bool = True ) -> Iterator[Tuple[str, Union[ToolSource, object]]]: """Walk single path and yield ToolSource objects discovered.""" tools = load_tool_sources_from_path( path, recursive, register_load_errors=True, ) for (tool_path, tool_source) in tools: if is_tool_load_error(tool_source): if yield_load_errors: yield (tool_path, tool_source) else: error(LOAD_ERROR_MESSAGE % tool_path) continue if not _is_tool_source(ctx, tool_path, tool_source): continue yield (tool_path, tool_source)
[docs]def load_tool_sources_from_path( path: str, recursive: bool, register_load_errors: bool = False ) -> List[Tuple[str, Union[ToolSource, object]]]: """Generate a list for tool sources found down specified path.""" return loader_directory.load_tool_sources_from_path( path, _load_exception_handler, recursive=recursive, register_load_errors=register_load_errors, )
def _load_exception_handler(path, exc_info): error(LOAD_ERROR_MESSAGE % path) traceback.print_exception(*exc_info, limit=1, file=sys.stderr) def _is_tool_source(ctx: Optional["PlanemoCliContext"], tool_path: str, tool_source: "ToolSource") -> bool: if os.path.basename(tool_path) in SHED_FILES: return False root = getattr(tool_source, "root", None) if root is not None: if root.tag != "tool": if ctx and ctx.verbose: info(SKIP_XML_MESSAGE % tool_path) return False return True __all__ = ( "is_tool_load_error", "load_tool_sources_from_path", "yield_tool_sources", "yield_tool_sources_on_paths", )