mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
This comes in two modes - simple lists of required attributes and per-attribute parameters that may specify defaults.
The following toy example:
```
<tool>
<expand macro="inputs" bar="hello" />
<macros>
<xml name="inputs" dollar_tokens="bar">
<inputs type="the type is $BAR$" />
</xml>
</macros>
</tool>
```
will evalute to ``<tool><inputs type="the type is hello" /><tool>``. The XML macro definition tag can now take in two new fixed attributes dollar_tokens and at_tokens - which will be interpreted as a list of parameter names. Each parameter can be specified when expanding the macros as simple attributes specifying the value of the parameter. The "dollar" parameter with name bar would map to a token with name $BAR$. Likewise an "at" parameter with name foo would map to a token with name @FOO@.
Both parameter types can be specified on a per-parameter basis to also specify default values. So the following example:
```
<tool>
<expand macro="inputs" foo="hello" />
<expand macro="inputs" foo="world" />
<expand macro="inputs" />
<macros>
<xml name="inputs" at_token_foo="the_default">
<inputs>@FOO@</inputs>
</xml>
</macros>
</tool>
```
Would evalute to ``<tool><inputs>hello</inputs><inputs>world</inputs><inputs>the_default</inputs>``.
Updated unit tests explain the above much more succinctly - though some like English and words for reasons that escape me.
230 lines
6.0 KiB
Python
230 lines
6.0 KiB
Python
from tempfile import mkdtemp
|
|
from shutil import rmtree
|
|
import os
|
|
|
|
from galaxy.util import parse_xml
|
|
from galaxy.tools.loader import template_macro_params, load_tool
|
|
|
|
def test_loader():
|
|
|
|
class TestToolDirectory(object):
|
|
def __init__(self):
|
|
self.temp_directory = mkdtemp()
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, type, value, tb):
|
|
rmtree(self.temp_directory)
|
|
|
|
def write(self, contents, name="tool.xml"):
|
|
open(os.path.join(self.temp_directory, name), "w").write(contents)
|
|
|
|
def load(self, name="tool.xml", preprocess=True):
|
|
if preprocess:
|
|
loader = load_tool
|
|
else:
|
|
loader = parse_xml
|
|
return loader(os.path.join(self.temp_directory, name))
|
|
|
|
## Test simple macro replacement.
|
|
with TestToolDirectory() as tool_dir:
|
|
tool_dir.write('''
|
|
<tool>
|
|
<expand macro="inputs" />
|
|
<macros>
|
|
<macro name="inputs">
|
|
<inputs />
|
|
</macro>
|
|
</macros>
|
|
</tool>''')
|
|
xml = tool_dir.load(preprocess=False)
|
|
assert xml.find("inputs") is None
|
|
xml = tool_dir.load(preprocess=True)
|
|
assert xml.find("inputs") is not None
|
|
|
|
# Test importing macros from external files
|
|
with TestToolDirectory() as tool_dir:
|
|
tool_dir.write('''
|
|
<tool>
|
|
<expand macro="inputs" />
|
|
<macros>
|
|
<import>external.xml</import>
|
|
</macros>
|
|
</tool>''')
|
|
|
|
tool_dir.write('''
|
|
<macros>
|
|
<macro name="inputs">
|
|
<inputs />
|
|
</macro>
|
|
</macros>''', name="external.xml")
|
|
xml = tool_dir.load(preprocess=False)
|
|
assert xml.find("inputs") is None
|
|
xml = tool_dir.load(preprocess=True)
|
|
assert xml.find("inputs") is not None
|
|
|
|
# Test macros with unnamed yield statements.
|
|
with TestToolDirectory() as tool_dir:
|
|
tool_dir.write('''
|
|
<tool>
|
|
<expand macro="inputs">
|
|
<input name="first_input" />
|
|
</expand>
|
|
<macros>
|
|
<macro name="inputs">
|
|
<inputs>
|
|
<yield />
|
|
</inputs>
|
|
</macro>
|
|
</macros>
|
|
</tool>''')
|
|
xml = tool_dir.load()
|
|
assert xml.find("inputs").find("input").get("name") == "first_input"
|
|
|
|
# Test recursive macro applications.
|
|
with TestToolDirectory() as tool_dir:
|
|
tool_dir.write('''
|
|
<tool>
|
|
<expand macro="inputs">
|
|
<input name="first_input" />
|
|
<expand macro="second" />
|
|
</expand>
|
|
<macros>
|
|
<macro name="inputs">
|
|
<inputs>
|
|
<yield />
|
|
</inputs>
|
|
</macro>
|
|
<macro name="second">
|
|
<input name="second_input" />
|
|
</macro>
|
|
</macros>
|
|
</tool>''')
|
|
xml = tool_dir.load()
|
|
assert xml.find("inputs").findall("input")[1].get("name") == "second_input"
|
|
|
|
# Test recursive macro applications.
|
|
with TestToolDirectory() as tool_dir:
|
|
tool_dir.write('''
|
|
<tool>
|
|
<expand macro="inputs">
|
|
<input name="first_input" />
|
|
<expand macro="second" />
|
|
</expand>
|
|
<macros>
|
|
<macro name="inputs">
|
|
<inputs>
|
|
<yield />
|
|
</inputs>
|
|
</macro>
|
|
<macro name="second">
|
|
<expand macro="second_delegate" />
|
|
</macro>
|
|
<macro name="second_delegate">
|
|
<input name="second_input" />
|
|
</macro>
|
|
</macros>
|
|
</tool>''')
|
|
xml = tool_dir.load()
|
|
assert xml.find("inputs").findall("input")[1].get("name") == "second_input"
|
|
|
|
# Test <xml> is shortcut for macro type="xml"
|
|
with TestToolDirectory() as tool_dir:
|
|
tool_dir.write('''
|
|
<tool>
|
|
<expand macro="inputs" />
|
|
<macros>
|
|
<xml name="inputs">
|
|
<inputs />
|
|
</xml>
|
|
</macros>
|
|
</tool>''')
|
|
xml = tool_dir.load()
|
|
assert xml.find("inputs") is not None
|
|
|
|
with TestToolDirectory() as tool_dir:
|
|
tool_dir.write('''
|
|
<tool>
|
|
<command interpreter="python">tool_wrapper.py
|
|
#include source=$tool_params
|
|
</command>
|
|
<macros>
|
|
<template name="tool_params">-a 1 -b 2</template>
|
|
</macros>
|
|
</tool>
|
|
''')
|
|
xml = tool_dir.load()
|
|
params_dict = template_macro_params(xml.getroot())
|
|
assert params_dict['tool_params'] == "-a 1 -b 2"
|
|
|
|
with TestToolDirectory() as tool_dir:
|
|
tool_dir.write('''
|
|
<tool>
|
|
<macros>
|
|
<token name="@CITATION@">The citation.</token>
|
|
</macros>
|
|
<help>@CITATION@</help>
|
|
<another>
|
|
<tag />
|
|
</another>
|
|
</tool>
|
|
''')
|
|
xml = tool_dir.load()
|
|
help_el = xml.find("help")
|
|
assert help_el.text == "The citation.", help_el.text
|
|
|
|
with TestToolDirectory() as tool_dir:
|
|
tool_dir.write('''
|
|
<tool>
|
|
<macros>
|
|
<token name="@TAG_VAL@">The value.</token>
|
|
</macros>
|
|
<another>
|
|
<tag value="@TAG_VAL@" />
|
|
</another>
|
|
</tool>
|
|
''')
|
|
xml = tool_dir.load()
|
|
tag_el = xml.find("another").find("tag")
|
|
value = tag_el.get('value')
|
|
assert value == "The value.", value
|
|
|
|
# Test macros XML macros with $ expansions in attributes
|
|
with TestToolDirectory() as tool_dir:
|
|
tool_dir.write('''
|
|
<tool>
|
|
<expand macro="inputs" bar="hello" />
|
|
<macros>
|
|
<xml name="inputs" dollar_tokens="bar">
|
|
<inputs type="the type is $BAR$" />
|
|
</xml>
|
|
</macros>
|
|
</tool>
|
|
''')
|
|
xml = tool_dir.load()
|
|
input_els = xml.findall("inputs")
|
|
assert len(input_els) == 1
|
|
assert input_els[0].attrib["type"] == "the type is hello"
|
|
|
|
# Test macros XML macros with @ expansions in text
|
|
with TestToolDirectory() as tool_dir:
|
|
tool_dir.write('''
|
|
<tool>
|
|
<expand macro="inputs" foo="hello" />
|
|
<expand macro="inputs" foo="world" />
|
|
<expand macro="inputs" />
|
|
<macros>
|
|
<xml name="inputs" at_token_foo="the_default">
|
|
<inputs>@FOO@</inputs>
|
|
</xml>
|
|
</macros>
|
|
</tool>
|
|
''')
|
|
xml = tool_dir.load()
|
|
input_els = xml.findall("inputs")
|
|
assert len(input_els) == 3
|
|
assert input_els[0].text == "hello"
|
|
assert input_els[1].text == "world"
|
|
assert input_els[2].text == "the_default"
|