/
cmd_tool_init.py
235 lines (226 loc) · 6.16 KB
/
cmd_tool_init.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
import os
import sys
import click
from planemo.cli import pass_context
from planemo import options
from planemo import io
from planemo import tool_builder
REUSING_MACROS_MESSAGE = ("Macros file macros.xml already exists, assuming "
" it has relevant planemo-generated definitions.")
# --input_format
# --output_format
# --advanced_options
@click.option(
"-i",
"--id",
type=click.STRING,
prompt=True,
help="Short identifier for new tool (no whitespace)",
)
@options.force_option(what="tool")
@click.option(
"-t",
"--tool",
default=None,
type=click.Path(exists=False,
file_okay=True,
dir_okay=False,
writable=True,
resolve_path=True),
help="Output path for new tool (default is <id>.xml)",
)
@click.option(
"-n",
"--name",
type=click.STRING,
prompt=True,
help="Name for new tool (user facing)",
)
@click.option(
"--version",
default="0.1.0",
type=click.STRING,
help="Tool XML version.",
)
@click.option(
"-d",
"--description",
type=click.STRING,
default=None,
prompt=False,
help="Short description for new tool (user facing)",
)
@click.option(
"-c",
"--command",
type=click.STRING,
default=None,
prompt=False,
help=("Command potentially including cheetah variables ()"
"(e.g. 'seqtk seq -a $input > $output')"),
)
@click.option(
"--example_command",
type=click.STRING,
default=None,
prompt=False,
help=("Example to command with paths to build Cheetah template from "
"(e.g. 'seqtk seq -a 2.fastq > 2.fasta'). Option cannot be used "
"with --command, should be used --example_input and "
"--example_output."),
)
@click.option(
"--example_input",
type=click.STRING,
default=None,
prompt=False,
multiple=True,
help=("For use with --example_command, replace input file (e.g. 2.fastq "
"with a data input parameter)."),
)
@click.option(
"--example_output",
type=click.STRING,
default=None,
prompt=False,
multiple=True,
help=("For use with --example_command, replace input file (e.g. 2.fastq "
"with a tool output)."),
)
@click.option(
"--version_command",
type=click.STRING,
default=None,
prompt=False,
help="Command to print version (e.g. 'seqtk --version')",
)
@click.option(
"--input",
type=click.STRING,
default=None,
prompt=False,
multiple=True,
help="An input description (e.g. input.fasta)",
)
@click.option(
"--output",
type=click.STRING,
default=None,
prompt=False,
help=("An output location (e.g. output.bam), the Galaxy datatype is "
"inferred from the extension."),
)
@click.option(
"--named_output",
type=click.STRING,
default=None,
prompt=False,
help=("Create a named output for use with command block for example "
"specify --named_output=output1.bam and then use '-o $ouput1' "
"in your command block."),
)
@click.option(
"--help_text",
type=click.STRING,
default=None,
prompt=False,
help="Help text (reStructuredText)",
)
@click.option(
"--help_from_command",
type=click.STRING,
default=None,
prompt=False,
help="Auto populate help from supplied command.",
)
@click.option(
"--requirement",
type=click.STRING,
default=None,
multiple=True,
prompt=False,
help="Add a tool requirement package (e.g. 'seqtk' or 'seqtk@1.68')."
)
@click.option(
"--container",
type=click.STRING,
default=None,
multiple=True,
prompt=False,
help="Add a Docker image identifier for this tool."
)
@click.option(
"--doi",
type=click.STRING,
default=None,
multiple=True,
prompt=False,
help=("Supply a DOI (http://www.doi.org/) easing citation of the tool "
"for Galxy users (e.g. 10.1101/014043).")
)
@click.option(
"--test_case",
is_flag=True,
default=None,
prompt=False,
help=("For use with --example_commmand, generate a tool test case from "
"the supplied example."),
)
@click.option(
"--macros",
is_flag=True,
default=None,
prompt=False,
help="Generate a macros.xml for reuse across many tools.",
)
@click.command("tool_init")
@pass_context
def cli(ctx, **kwds):
"""Generate a tool outline from supplied arguments.
"""
invalid = _validate_kwds(kwds)
if invalid:
return invalid
output = kwds.get("tool")
if not output:
output = "%s.xml" % kwds.get("id")
if not io.can_write_to_path(output, **kwds):
sys.exit(1)
tool_description = tool_builder.build(**kwds)
open(output, "w").write(tool_description.contents)
io.info("Tool written to %s" % output)
macros = kwds["macros"]
macros_file = "macros.xml"
if macros and not os.path.exists(macros_file):
open(macros_file, "w").write(tool_description.macro_contents)
else:
io.info(REUSING_MACROS_MESSAGE)
if tool_description.test_files:
if not os.path.exists("test-data"):
io.info("No test-data directory, creating one.")
io.shell("mkdir -p 'test-data'")
for test_file in tool_description.test_files:
io.info("Copying test-file %s" % test_file)
io.shell("cp '%s' 'test-data'" % test_file)
def _validate_kwds(kwds):
def not_exclusive(x, y):
if kwds.get(x) and kwds.get(y):
io.error("Can only specify one of --%s and --%s" % (x, y))
return True
def not_specifing_dependent_option(x, y):
if kwds.get(x) and not kwds.get(y):
template = "Can only use the --%s option if also specifying --%s"
message = template % (x, y)
io.error(message)
return True
if not_exclusive("help_text", "help_from_command"):
return 1
if not_exclusive("command", "example_command"):
return 1
if not_specifing_dependent_option("example_input", "example_command"):
return 1
if not_specifing_dependent_option("example_output", "example_command"):
return 1
if not_specifing_dependent_option("test_case", "example_command"):
return 1
return 0