Skip to content

Commit ec6e30f

Browse files
committed
Add --macros flag to tool_init command.
Will pull citations, requirements, stdio, and version_command out into an imported macros file. Subsequent suite definitions in the same directory generated with --macros will reuse the same file. Fixes to lint and extensions to testing to enable this.
1 parent ab06ff6 commit ec6e30f

File tree

5 files changed

+91
-21
lines changed

5 files changed

+91
-21
lines changed

planemo/commands/cmd_lint.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def cli(ctx, path, report_level="all", fail_level="warn"):
3434
exit = 0
3535
lint_args = dict(level=report_level, fail_level=fail_level)
3636
tools = load_tool_elements_from_path(path, load_exception_handler)
37+
valid_tools = 0
3738
for (tool_path, tool_xml) in tools:
3839
if tool_xml.getroot().tag != "tool":
3940
if ctx.verbose:
@@ -42,6 +43,10 @@ def cli(ctx, path, report_level="all", fail_level="warn"):
4243
info("Linting tool %s" % tool_path)
4344
if not lint_xml(tool_xml, **lint_args):
4445
exit = 1
46+
else:
47+
valid_tools += 1
48+
if exit == 0 and valid_tools == 0:
49+
exit = 2
4550
sys.exit(exit)
4651

4752

planemo/commands/cmd_tool_init.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
from planemo import io
55
from planemo import tool_builder
66

7+
REUSING_MACROS_MESSAGE = ("Macros file macros.xml already exists, assuming "
8+
" it has relevant planemo-generated definitions.")
9+
710

811
# --input_format
912
# --output_format
@@ -169,6 +172,13 @@
169172
help=("For use with --example_commmand, generate a tool test case from "
170173
"the supplied example."),
171174
)
175+
@click.option(
176+
"--macros",
177+
is_flag=True,
178+
default=None,
179+
prompt=False,
180+
help="Generate a macros.xml for reuse across many tools.",
181+
)
172182
@click.command("tool_init")
173183
@pass_context
174184
def cli(ctx, **kwds):
@@ -186,6 +196,12 @@ def cli(ctx, **kwds):
186196
tool_description = tool_builder.build(**kwds)
187197
open(output, "w").write(tool_description.contents)
188198
io.info("Tool written to %s" % output)
199+
macros = kwds["macros"]
200+
macros_file = "macros.xml"
201+
if macros and not os.path.exists(macros_file):
202+
open(macros_file, "w").write(tool_description.macro_contents)
203+
else:
204+
io.info(REUSING_MACROS_MESSAGE)
189205
if tool_description.test_files:
190206
if not os.path.exists("test-data"):
191207
io.info("No test-data directory, creating one.")

