diff env/lib/python3.9/site-packages/galaxy/tool_util/linters/outputs.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/env/lib/python3.9/site-packages/galaxy/tool_util/linters/outputs.py	Mon Mar 22 18:12:50 2021 +0000
@@ -0,0 +1,83 @@
+"""This module contains a linting functions for tool outputs."""
+from ._util import is_valid_cheetah_placeholder
+
+
+def lint_output(tool_xml, lint_ctx):
+    """Check output elements, ensure there is at least one and check attributes."""
+    outputs = tool_xml.findall("./outputs")
+    if len(outputs) == 0:
+        lint_ctx.warn("Tool contains no outputs section, most tools should produce outputs.")
+    if len(outputs) > 1:
+        lint_ctx.warn("Tool contains multiple output sections, behavior undefined.")
+
+    num_outputs = 0
+    if len(outputs) == 0:
+        lint_ctx.warn("No outputs found")
+        return
+
+    for output in list(outputs[0]):
+        if output.tag not in ["data", "collection"]:
+            lint_ctx.warn("Unknown element found in outputs [%s]" % output.tag)
+            continue
+        num_outputs += 1
+        if "name" not in output.attrib:
+            lint_ctx.warn("Tool output doesn't define a name - this is likely a problem.")
+        else:
+            if not is_valid_cheetah_placeholder(output.attrib["name"]):
+                lint_ctx.warn("Tool output name [%s] is not a valid Cheetah placeholder.", output.attrib["name"])
+
+        format_set = False
+        if __check_format(output, lint_ctx):
+            format_set = True
+        if output.tag == "data":
+            if "auto_format" in output.attrib and output.attrib["auto_format"]:
+                format_set = True
+
+        elif output.tag == "collection":
+            if "type" not in output.attrib:
+                lint_ctx.warn("Collection output with undefined 'type' found.")
+            if "structured_like" in output.attrib and "inherit_format" in output.attrib:
+                format_set = True
+        if "format_source" in output.attrib:
+            format_set = True
+        for sub in output:
+            if __check_pattern(sub):
+                format_set = True
+            elif __check_format(sub, lint_ctx, allow_ext=True):
+                format_set = True
+
+        if not format_set:
+            lint_ctx.warn("Tool {} output {} doesn't define an output format.".format(output.tag, output.attrib.get("name", "with missing name")))
+
+    lint_ctx.info("%d outputs found.", num_outputs)
+
+
+def __check_format(node, lint_ctx, allow_ext=False):
+    """
+    check if format/ext attribute is set in a given node
+    issue a warning if the value is input
+    return true (node defines format/ext) / false (else)
+    """
+    fmt = None
+    # if allowed (e.g. for discover_datasets), ext takes precedence over format
+    if allow_ext:
+        fmt = node.attrib.get("ext")
+    if fmt is None:
+        fmt = node.attrib.get("format")
+    if fmt == "input":
+        lint_ctx.warn("Using format='input' on %s, format_source attribute is less ambiguous and should be used instead." % node.tag)
+    return fmt is not None
+
+
+def __check_pattern(node):
+    """
+    check if pattern attribute is set and defines the extension
+    """
+    if node.tag != "discover_datasets":
+        return False
+    if "pattern" not in node.attrib:
+        return False
+    if node.attrib["pattern"] == "__default__":
+        return True
+    if "ext" in node.attrib["pattern"] and node.attrib["pattern"].startswith("__") and node.attrib["pattern"].endswith("__"):
+        return True