diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/planemo/lib/python3.7/site-packages/galaxy/tool_util/linters/inputs.py	Fri Jul 31 00:32:28 2020 -0400
@@ -0,0 +1,132 @@
+"""This module contains a linting functions for tool inputs."""
+from galaxy.util import string_as_bool
+from ._util import is_datasource, is_valid_cheetah_placeholder
+from ..parser.util import _parse_name
+
+
+def lint_inputs(tool_xml, lint_ctx):
+    """Lint parameters in a tool's inputs block."""
+    datasource = is_datasource(tool_xml)
+    inputs = tool_xml.findall("./inputs//param")
+    num_inputs = 0
+    for param in inputs:
+        num_inputs += 1
+        param_attrib = param.attrib
+        has_errors = False
+        if "type" not in param_attrib:
+            lint_ctx.error("Found param input with no type specified.")
+            has_errors = True
+        if "name" not in param_attrib and "argument" not in param_attrib:
+            lint_ctx.error("Found param input with no name specified.")
+            has_errors = True
+
+        if has_errors:
+            continue
+
+        param_type = param_attrib["type"]
+        param_name = _parse_name(param_attrib.get("name"), param_attrib.get("argument"))
+
+        if not is_valid_cheetah_placeholder(param_name):
+            lint_ctx.warn("Param input [%s] is not a valid Cheetah placeholder.", param_name)
+
+        if param_type == "data":
+            if "format" not in param_attrib:
+                lint_ctx.warn("Param input [%s] with no format specified - 'data' format will be assumed.", param_name)
+
+        if param_type == "select":
+            dynamic_options = param.get("dynamic_options", None)
+            if dynamic_options is None:
+                dynamic_options = param.find("options")
+
+            select_options = _find_with_attribute(param, 'option', 'value')
+            if any(['value' not in option.attrib for option in select_options]):
+                lint_ctx.error("Option without value")
+
+            if dynamic_options is None and len(select_options) == 0:
+                message = "No options defined for select [%s]" % param_name
+                lint_ctx.warn(message)
+
+        # TODO: Validate type, much more...
+
+    conditional_selects = tool_xml.findall("./inputs//conditional")
+    for conditional in conditional_selects:
+        conditional_name = conditional.get('name')
+        if not conditional_name:
+            lint_ctx.error("Conditional without a name")
+        if conditional.get("value_from"):
+            # Probably only the upload tool use this, no children elements
+            continue
+        first_param = conditional.find("param")
+        if first_param is None:
+            lint_ctx.error("Conditional '%s' has no child <param>" % conditional_name)
+            continue
+        first_param_type = first_param.get('type')
+        if first_param_type not in ['select', 'boolean']:
+            lint_ctx.warn("Conditional '%s' first param should have type=\"select\" /> or type=\"boolean\"" % conditional_name)
+            continue
+
+        if first_param_type == 'select':
+            select_options = _find_with_attribute(first_param, 'option', 'value')
+            option_ids = [option.get('value') for option in select_options]
+        else:  # boolean
+            option_ids = [
+                first_param.get('truevalue', 'true'),
+                first_param.get('falsevalue', 'false')
+            ]
+
+        if string_as_bool(first_param.get('optional', False)):
+            lint_ctx.warn("Conditional test parameter cannot be optional")
+
+        whens = conditional.findall('./when')
+        if any('value' not in when.attrib for when in whens):
+            lint_ctx.error("When without value")
+
+        when_ids = [w.get('value') for w in whens]
+
+        for option_id in option_ids:
+            if option_id not in when_ids:
+                lint_ctx.warn("No <when /> block found for %s option '%s' inside conditional '%s'" % (first_param_type, option_id, conditional_name))
+
+        for when_id in when_ids:
+            if when_id not in option_ids:
+                if first_param_type == 'select':
+                    lint_ctx.warn("No <option /> found for when block '%s' inside conditional '%s'" % (when_id, conditional_name))
+                else:
+                    lint_ctx.warn("No truevalue/falsevalue found for when block '%s' inside conditional '%s'" % (when_id, conditional_name))
+
+    if datasource:
+        for datasource_tag in ('display', 'uihints'):
+            if not any([param.tag == datasource_tag for param in inputs]):
+                lint_ctx.info("%s tag usually present in data sources" % datasource_tag)
+
+    if num_inputs:
+        lint_ctx.info("Found %d input parameters.", num_inputs)
+    else:
+        if datasource:
+            lint_ctx.info("No input parameters, OK for data sources")
+        else:
+            lint_ctx.warn("Found no input parameters.")
+
+
+def lint_repeats(tool_xml, lint_ctx):
+    """Lint repeat blocks in tool inputs."""
+    repeats = tool_xml.findall("./inputs//repeat")
+    for repeat in repeats:
+        if "name" not in repeat.attrib:
+            lint_ctx.error("Repeat does not specify name attribute.")
+        if "title" not in repeat.attrib:
+            lint_ctx.error("Repeat does not specify title attribute.")
+
+
+def _find_with_attribute(element, tag, attribute, test_value=None):
+    rval = []
+    for el in (element.findall('./%s' % tag) or []):
+        if attribute not in el.attrib:
+            continue
+        value = el.attrib[attribute]
+        if test_value is not None:
+            if value == test_value:
+                rval.append(el)
+        else:
+            rval.append(el)
+    return rval