[med-svn] [python-galaxyxml] 01/11: Imported Upstream version 0.1

Andreas Tille tille at debian.org
Sat Jan 14 14:55:22 UTC 2017


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository python-galaxyxml.

commit 9bbb0a5ea094eed53a61c1c8c07bdfaf4b682614
Author: Anton Khodak <anton.khodak at ukr.net>
Date:   Sat Jan 14 15:43:42 2017 +0200

    Imported Upstream version 0.1
---
 .gitignore                            |  67 ++++++
 README.md                             |  20 ++
 examples/example.py                   |  51 +++++
 examples/tool.xml                     |  20 ++
 galaxyxml/__init__.py                 |  47 ++++
 galaxyxml/tool/__init__.py            | 103 +++++++++
 galaxyxml/tool/parameters/__init__.py | 400 ++++++++++++++++++++++++++++++++++
 parser.py                             | 119 ++++++++++
 requirements.txt                      |   1 +
 setup.py                              |  19 ++
 10 files changed, 847 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..47af8f3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,67 @@
+# Created by https://www.gitignore.io
+
+### vim ###
+[._]*.s[a-w][a-z]
+[._]s[a-w][a-z]
+*.un~
+Session.vim
+.netrwhist
+*~
+
+
+### Python ###
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.cache
+nosetests.xml
+coverage.xml
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..32dcbe7
--- /dev/null
+++ b/README.md
@@ -0,0 +1,20 @@
+# Galaxy XML Generation Libraries
+
+These libraries will support building of Tool XML and Tool Dependencies XML.
+We'd be happy to support any other XML that Galaxy supports, just make an issue
+or PR if you're feeling motivated.
+
+## Status
+
+- ToolXML is mostly supported, there
+
+## Known Bugs
+
+- no validation of unique names
+- repeats aren't named properly
+- conditional/whens aren't named properly
+- conditionals not handled in CLI
+
+## License
+
+- Apache License, v2
diff --git a/examples/example.py b/examples/example.py
new file mode 100644
index 0000000..c97d48a
--- /dev/null
+++ b/examples/example.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+import galaxyxml.tool as gxt
+import galaxyxml.tool.parameters as gxtp
+
+tool = gxt.Tool("aragorn", 'se.lu.mbioekol.mbio-serv2.aragorn',
+    "1.2.36", "Aragorn is a tRNA finder", "aragorn.exe")
+
+inputs = gxtp.Inputs()
+outputs = gxtp.Outputs()
+
+# A parameter
+param = gxtp.BooleanParam('flag', label='Flag label', help='Flag help', num_dashes=1)
+# Yes I know this is rubbish. Please make a PR!!
+param.space_between_arg = ' '
+inputs.append(param)
+
+
+# A float
+param = gxtp.FloatParam('float', label='Float label',
+                        help='Float help', value=0, num_dashes=1)
+param.space_between_arg = ' '
+inputs.append(param)
+
+
+param_min = gxtp.IntegerParam('int_min',
+                              label='int_min label',
+                              help='int_min help', value=0, num_dashes=1)
+param_max = gxtp.IntegerParam('int_max',
+                              label='int_max label',
+                              help='int_max help', value=0, num_dashes=1)
+param_min.command_line_override = '-i$int_min,$int_max'
+param_max.command_line_override = ''
+param_min.space_between_arg = ' '
+param_max.space_between_arg = ' '
+inputs.append(param_min)
+inputs.append(param_max)
+
+
+# Outputs
+param = gxtp.OutputParameter('output', format="tabular", num_dashes=1)
+param.space_between_arg = ' '
+outputs.append(param)
+
+tool.inputs = inputs
+tool.outputs = outputs
+tool.help = 'HI'
+
+data = tool.export()
+
+with open('tool.xml', 'w') as handle:
+    handle.write(data)
diff --git a/examples/tool.xml b/examples/tool.xml
new file mode 100644
index 0000000..a7c64a8
--- /dev/null
+++ b/examples/tool.xml
@@ -0,0 +1,20 @@
+<tool force_history_refresh="false" hidden="false" id="se.lu.mbioekol.mbio-serv2.aragorn" name="aragorn" version="1.2.36" workflow_compatible="true">
+  <description>Aragorn is a tRNA finder</description>
+  <stdio>
+    <exit_code level="fatal" range="1:"/>
+  </stdio>
+  <command><![CDATA[aragorn.exe $flag
+-float $float
+-i$int_min,$int_max
+-output $output]]></command>
+  <inputs>
+    <param checked="false" help="(-flag) Flag help" label="Flag label" name="flag" type="boolean" truevalue="-flag"/>
+    <param help="(-float) Float help" label="Float label" name="float" type="float" value="0"/>
+    <param help="(-int_min) int_min help" label="int_min label" name="int_min" type="integer" value="0"/>
+    <param help="(-int_max) int_max help" label="int_max label" name="int_max" type="integer" value="0"/>
+  </inputs>
+  <outputs>
+    <data format="tabular" hidden="false" name="output"/>
+  </outputs>
+  <help><![CDATA[HI]]></help>
+</tool>
diff --git a/galaxyxml/__init__.py b/galaxyxml/__init__.py
new file mode 100644
index 0000000..0d2e959
--- /dev/null
+++ b/galaxyxml/__init__.py
@@ -0,0 +1,47 @@
+from lxml import etree
+
+class GalaxyXML(object):
+
+    def __init__(self):
+        self.root = etree.Element('root')
+
+    def export(self):
+        return etree.tostring(self.root, pretty_print=True)
+
+
+class Util(object):
+
+    @classmethod
+    def coerce(cls, data):
+        """Recursive data sanitisation
+        """
+        if isinstance(data, dict):
+            return {k: cls.coerce(v) for k, v in data.items() if v is not None}
+        elif isinstance(data, list):
+            return [cls.coerce(v) for v in data]
+        else:
+            return cls.coerce_value(data)
+
+    @classmethod
+    def coerce_value(cls, obj):
+        """Make everything a string!
+        """
+        if isinstance(obj, bool):
+            if obj:
+                return "true"
+            else:
+                return "false"
+        elif isinstance(obj, str):
+            return obj
+        else:
+            return str(obj)
+
+    @classmethod
+    def clean_kwargs(cls, params):
+        if 'kwargs' in params:
+            kwargs = params['kwargs']
+            for k in kwargs:
+                params[k] = kwargs[k]
+            del params['kwargs']
+        del params['self']
+        return params
diff --git a/galaxyxml/tool/__init__.py b/galaxyxml/tool/__init__.py
new file mode 100644
index 0000000..6e077df
--- /dev/null
+++ b/galaxyxml/tool/__init__.py
@@ -0,0 +1,103 @@
+from lxml import etree
+from galaxyxml import Util, GalaxyXML
+from galaxyxml.tool.parameters import XMLParam
+
+VALID_TOOL_TYPES = ('data_source', 'data_source_async')
+VALID_URL_METHODS = ('get', 'post')
+
+
+class Tool(GalaxyXML):
+
+    def __init__(self, name, id, version, description, executable, hidden=False,
+                 tool_type=None, URL_method=None, workflow_compatible=True,
+                 force_history_refresh=False, interpreter=None):
+
+        self.executable = executable
+        self.interpreter = interpreter
+        kwargs = {
+            'name': name,
+            'id': id,
+            'version': version,
+            'hidden': hidden,
+            'workflow_compatible': workflow_compatible,
+            'force_history_refresh': force_history_refresh,
+        }
+        kwargs = Util.coerce(kwargs)
+        self.root = etree.Element('tool', **kwargs)
+
+        if tool_type is not None:
+            if tool_type not in VALID_TOOL_TYPES:
+                raise Exception("Tool type must be one of %s" % ','.join(VALID_TOOL_TYPES))
+            else:
+                kwargs['tool_type'] = tool_type
+
+                if URL_method is not None:
+                    if URL_method in VALID_URL_METHODS:
+                        kwargs['URL_method'] = URL_method
+                    else:
+                        raise Exception("URL_method must be one of %s" %
+                                        ','.join(VALID_URL_METHODS))
+
+        description_node = etree.SubElement(self.root, 'description')
+        description_node.text = description
+
+    def version_command(self, command_string):
+        version_command = etree.SubElement(self.root, 'version_command')
+        version_command.text = version_command
+
+    def append(self, sub_node):
+        if issubclass(type(sub_node), XMLParam):
+            self.root.append(sub_node.node)
+        else:
+            self.root.append(sub_node)
+
+    def clean_command_string(self, command_line):
+        clean = []
+        for x in command_line:
+            if x is not [] and x is not ['']:
+                clean.append(x)
+
+        return '\n'.join(clean)
+
+    def export(self):
+        command_line = []
+        try:
+            command_line.append(self.inputs.cli())
+        except Exception, e:
+            print e
+
+        try:
+            command_line.append(self.outputs.cli())
+        except:
+            pass
+
+        # Add stdio section
+        stdio = etree.SubElement(self.root, 'stdio')
+        etree.SubElement(stdio, 'exit_code', range='1:', level='fatal')
+
+        # Steal interpreter from kwargs
+        command_kwargs = {}
+        if self.interpreter is not None:
+            command_kwargs['interpreter'] = self.interpreter
+
+        # Add command section
+        command_node = etree.SubElement(self.root, 'command', **command_kwargs)
+
+        actual_cli = "%s %s" % (self.executable, self.clean_command_string(command_line))
+        command_node.text = etree.CDATA(actual_cli.strip())
+
+
+        try:
+            self.append(self.inputs)
+        except:
+            pass
+
+        try:
+            self.append(self.outputs)
+        except:
+            pass
+
+        help_element = etree.SubElement(self.root, 'help')
+        help_element.text = etree.CDATA(self.help)
+
+        return super(Tool, self).export()
diff --git a/galaxyxml/tool/parameters/__init__.py b/galaxyxml/tool/parameters/__init__.py
new file mode 100644
index 0000000..1703adb
--- /dev/null
+++ b/galaxyxml/tool/parameters/__init__.py
@@ -0,0 +1,400 @@
+from lxml import etree
+from galaxyxml import Util
+
+class XMLParam(object):
+    name = 'node'
+
+    def __init__(self, *args, **kwargs):
+        # http://stackoverflow.com/a/12118700
+        self.children = []
+        kwargs = {k: v for k, v in kwargs.items() if v is not None}
+        kwargs = Util.coerce(kwargs)
+        self.node = etree.Element(self.name, **kwargs)
+
+    def append(self, sub_node):
+        if self.acceptable_child(sub_node):
+            # If one of ours, they aren't etree nodes, they're custom objects
+            if issubclass(type(sub_node), XMLParam):
+                self.node.append(sub_node.node)
+                self.children.append(sub_node)
+            else:
+                raise Exception("Child was unacceptable to parent (%s is not appropriate for %s)" % (type(self), type(sub_node)))
+        else:
+            raise Exception("Child was unacceptable to parent (%s is not appropriate for %s)" % (type(self), type(sub_node)))
+
+    def validate(self):
+        # Very few need validation, but some nodes we may want to have
+        # validation routines on. Should only be called when DONE.
+        for child in self.children:
+            # If any child fails to validate return false.
+            if not child.validate():
+                return False
+        return True
+
+    def cli(self):
+        lines = []
+        for child in self.children:
+            lines.append(child.command_line())
+            #lines += child.command_line()
+        return '\n'.join(lines)
+
+    def command_line(self):
+        return None
+
+
+class RequestParamTranslation(XMLParam):
+    name = 'request_param_translation'
+
+    def __init__(self, **kwargs):
+        self.node = etree.Element(self.name)
+
+    def acceptable_child(self, child):
+        return isinstance(child, RequestParamTranslation)
+
+
+class RequestParam(XMLParam):
+    name = 'request_param'
+
+    def __init__(self, galaxy_name, remote_name, missing, **kwargs):
+        #TODO: bulk copy locals into self.attr?
+        self.galaxy_name = galaxy_name
+        # http://stackoverflow.com/a/1408860
+        params = Util.clean_kwargs(locals().copy())
+        super(RequestParam, self).__init__(**params)
+
+    def acceptable_child(self, child):
+        return isinstance(child, AppendParam) and self.galaxy_name == "URL"
+
+
+class AppendParam(XMLParam):
+    name = 'append_param'
+
+    def __init__(self, separator="&", first_separator="?", join="=", **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        super(AppendParam, self).__init__(**params)
+
+    def acceptable_child(self, child):
+        return isinstance(child, AppendParamValue)
+
+
+class AppendParamValue(XMLParam):
+    name = 'value'
+
+    def __init__(self, name="_export", missing="1", **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        super(AppendParamValue, self).__init__(**params)
+
+    def acceptable_child(self, child):
+        return False
+
+
+class Inputs(XMLParam):
+    name = 'inputs'
+    # This bodes to be an issue -__-
+
+    def acceptable_child(self, child):
+        return issubclass(type(child), InputParameter)
+
+
+class InputParameter(XMLParam):
+
+    def __init__(self, name, **kwargs):
+        # TODO: look at
+        self.mako_identifier = name
+        # We use kwargs instead of the usual locals(), so manually copy the
+        # name to kwargs
+        kwargs['name'] = name
+
+        # Handle positional parameters
+        if 'positional' in kwargs and kwargs['positional']:
+            self.positional = True
+        else:
+            self.positional = False
+
+        if 'num_dashes' in kwargs:
+            self.num_dashes = kwargs['num_dashes']
+            del kwargs['num_dashes']
+        else:
+            self.num_dashes = 0
+
+        self.space_between_arg = " "
+
+        # Not sure about this :(
+        # https://wiki.galaxyproject.org/Tools/BestPractices#Parameter_help
+        if 'label' in kwargs:
+            # TODO: replace with positional attribute
+            if len(self.flag()) > 0:
+                if kwargs['label'] is None:
+                    kwargs['label'] = 'Author did not provide help for this parameter... '
+                if not self.positional:
+                    kwargs['label'] += ' (%s)' % self.flag()
+
+        super(InputParameter, self).__init__(**kwargs)
+
+    def command_line(self):
+        before = self.command_line_before()
+        cli = self.command_line_actual()
+        after = self.command_line_after()
+
+        complete = [x for x in (before, cli, after) if x is not None]
+        return '\n'.join(complete)
+
+    def command_line_before(self):
+        return None
+
+    def command_line_after(self):
+        return None
+
+    def command_line_actual(self):
+        if hasattr(self, 'command_line_override'):
+            return self.command_line_override
+        else:
+            if self.positional:
+                return self.mako_name()
+            else:
+                return "%s%s%s" % (self.flag(), self.space_between_arg, self.mako_name())
+
+    def mako_name(self):
+        # TODO: enhance logic to check up parents for things like repeat>condotion>param
+        return '$' + self.mako_identifier
+
+    def flag(self):
+        flag = '-' * self.num_dashes
+        return flag + self.mako_identifier
+
+
+class Repeat(InputParameter):
+    name = 'repeat'
+
+    def __init__(self, name, title, min=None, max=None, default=None,
+            **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        # Allow overriding
+        self.cli_before = '#for $i in $%s' % name
+        self.cli_after  = '#end for'
+        super(Repeat, self).__init__(**params)
+
+    def acceptable_child(self, child):
+        return issubclass(type(child), InputParameter)
+
+    def command_line_before(self):
+        return self.cli_before
+
+    def command_line_after(self):
+        return self.cli_after
+
+    def command_line_actual(self):
+        if hasattr(self, 'command_line_override'):
+            return self.command_line_override
+        else:
+            return "%s" % self.mako_name()
+
+class Conditional(InputParameter):
+    name = 'conditional'
+
+    def __init__(self, name, **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        super(Conditional, self).__init__(**params)
+
+    def acceptable_child(self, child):
+        return issubclass(type(child), InputParameter) \
+            and not isinstance(child, Conditional)
+
+    def validate(self):
+        # Find a way to check if one of the kids is a WHEN
+        pass
+
+
+class Param(InputParameter):
+    name = 'param'
+
+    # This...isn't really valid as-is, and shouldn't be used.
+    def __init__(self, name, optional=None, label=None, help=None, **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        params['type'] = self.type
+        super(Param, self).__init__(**params)
+
+        if type(self) == Param:
+            raise Exception("Param class is not an actual parameter type, use a subclass of Param")
+
+    def acceptable_child(self, child):
+        return issubclass(type(child, InputParameter) or isinstance(child), ValidatorParam)
+
+
+class TextParam(Param):
+    type = 'text'
+
+    def __init__(self, name, optional=None, label=None, help=None, size=None,
+            area=False, **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        super(TextParam, self).__init__(**params)
+
+
+class _NumericParam(Param):
+
+    def __init__(self, name, value, optional=None, label=None, help=None,
+            min=None, max=None, **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        super(_NumericParam, self).__init__(**params)
+
+
+class IntegerParam(_NumericParam):
+    type = 'integer'
+
+
+class FloatParam(_NumericParam):
+    type = 'float'
+
+
+class BooleanParam(Param):
+    type = 'boolean'
+
+    def __init__(self, name, optional=None, label=None, help=None,
+                 checked=False, truevalue=None, falsevalue=None, **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+
+        super(BooleanParam, self).__init__(**params)
+        if truevalue is None and falsevalue is None:
+            # If truevalue and falsevalue are None, then we use "auto", the IUC
+            # recommended default.
+            #
+            # truevalue is set to the parameter's value, and falsevalue is not.
+            #
+            # Unfortunately, mako_identifier is set as a result of the super
+            # call, which we shouldn't call TWICE, so we'll just hack around this :(
+            #params['truevalue'] = '%s%s' % (self.)
+            self.node.attrib['truevalue'] = self.flag()
+
+
+    def command_line_actual(self):
+        if hasattr(self, 'command_line_override'):
+            return self.command_line_override
+        else:
+            return "%s" % self.mako_name()
+
+
+class DataParam(Param):
+    type = 'data'
+
+    def __init__(self, name, optional=None, label=None, help=None, format=None,
+                 multiple=None, **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        super(DataParam, self).__init__(**params)
+
+
+class SelectParam(Param):
+    type = 'data'
+
+    def __init__(self, name, optional=None, label=None, help=None,
+            data_ref=None, display=None, multiple=None, options=None,
+            default=None, **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        del params['options']
+        del params['default']
+
+        super(DataParam, self).__init__(**params)
+
+        if options is not None and default is not None:
+            if default  not in options:
+                raise Exception("Specified a default that isn't in options")
+
+        for k,v  in options:
+            selected = (k == default)
+            self.append(SelectOption(k, v, selected=selected))
+
+
+class SelectOption(InputParameter):
+    name = 'option'
+
+    def __init__(self, value, text, selected=False, **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        del params['text']
+        super(SelectOption, self).__init__(**params)
+        self.node.text = text
+
+
+class ValidatorParam(InputParameter):
+    name = 'validator'
+
+    def __init__(self, type, message=None, filename=None, metadata_name=None,
+                 metadata_column=None, line_startswith=None, min=None,
+                 max=None, **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        super(ValidatorParam, self).__init__(**params)
+
+
+class Outputs(XMLParam):
+    name = 'outputs'
+
+    def acceptable_child(self, child):
+        return issubclass(type(child), OutputParameter)
+
+
+class OutputParameter(XMLParam):
+    """Copypasta of InputParameter, needs work
+    """
+    name = 'data'
+
+    def __init__(self, name, format, format_source=None, metadata_source=None,
+                 label=None, from_work_dir=None, hidden=False, **kwargs):
+        # TODO: validate format_source&metadata_source against something in the
+        # XMLParam children tree.
+        self.mako_identifier = name
+        if 'num_dashes' in kwargs:
+            self.num_dashes = kwargs['num_dashes']
+            del kwargs['num_dashes']
+        else:
+            self.num_dashes = 0
+        self.space_between_arg = " "
+        params = Util.clean_kwargs(locals().copy())
+
+        super(OutputParameter, self).__init__(**params)
+
+    def command_line(self):
+        if hasattr(self, 'command_line_override'):
+            return self.command_line_override
+        else:
+            return "%s%s%s" % (self.flag(), self.space_between_arg, self.mako_name())
+
+    def mako_name(self):
+        return '$' + self.mako_identifier
+
+    def flag(self):
+        flag = '-' * self.num_dashes
+        return flag + self.mako_identifier
+
+    def acceptable_child(self, child):
+        return isinstance(child, OutputFilter) or isinstance(child, ChangeFormat)
+
+class OutputFilter(XMLParam):
+    name = 'filter'
+
+    def __init__(self, text, **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        del params['text']
+        super(OutputFilter, self).__init__(**params)
+        self.node.text = text
+
+    def acceptable_child(self, child):
+        return False
+
+class ChangeFormat(XMLParam):
+    name = 'change_format'
+
+    def __init__(self, **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        super(ChangeFormat, self).__init__(**params)
+
+    def acceptable_child(self, child):
+        return isinstance(child, ChangeFormatWhen)
+
+
+class ChangeFormatWhen(XMLParam):
+    name = 'when'
+
+    def __init__(self, input, format, value, **kwargs):
+        params = Util.clean_kwargs(locals().copy())
+        super(ChangeFormatWhen, self).__init__(**params)
+
+    def acceptable_child(self, child):
+        return False
diff --git a/parser.py b/parser.py
new file mode 100644
index 0000000..e822ef6
--- /dev/null
+++ b/parser.py
@@ -0,0 +1,119 @@
+import re
+
+def start_pattern(string):
+    return string.startswith('    -')
+
+
+CLI = {
+    'OUTPUT': (re.compile(r'^\s*(?P<dash>--?)(?P<name>[A-Za-z0-9]+)(?P<space_between_arg>[ ]*)<(?P<args>out[^>]*)>\s+(?P<content>.*)'), {'nargs': 1}),
+    'FLAG': (re.compile(r'^\s*(?P<dash>--?)(?P<name>[A-Za-z0-9]+)[ ]{2,}(?P<content>.*)'), {'nargs': 0}),
+    'PARAM': (re.compile(r'^\s*(?P<dash>--?)(?P<name>[A-Za-z0-9]+)(?P<space_between_arg>[ ]*)<(?P<args>[^>]*)>\s+(?P<content>.*)'), {'nargs': 1}),
+    'PARAM_RANGE': (re.compile(r'^\s*(?P<dash>--?)(?P<name>[A-Za-z0-9]+)(?P<space_between_arg>[ ]*)<(?P<args>[^>]*)>,<(?P<args2>[^>]*)>\s+(?P<content>.*)'), {'nargs': 2}),
+}
+
+CLI_GROUPS = ('name', 'args', 'content', 'args2', 'dash', 'space_between_arg')
+CLI_DEFAULTS = {
+    'space_between_arg': ' '
+}
+
+def detect_args(cli):
+    for matcher in CLI:
+        matches = CLI[matcher][0].search(cli)
+        if matches:
+            hit = CLI[matcher][1]
+            hit['type'] = matcher
+
+            # Apply defaults. Poorly organised.
+            for default in CLI_DEFAULTS:
+                hit[default] = CLI_DEFAULTS[default]
+
+            # Actual groups in regex
+            for group in CLI_GROUPS:
+                try:
+                    hit[group] = matches.group(group)
+                except IndexError:
+                    # Ignore missing groups
+                    pass
+            return hit
+    return None
+
+def reflow_block(block):
+    single = ' '.join([x.strip() for x in block])
+    return detect_args(single)
+
+def blocks(iterable):
+    accumulator = []
+    for line in iterable:
+        if start_pattern(line):
+            if accumulator:
+                yield reflow_block(accumulator)
+                accumulator = [line]
+        else:
+            accumulator.append(line)
+    if accumulator:
+        yield reflow_block(accumulator)
+
+import galaxyxml.tool as gxt
+import galaxyxml.tool.parameters as gxtp
+
+tool = gxt.Tool(name="aragorn", version="1.2.36", description="tRNA finder",
+                executable="aragorn")
+inputs = gxtp.Inputs()
+outputs = gxtp.Outputs()
+for line in blocks(open('tmp','r').readlines()):
+    if line and line['type'] == 'FLAG':
+        param = gxtp.BooleanParam(line['name'], label=line['name'], help=line['content'],
+                                 #truevalue=cli_param, falsevalue="")
+                                  )
+        param.num_dashes = len(line['dash'])
+        param.space_between_arg = line['space_between_arg']
+        inputs.append(param)
+    elif line and line['type'] == 'PARAM':
+        print "%(dash)s%(name)s <%(args)s> %(content)s" % line
+        answer = raw_input("Is this a FLOAT, INT, or TEXT input? ")
+        if 'FLOAT' in answer:
+            param = gxtp.FloatParam(line['name'], label=line['name'],
+                                    help=line['content'], value=0)
+        elif 'INT' in answer:
+            param = gxtp.IntegerParam(line['name'], label=line['name'],
+                                      help=line['content'], value=0)
+        elif 'TEXT' in answer:
+            param = gxtp.TextParam(line['name'], label=line['name'],
+                                   help=line['content'])
+        try:
+            param.num_dashes = len(line['dash'])
+            param.space_between_arg = line['space_between_arg']
+            inputs.append(param)
+        except:
+            print "Uhoh, bad answer"
+        print
+    elif line and line['type'] == 'PARAM_RANGE':
+        param_min = gxtp.IntegerParam(line['name']+'_min',
+                                      label=line['name']+'_min',
+                                      help=line['content'], value=0)
+        param_max = gxtp.IntegerParam(line['name']+'_max',
+                                      label=line['name']+'_max',
+                                      help=line['content'], value=0)
+        param_min.command_line_override = '-i$i_min,$i_max'
+        param_max.command_line_override = ''
+        param_min.num_dashes = len(line['dash'])
+        param_max.num_dashes = len(line['dash'])
+        param_min.space_between_arg = line['space_between_arg']
+        param_max.space_between_arg = line['space_between_arg']
+        inputs.append(param_min)
+        inputs.append(param_max)
+    elif line and line['type'] == 'OUTPUT':
+        param = gxtp.OutputParameter(line['name'], format="tabular")
+        param.num_dashes = len(line['dash'])
+        param.space_between_arg = line['space_between_arg']
+        outputs.append(param)
+
+tool.inputs = inputs
+tool.outputs = outputs
+tool.help = 'HI'
+
+
+data = tool.export()
+
+with open('tool.xml', 'w') as handle:
+    handle.write(data)
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..ab90481
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+lxml
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..90a9146
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,19 @@
+from setuptools import setup
+
+requirements = [x.strip() for x in open('requirements.txt', 'r').readlines()]
+
+setup(name="galaxyxml",
+        version='0.1',
+        description='Galaxy XML generation library',
+        author='Eric Rasche',
+        author_email='rasche.eric at yandex.ru',
+        license='GPL3',
+        install_requires=requirements,
+        packages=["galaxyxml", "galaxyxml.tool", "galaxyxml.tool.parameters"],
+        classifiers=[
+            'Development Status :: 3 - Alpha',
+            'Operating System :: OS Independent',
+            'Intended Audience :: Developers',
+            'Environment :: Console',
+            ],
+        )

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/python-galaxyxml.git



More information about the debian-med-commit mailing list