This is an automated email from the git hooks/post-receive script. tille pushed a commit to branch master in repository python-galaxyxml.
commit 78588606c0fa7eceb1d8c16d9b6dc5680e5fe1d5 Author: Anton Khodak <[email protected]> Date: Sat Jan 14 16:10:30 2017 +0200 Change repo structure --- 0.1.tar.gz | Bin 7225 -> 0 bytes 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 ---------- python-galaxyxml_0.1.orig.tar.gz | 1 - requirements.txt | 1 - setup.py | 19 -- 11 files changed, 781 deletions(-) diff --git a/0.1.tar.gz b/0.1.tar.gz deleted file mode 100644 index 9e4d8f5..0000000 Binary files a/0.1.tar.gz and /dev/null differ diff --git a/README.md b/README.md deleted file mode 100644 index 32dcbe7..0000000 --- a/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# 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 deleted file mode 100644 index c97d48a..0000000 --- a/examples/example.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/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 deleted file mode 100644 index a7c64a8..0000000 --- a/examples/tool.xml +++ /dev/null @@ -1,20 +0,0 @@ -<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 deleted file mode 100644 index 0d2e959..0000000 --- a/galaxyxml/__init__.py +++ /dev/null @@ -1,47 +0,0 @@ -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 deleted file mode 100644 index 6e077df..0000000 --- a/galaxyxml/tool/__init__.py +++ /dev/null @@ -1,103 +0,0 @@ -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 deleted file mode 100644 index 1703adb..0000000 --- a/galaxyxml/tool/parameters/__init__.py +++ /dev/null @@ -1,400 +0,0 @@ -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 deleted file mode 100644 index e822ef6..0000000 --- a/parser.py +++ /dev/null @@ -1,119 +0,0 @@ -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/python-galaxyxml_0.1.orig.tar.gz b/python-galaxyxml_0.1.orig.tar.gz deleted file mode 120000 index 1fafd7d..0000000 --- a/python-galaxyxml_0.1.orig.tar.gz +++ /dev/null @@ -1 +0,0 @@ -0.1.tar.gz \ No newline at end of file diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index ab90481..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -lxml diff --git a/setup.py b/setup.py deleted file mode 100644 index 90a9146..0000000 --- a/setup.py +++ /dev/null @@ -1,19 +0,0 @@ -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='[email protected]', - 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 _______________________________________________ debian-med-commit mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit
