comparison planemo/lib/python3.7/site-packages/galaxy/tool_util/linters/inputs.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 """This module contains a linting functions for tool inputs."""
2 from galaxy.util import string_as_bool
3 from ._util import is_datasource, is_valid_cheetah_placeholder
4 from ..parser.util import _parse_name
5
6
7 def lint_inputs(tool_xml, lint_ctx):
8 """Lint parameters in a tool's inputs block."""
9 datasource = is_datasource(tool_xml)
10 inputs = tool_xml.findall("./inputs//param")
11 num_inputs = 0
12 for param in inputs:
13 num_inputs += 1
14 param_attrib = param.attrib
15 has_errors = False
16 if "type" not in param_attrib:
17 lint_ctx.error("Found param input with no type specified.")
18 has_errors = True
19 if "name" not in param_attrib and "argument" not in param_attrib:
20 lint_ctx.error("Found param input with no name specified.")
21 has_errors = True
22
23 if has_errors:
24 continue
25
26 param_type = param_attrib["type"]
27 param_name = _parse_name(param_attrib.get("name"), param_attrib.get("argument"))
28
29 if not is_valid_cheetah_placeholder(param_name):
30 lint_ctx.warn("Param input [%s] is not a valid Cheetah placeholder.", param_name)
31
32 if param_type == "data":
33 if "format" not in param_attrib:
34 lint_ctx.warn("Param input [%s] with no format specified - 'data' format will be assumed.", param_name)
35
36 if param_type == "select":
37 dynamic_options = param.get("dynamic_options", None)
38 if dynamic_options is None:
39 dynamic_options = param.find("options")
40
41 select_options = _find_with_attribute(param, 'option', 'value')
42 if any(['value' not in option.attrib for option in select_options]):
43 lint_ctx.error("Option without value")
44
45 if dynamic_options is None and len(select_options) == 0:
46 message = "No options defined for select [%s]" % param_name
47 lint_ctx.warn(message)
48
49 # TODO: Validate type, much more...
50
51 conditional_selects = tool_xml.findall("./inputs//conditional")
52 for conditional in conditional_selects:
53 conditional_name = conditional.get('name')
54 if not conditional_name:
55 lint_ctx.error("Conditional without a name")
56 if conditional.get("value_from"):
57 # Probably only the upload tool use this, no children elements
58 continue
59 first_param = conditional.find("param")
60 if first_param is None:
61 lint_ctx.error("Conditional '%s' has no child <param>" % conditional_name)
62 continue
63 first_param_type = first_param.get('type')
64 if first_param_type not in ['select', 'boolean']:
65 lint_ctx.warn("Conditional '%s' first param should have type=\"select\" /> or type=\"boolean\"" % conditional_name)
66 continue
67
68 if first_param_type == 'select':
69 select_options = _find_with_attribute(first_param, 'option', 'value')
70 option_ids = [option.get('value') for option in select_options]
71 else: # boolean
72 option_ids = [
73 first_param.get('truevalue', 'true'),
74 first_param.get('falsevalue', 'false')
75 ]
76
77 if string_as_bool(first_param.get('optional', False)):
78 lint_ctx.warn("Conditional test parameter cannot be optional")
79
80 whens = conditional.findall('./when')
81 if any('value' not in when.attrib for when in whens):
82 lint_ctx.error("When without value")
83
84 when_ids = [w.get('value') for w in whens]
85
86 for option_id in option_ids:
87 if option_id not in when_ids:
88 lint_ctx.warn("No <when /> block found for %s option '%s' inside conditional '%s'" % (first_param_type, option_id, conditional_name))
89
90 for when_id in when_ids:
91 if when_id not in option_ids:
92 if first_param_type == 'select':
93 lint_ctx.warn("No <option /> found for when block '%s' inside conditional '%s'" % (when_id, conditional_name))
94 else:
95 lint_ctx.warn("No truevalue/falsevalue found for when block '%s' inside conditional '%s'" % (when_id, conditional_name))
96
97 if datasource:
98 for datasource_tag in ('display', 'uihints'):
99 if not any([param.tag == datasource_tag for param in inputs]):
100 lint_ctx.info("%s tag usually present in data sources" % datasource_tag)
101
102 if num_inputs:
103 lint_ctx.info("Found %d input parameters.", num_inputs)
104 else:
105 if datasource:
106 lint_ctx.info("No input parameters, OK for data sources")
107 else:
108 lint_ctx.warn("Found no input parameters.")
109
110
111 def lint_repeats(tool_xml, lint_ctx):
112 """Lint repeat blocks in tool inputs."""
113 repeats = tool_xml.findall("./inputs//repeat")
114 for repeat in repeats:
115 if "name" not in repeat.attrib:
116 lint_ctx.error("Repeat does not specify name attribute.")
117 if "title" not in repeat.attrib:
118 lint_ctx.error("Repeat does not specify title attribute.")
119
120
121 def _find_with_attribute(element, tag, attribute, test_value=None):
122 rval = []
123 for el in (element.findall('./%s' % tag) or []):
124 if attribute not in el.attrib:
125 continue
126 value = el.attrib[attribute]
127 if test_value is not None:
128 if value == test_value:
129 rval.append(el)
130 else:
131 rval.append(el)
132 return rval