comparison planemo/lib/python3.7/site-packages/galaxy/tool_util/parser/yaml.py @ 1:56ad4e20f292 draft

"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author guerler
date Fri, 31 Jul 2020 00:32:28 -0400
parents
children
comparison
equal deleted inserted replaced
0:d30785e31577 1:56ad4e20f292
1 from collections import OrderedDict
2
3 import packaging.version
4
5 from galaxy.tool_util.deps import requirements
6 from galaxy.tool_util.parser.util import (
7 DEFAULT_DELTA,
8 DEFAULT_DELTA_FRAC
9 )
10 from .interface import (
11 InputSource,
12 PageSource,
13 PagesSource,
14 ToolSource,
15 )
16 from .output_collection_def import dataset_collector_descriptions_from_output_dict
17 from .output_objects import (
18 ToolOutput,
19 ToolOutputCollection,
20 ToolOutputCollectionStructure,
21 )
22 from .stdio import error_on_exit_code
23 from .util import is_dict
24
25
26 class YamlToolSource(ToolSource):
27
28 def __init__(self, root_dict, source_path=None):
29 self.root_dict = root_dict
30 self._source_path = source_path
31 self._macro_paths = []
32
33 @property
34 def source_path(self):
35 return self._source_path
36
37 def parse_id(self):
38 return self.root_dict.get("id")
39
40 def parse_version(self):
41 return self.root_dict.get("version")
42
43 def parse_name(self):
44 return self.root_dict.get("name")
45
46 def parse_description(self):
47 return self.root_dict.get("description", "")
48
49 def parse_edam_operations(self):
50 return self.root_dict.get("edam_operations", [])
51
52 def parse_edam_topics(self):
53 return self.root_dict.get("edam_topics", [])
54
55 def parse_xrefs(self):
56 xrefs = self.root_dict.get("xrefs", [])
57 return [dict(value=xref["value"], reftype=xref["type"]) for xref in xrefs if xref["type"]]
58
59 def parse_is_multi_byte(self):
60 return self.root_dict.get("is_multi_byte", self.default_is_multi_byte)
61
62 def parse_sanitize(self):
63 return self.root_dict.get("sanitize", True)
64
65 def parse_display_interface(self, default):
66 return self.root_dict.get('display_interface', default)
67
68 def parse_require_login(self, default):
69 return self.root_dict.get('require_login', default)
70
71 def parse_command(self):
72 return self.root_dict.get("command")
73
74 def parse_expression(self):
75 return self.root_dict.get("expression")
76
77 def parse_environment_variables(self):
78 return []
79
80 def parse_interpreter(self):
81 return self.root_dict.get("interpreter")
82
83 def parse_version_command(self):
84 return self.root_dict.get("runtime_version", {}).get("command", None)
85
86 def parse_version_command_interpreter(self):
87 return self.root_dict.get("runtime_version", {}).get("interpreter", None)
88
89 def parse_requirements_and_containers(self):
90 return requirements.parse_requirements_from_dict(self.root_dict)
91
92 def parse_input_pages(self):
93 # All YAML tools have only one page (feature is deprecated)
94 page_source = YamlPageSource(self.root_dict.get("inputs", {}))
95 return PagesSource([page_source])
96
97 def parse_strict_shell(self):
98 # TODO: Add ability to disable this.
99 return True
100
101 def parse_stdio(self):
102 return error_on_exit_code()
103
104 def parse_help(self):
105 return self.root_dict.get("help", None)
106
107 def parse_outputs(self, tool):
108 outputs = self.root_dict.get("outputs", {})
109 output_defs = []
110 output_collection_defs = []
111 for name, output_dict in outputs.items():
112 output_type = output_dict.get("type", "data")
113 if output_type == "data":
114 output_defs.append(self._parse_output(tool, name, output_dict))
115 elif output_type == "collection":
116 output_collection_defs.append(self._parse_output_collection(tool, name, output_dict))
117 else:
118 message = "Unknown output_type [%s] encountered." % output_type
119 raise Exception(message)
120 outputs = OrderedDict()
121 for output in output_defs:
122 outputs[output.name] = output
123 output_collections = OrderedDict()
124 for output in output_collection_defs:
125 output_collections[output.name] = output
126
127 return outputs, output_collections
128
129 def _parse_output(self, tool, name, output_dict):
130 output = ToolOutput.from_dict(name, output_dict, tool=tool)
131 return output
132
133 def _parse_output_collection(self, tool, name, output_dict):
134 name = output_dict.get("name")
135 label = output_dict.get("label")
136 default_format = output_dict.get("format", "data")
137 collection_type = output_dict.get("type", None)
138 collection_type_source = output_dict.get("type_source", None)
139 structured_like = output_dict.get("structured_like", None)
140 inherit_format = False
141 inherit_metadata = False
142 if structured_like:
143 inherit_format = output_dict.get("inherit_format", None)
144 inherit_metadata = output_dict.get("inherit_metadata", None)
145 default_format_source = output_dict.get("format_source", None)
146 default_metadata_source = output_dict.get("metadata_source", "")
147 filters = []
148 dataset_collector_descriptions = dataset_collector_descriptions_from_output_dict(output_dict)
149
150 structure = ToolOutputCollectionStructure(
151 collection_type=collection_type,
152 collection_type_source=collection_type_source,
153 structured_like=structured_like,
154 dataset_collector_descriptions=dataset_collector_descriptions,
155 )
156 output_collection = ToolOutputCollection(
157 name,
158 structure,
159 label=label,
160 filters=filters,
161 default_format=default_format,
162 inherit_format=inherit_format,
163 inherit_metadata=inherit_metadata,
164 default_format_source=default_format_source,
165 default_metadata_source=default_metadata_source,
166 )
167 return output_collection
168
169 def parse_tests_to_dict(self):
170 tests = []
171 rval = dict(
172 tests=tests
173 )
174
175 for i, test_dict in enumerate(self.root_dict.get("tests", [])):
176 tests.append(_parse_test(i, test_dict))
177
178 return rval
179
180 def parse_profile(self):
181 return self.root_dict.get("profile", "16.04")
182
183 def parse_interactivetool(self):
184 return self.root_dict.get("entry_points", [])
185
186 def parse_python_template_version(self):
187 python_template_version = self.root_dict.get("python_template_version", None)
188 if python_template_version is not None:
189 python_template_version = packaging.version.parse(python_template_version)
190 return python_template_version
191
192
193 def _parse_test(i, test_dict):
194 inputs = test_dict["inputs"]
195 if is_dict(inputs):
196 new_inputs = []
197 for key, value in inputs.items():
198 new_inputs.append({"name": key, "value": value, "attributes": {}})
199 test_dict["inputs"] = new_inputs
200
201 outputs = test_dict["outputs"]
202
203 new_outputs = []
204 if is_dict(outputs):
205 for key, value in outputs.items():
206 if is_dict(value):
207 attributes = value
208 file = attributes.get("file")
209 else:
210 file = value
211 attributes = {}
212 new_outputs.append({
213 "name": key,
214 "value": file,
215 "attributes": attributes
216 })
217 else:
218 for output in outputs:
219 name = output["name"]
220 value = output.get("file", None)
221 attributes = output
222 new_outputs.append((name, value, attributes))
223
224 for output in new_outputs:
225 attributes = output["attributes"]
226 defaults = {
227 'compare': 'diff',
228 'lines_diff': 0,
229 'delta': DEFAULT_DELTA,
230 'delta_frac': DEFAULT_DELTA_FRAC,
231 'sort': False,
232 }
233 # TODO
234 attributes["extra_files"] = []
235 # TODO
236 attributes["metadata"] = {}
237 # TODO
238 assert_list = []
239 assert_list = __to_test_assert_list(attributes.get("asserts", []))
240 attributes["assert_list"] = assert_list
241 _ensure_has(attributes, defaults)
242
243 test_dict["outputs"] = new_outputs
244 # TODO: implement output collections for YAML tools.
245 test_dict["output_collections"] = []
246 test_dict["command"] = __to_test_assert_list(test_dict.get("command", []))
247 test_dict["stdout"] = __to_test_assert_list(test_dict.get("stdout", []))
248 test_dict["stderr"] = __to_test_assert_list(test_dict.get("stderr", []))
249 test_dict["expect_exit_code"] = test_dict.get("expect_exit_code", None)
250 test_dict["expect_failure"] = test_dict.get("expect_exit_code", False)
251 return test_dict
252
253
254 def __to_test_assert_list(assertions):
255 def expand_dict_form(item):
256 key, value = item
257 new_value = value.copy()
258 new_value["that"] = key
259 return new_value
260
261 if is_dict(assertions):
262 assertions = map(expand_dict_form, assertions.items())
263
264 assert_list = []
265 for assertion in assertions:
266 # TODO: not handling nested assertions correctly,
267 # not sure these are used though.
268 children = []
269 if "children" in assertion:
270 children = assertion["children"]
271 del assertion["children"]
272 assert_dict = dict(
273 tag=assertion["that"],
274 attributes=assertion,
275 children=children,
276 )
277 assert_list.append(assert_dict)
278
279 return assert_list or None # XML variant is None if no assertions made
280
281
282 class YamlPageSource(PageSource):
283
284 def __init__(self, inputs_list):
285 self.inputs_list = inputs_list
286
287 def parse_input_sources(self):
288 return map(YamlInputSource, self.inputs_list)
289
290
291 class YamlInputSource(InputSource):
292
293 def __init__(self, input_dict):
294 self.input_dict = input_dict
295
296 def get(self, key, default=None):
297 return self.input_dict.get(key, default)
298
299 def get_bool(self, key, default):
300 return self.input_dict.get(key, default)
301
302 def parse_input_type(self):
303 input_type = self.input_dict["type"]
304 if input_type == "repeat":
305 return "repeat"
306 elif input_type == "conditional":
307 return "conditional"
308 else:
309 return "param"
310
311 def parse_nested_inputs_source(self):
312 assert self.parse_input_type() == "repeat"
313 return YamlPageSource(self.input_dict["blocks"])
314
315 def parse_test_input_source(self):
316 test_dict = self.input_dict.get("test", None)
317 assert test_dict is not None, "conditional must contain a `test` definition"
318 return YamlInputSource(test_dict)
319
320 def parse_when_input_sources(self):
321 input_dict = self.input_dict
322
323 sources = []
324 for value, block in input_dict.get("when", {}).items():
325 if value is True:
326 value = "true"
327 elif value is False:
328 value = "false"
329 else:
330 value = str(value)
331
332 # str here to lose type information like XML, needed?
333 if not isinstance(block, list):
334 block = [block]
335 case_page_source = YamlPageSource(block)
336 sources.append((value, case_page_source))
337 return sources
338
339 def parse_static_options(self):
340 static_options = list()
341 input_dict = self.input_dict
342 for index, option in enumerate(input_dict.get("options", {})):
343 value = option.get("value")
344 label = option.get("label", value)
345 selected = option.get("selected", False)
346 static_options.append((label, value, selected))
347 return static_options
348
349
350 def _ensure_has(dict, defaults):
351 for key, value in defaults.items():
352 if key not in dict:
353 dict[key] = value