comparison env/lib/python3.7/site-packages/cwltool/software_requirements.py @ 0:26e78fe6e8c4 draft

"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author shellac
date Sat, 02 May 2020 07:14:21 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:26e78fe6e8c4
1 """This module handles resolution of SoftwareRequirement hints.
2
3 This is accomplished mainly by adapting cwltool internals to galaxy-lib's
4 concept of "dependencies". Despite the name, galaxy-lib is a light weight
5 library that can be used to map SoftwareRequirements in all sorts of ways -
6 Homebrew, Conda, custom scripts, environment modules. We'd be happy to find
7 ways to adapt new packages managers and such as well.
8 """
9 from __future__ import absolute_import
10
11 import argparse # pylint: disable=unused-import
12 import os
13 import string
14 from typing import Dict, List, MutableSequence, Optional
15
16 from typing_extensions import Text # pylint: disable=unused-import
17 # move to a regular typing import when Python 3.3-3.6 is no longer supported
18
19 from .builder import Builder, HasReqsHints
20 try:
21 from galaxy.tool_util.deps.requirements import ToolRequirement, ToolRequirements
22 from galaxy.tool_util import deps
23 except ImportError:
24 ToolRequirement = None # type: ignore
25 ToolRequirements = None # type: ignore
26 deps = None # type: ignore
27
28
29 SOFTWARE_REQUIREMENTS_ENABLED = deps is not None
30
31 COMMAND_WITH_DEPENDENCIES_TEMPLATE = string.Template("""#!/bin/bash
32 $handle_dependencies
33 python "run_job.py" "job.json"
34 """)
35
36
37 class DependenciesConfiguration(object):
38
39 def __init__(self, args):
40 # type: (argparse.Namespace) -> None
41 """Initialize."""
42 conf_file = getattr(args, "beta_dependency_resolvers_configuration", None)
43 tool_dependency_dir = getattr(args, "beta_dependencies_directory", None)
44 conda_dependencies = getattr(args, "beta_conda_dependencies", None)
45 if conf_file is not None and os.path.exists(conf_file):
46 self.use_tool_dependencies = True
47 if tool_dependency_dir is None:
48 tool_dependency_dir = os.path.abspath(os.path.dirname(conf_file))
49 self.tool_dependency_dir = tool_dependency_dir
50 self.dependency_resolvers_config_file = os.path.abspath(conf_file)
51 elif conda_dependencies is not None:
52 if tool_dependency_dir is None:
53 tool_dependency_dir = os.path.abspath("./cwltool_deps")
54 self.tool_dependency_dir = tool_dependency_dir
55 self.use_tool_dependencies = True
56 self.dependency_resolvers_config_file = None
57 else:
58 self.use_tool_dependencies = False
59
60 def build_job_script(self, builder, command):
61 # type: (Builder, List[str]) -> Text
62 ensure_galaxy_lib_available()
63 resolution_config_dict = {
64 'use': self.use_tool_dependencies,
65 'default_base_path': self.tool_dependency_dir,
66 }
67 app_config = {
68 'conda_auto_install': True,
69 'conda_auto_init': True,
70 }
71 tool_dependency_manager = deps.build_dependency_manager(
72 app_config_dict=app_config,
73 resolution_config_dict=resolution_config_dict,
74 conf_file=self.dependency_resolvers_config_file,
75 ) # type: deps.DependencyManager
76 dependencies = get_dependencies(builder)
77 handle_dependencies = "" # str
78 if dependencies:
79 handle_dependencies = "\n".join(
80 tool_dependency_manager.dependency_shell_commands(
81 dependencies, job_directory=builder.tmpdir))
82
83 template_kwds = dict(handle_dependencies=handle_dependencies) # type: Dict[str, str]
84 job_script = COMMAND_WITH_DEPENDENCIES_TEMPLATE.substitute(template_kwds)
85 return job_script
86
87
88 def get_dependencies(builder): # type: (HasReqsHints) -> ToolRequirements
89 (software_requirement, _) = builder.get_requirement("SoftwareRequirement")
90 dependencies = [] # type: List[ToolRequirement]
91 if software_requirement and software_requirement.get("packages"):
92 packages = software_requirement.get("packages")
93 for package in packages:
94 version = package.get("version", None)
95 if isinstance(version, MutableSequence):
96 if version:
97 version = version[0]
98 else:
99 version = None
100 specs = [{"uri": s} for s in package.get("specs", [])]
101 dependencies.append(ToolRequirement.from_dict(dict(
102 name=package["package"].split("#")[-1],
103 version=version,
104 type="package",
105 specs=specs,
106 )))
107
108 return ToolRequirements.from_list(dependencies)
109
110
111 def get_container_from_software_requirements(use_biocontainers, builder):
112 # type: (bool, HasReqsHints) -> Optional[Text]
113 if use_biocontainers:
114 ensure_galaxy_lib_available()
115 from galaxy.tool_util.deps.dependencies import AppInfo, ToolInfo
116 from galaxy.tool_util.deps.containers import ContainerRegistry, DOCKER_CONTAINER_TYPE
117 app_info = AppInfo(
118 involucro_auto_init=True,
119 enable_mulled_containers=True,
120 container_image_cache_path=".",
121 ) # type: AppInfo
122 container_registry = ContainerRegistry(app_info) # type: ContainerRegistry
123 requirements = get_dependencies(builder)
124 tool_info = ToolInfo(requirements=requirements) # type: ToolInfo
125 container_description = container_registry.find_best_container_description([DOCKER_CONTAINER_TYPE], tool_info)
126 if container_description:
127 return container_description.identifier
128
129 return None
130
131
132 def ensure_galaxy_lib_available():
133 # type: () -> None
134 if not SOFTWARE_REQUIREMENTS_ENABLED:
135 raise Exception("Optional Python library galaxy-lib not available, it is required for this configuration.")