planemo/tool_builder.py

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@
1010
{%- if description %}
1111
<description>{{ description }}</description>
1212
{% endif %}
13+
{%- if macros %}
14+
<macros>
15+
<import>macros.xml</import>
16+
</macros>
17+
<expand macro="requirements" />
18+
<expand macro="stdio" />
19+
{%- if version_command %}
20+
<expand macro="version_command" />
21+
{% endif %}
22+
{%- else %}
1323
<stdio>
1424
<exit_code range="1:" />
1525
</stdio>
@@ -24,6 +34,7 @@
2434
{%- if version_command %}
2535
<version_command>{{ version_command }}</version_command>
2636
{%- endif %}
37+
{% endif %}
2738
<command><![CDATA[
2839
{%- if command %}
2940
{{ command }}
@@ -62,16 +73,53 @@
6273
TODO: Fill in help.
6374
{%- endif %}
6475
]]></help>
76+
{%- if macros %}
77+
<expand macro="citations" />
78+
{%- else %}
6579
{%- if doi %}
6680
<citations>
6781
{%- for single_doi in doi %}
6882
<citation type="doi">{{ single_doi }}</citation>
6983
{%- endfor %}
7084
</citations>
7185
{%- endif %}
86+
{%- endif %}
7287
</tool>
7388
"""
7489

90+
MACROS_TEMPLATE = """<macros>
91+
<xml name="requirements">
92+
<requirements>
93+
{%- for requirement in requirements %}
94+
{{ requirement }}
95+
{%- endfor %}
96+
<yield/>
97+
{%- for container in containers %}
98+
{{ container }}
99+
{%- endfor %}
100+
</requirements>
101+
</xml>
102+
<xml name="stdio">
103+
<stdio>
104+
<exit_code range="1:" />
105+
</stdio>
106+
</xml>
107+
<xml name="citations">
108+
<citations>
109+
{%- for single_doi in doi %}
110+
<citation type="doi">{{ single_doi }}</citation>
111+
{%- endfor %}
112+
<yield />
113+
</citations>
114+
</xml>
115+
{%- if version_command %}
116+
<xml name="version_command">
117+
<version_command>{{ version_command }}</version_command>
118+
</xml>
119+
{%- endif %}
120+
</macros>
121+
"""
122+
75123

76124
def build(**kwds):
77125
if Template is None:
@@ -131,16 +179,20 @@ def build(**kwds):
131179
kwds["tests"] = tests
132180

133181
# Render tool content from template.
134-
contents = _render_tool(kwds)
182+
contents = _render(kwds)
183+
184+
macro_contents = None
185+
if kwds["macros"]:
186+
macro_contents = _render(kwds, MACROS_TEMPLATE)
135187

136-
return ToolDescription(contents, test_files)
188+
return ToolDescription(contents, macro_contents, test_files)
137189

138190

139-
def _render_tool(kwds):
191+
def _render(kwds, template_str=TOOL_TEMPLATE):
140192
""" Apply supplied template variables to TOOL_TEMPLATE to generate
141193
the final tool.
142194
"""
143-
template = Template(TOOL_TEMPLATE)
195+
template = Template(template_str)
144196
contents = template.render(**kwds)
145197
return contents
146198

@@ -227,8 +279,9 @@ def _find_command(kwds):
227279

228280
class ToolDescription(object):
229281

230-
def __init__(self, contents, test_files):
282+
def __init__(self, contents, macro_contents, test_files):
231283
self.contents = contents
284+
self.macro_contents = macro_contents
232285
self.test_files = test_files
233286

234287

tests/test_build_and_lint.py

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,21 @@
1-
1+
import os
22
from .test_utils import CliTestCase
33

44

5-
INIT_COMMAND = [
6-
"tool_init", "--force",
7-
"--id", "seqtk_seq",
8-
"--name", "Convert to FASTA (seqtk)",
9-
"--requirement", "seqtk@1.0-r68",
10-
"--example_command", "seqtk seq -a 2.fastq > 2.fasta",
11-
"--example_input", "2.fastq",
12-
"--example_output", "2.fasta",
13-
"--test_case",
14-
"--help_text", "The help text.",
15-
"--doi", "10.1101/014043"
16-
]
17-
18-
195
class BuildAndLintTestCase(CliTestCase):
206

217
def test_build_and_lint(self):
228
with self._isolate():
239
self._check_exit_code(_init_command())
2410
self._check_lint(exit_code=0)
2511

12+
def test_build_and_lint_with_macros(self):
13+
with self._isolate() as f:
14+
self._check_exit_code(_init_command(macros=True))
15+
self._check_lint(exit_code=0)
16+
macros_file = os.path.join(f, "macros.xml")
17+
assert os.path.exists(macros_file)
18+
2619
def test_lint_fails_if_no_help(self):
2720
with self._isolate():
2821
self._check_exit_code(_init_command(help_text=False))
@@ -43,7 +36,7 @@ def _check_lint(self, exit_code=0):
4336
self._check_exit_code(lint_cmd, exit_code=exit_code)
4437

4538

46-
def _init_command(test_case=True, help_text=True, doi=True):
39+
def _init_command(test_case=True, help_text=True, doi=True, macros=False):
4740
command = [
4841
"tool_init", "--force",
4942
"--id", "seqtk_seq",
@@ -59,4 +52,6 @@ def _init_command(test_case=True, help_text=True, doi=True):
5952
command.extend(["--help_text", "The help text."])
6053
if doi:
6154
command.extend(["--doi", "10.1101/014043"])
55+
if macros:
56+
command.append("--macros")
6257
return command

tests/test_utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def _check_exit_code(self, command_list, exit_code=0):
4343
result.output,
4444
)
4545
raise AssertionError(message)
46+
return result
4647

4748

4849
__all__ = [

0 commit comments

Comments
 (0)