Skip to content

Commit e8c1d45

Browse files
committed
Implement 'normalize' command.
Generates a normalized tool XML from the supplied input file. The top-level blocks will be reordered and whitespace fixed according to the tool development best practices outlined on the Galaxy wiki (see https://wiki.galaxyproject.org/Tools/BestPractices). The --expand_macros flag will additionally cause the tool to be printed out with macros full expanded - useful for debugging macro operations. % # Print normalized version of tool. % planemo normalize tool.xml <tool> ... % # Print a variant of tool with all macros expanded out, useful for % # debugging complex macros. % planemo normalize --expand_macros tool.xml <tool> ...
1 parent b8d90ab commit e8c1d45

File tree

3 files changed

+158
-0
lines changed

3 files changed

+158
-0
lines changed

docs/commands.rst

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ documentation describes these commands.
1414
.. include:: commands/docker_build.rst
1515
.. include:: commands/docker_shell.rst
1616
.. include:: commands/lint.rst
17+
.. include:: commands/normalize.rst
1718
.. include:: commands/project_init.rst
1819
.. include:: commands/serve.rst
1920
.. include:: commands/share_test.rst

docs/commands/normalize.rst

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
2+
``normalize`` command
3+
===============================
4+
5+
This section is auto-generated from the help text for the planemo command
6+
``normalize``. This help message can be generated with ``planemo normalize
7+
--help``.
8+
9+
**Usage**::
10+
11+
planemo normalize [OPTIONS] TOOL_PATH
12+
13+
**Help**
14+
15+
Generate normalized tool XML from input.
16+
17+
The top-level blocks will be reordered and whitespace fixed according to
18+
the tool development best practices outlined on the Galaxy wiki.
19+
20+
See also https://wiki.galaxyproject.org/Tools/BestPractices.
21+
22+
::
23+
24+
% # Print normalized version of tool.
25+
% planemo normalize tool.xml
26+
<tool>
27+
...
28+
% # Print a variant of tool with all macros expanded out, useful for
29+
% # debugging complex macros.
30+
% planemo normalize --expand_macros tool.xml
31+
<tool>
32+
...
33+
34+
**Options**::
35+
36+
37+
--expand_macros Expand macros while normalizing tool XML - useful to see
38+
how macros are evaluated.
39+
--skip_reorder Planemo will reorder top-level tool blocks according to
40+
tool development best practices as part of this command,
41+
this flag will disable that behavior.
42+
--skip_reindent Planemo will reindent the XML according to tool development
43+
best practices as part of this command, this flag will
44+
disable that behavior.
45+
--help Show this message and exit.
46+

planemo/commands/cmd_normalize.py

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
from xml.etree import ElementTree
2+
3+
import click
4+
5+
from planemo.cli import pass_context
6+
from planemo import options
7+
8+
from galaxy.tools.loader import (
9+
load_tool,
10+
raw_tool_xml_tree,
11+
)
12+
13+
14+
TAG_ORDER = [
15+
'description',
16+
'macros',
17+
'requirements',
18+
'code',
19+
'stdio',
20+
'version_command',
21+
'command',
22+
'inputs',
23+
'outputs',
24+
'tests',
25+
'help',
26+
'citations',
27+
]
28+
29+
30+
@click.command('normalize')
31+
@options.required_tool_arg()
32+
@click.option(
33+
"--expand_macros",
34+
is_flag=True,
35+
help=("Expand macros while normalizing tool XML - useful to see how "
36+
"macros are evaluated.")
37+
)
38+
@click.option(
39+
"--skip_reorder",
40+
is_flag=True,
41+
help=("Planemo will reorder top-level tool blocks according to tool "
42+
"development best practices as part of this command, this flag "
43+
"will disable that behavior.")
44+
)
45+
@click.option(
46+
"--skip_reindent",
47+
is_flag=True,
48+
help=("Planemo will reindent the XML according to tool development "
49+
"best practices as part of this command, this flag will disable "
50+
"that behavior.")
51+
)
52+
@pass_context
53+
def cli(ctx, path, expand_macros=False, **kwds):
54+
"""Generate normalized tool XML from input.
55+
56+
The top-level blocks will be reordered and whitespace fixed according to
57+
the tool development best practices outlined on the Galaxy wiki.
58+
59+
See also https://wiki.galaxyproject.org/Tools/BestPractices.
60+
61+
::
62+
63+
% # Print normalized version of tool.
64+
% planemo normalize tool.xml
65+
<tool>
66+
...
67+
% # Print a variant of tool with all macros expanded out, useful for
68+
% # debugging complex macros.
69+
% planemo normalize --expand_macros tool.xml
70+
<tool>
71+
...
72+
"""
73+
if expand_macros:
74+
tree = load_tool(path)
75+
else:
76+
tree = raw_tool_xml_tree(path)
77+
78+
root = tree.getroot()
79+
if not kwds.get("skip_reorder", False):
80+
last_index = len(TAG_ORDER)
81+
data = []
82+
for elem in root:
83+
tag = elem.tag
84+
if tag in TAG_ORDER:
85+
key = TAG_ORDER.index(tag)
86+
else:
87+
key = last_index
88+
last_index += 1
89+
data.append((key, elem))
90+
data.sort()
91+
root[:] = [item[-1] for item in data]
92+
if not kwds.get("skip_reindent", False):
93+
_indent(root)
94+
ElementTree.dump(root)
95+
96+
97+
def _indent(elem, level=0):
98+
# http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python
99+
i = "\n" + level * " "
100+
if len(elem):
101+
if not elem.text or not elem.text.strip():
102+
elem.text = i + " "
103+
if not elem.tail or not elem.tail.strip():
104+
elem.tail = i
105+
for elem in elem:
106+
_indent(elem, level + 1)
107+
if not elem.tail or not elem.tail.strip():
108+
elem.tail = i
109+
else:
110+
if level and (not elem.tail or not elem.tail.strip()):
111+
elem.tail = i

0 commit comments

Comments
 (0)