Mercurial > repos > fubar > tool_factory_2
comparison toolfactory/rgToolFactory2.py @ 36:ce2b1f8ea68d draft
passes flake8 tests finally :)
author | fubar |
---|---|
date | Mon, 10 Aug 2020 23:24:41 -0400 |
parents | 5052ac89c036 |
children | a30536c100bf |
comparison
equal
deleted
inserted
replaced
35:5d38cb3d9be8 | 36:ce2b1f8ea68d |
---|---|
17 # galaxyxml now generates the tool xml https://github.com/hexylena/galaxyxml | 17 # galaxyxml now generates the tool xml https://github.com/hexylena/galaxyxml |
18 # No support for automatic HTML file creation from arbitrary outputs | 18 # No support for automatic HTML file creation from arbitrary outputs |
19 # TODO: add option to run that code as a post execution hook | 19 # TODO: add option to run that code as a post execution hook |
20 # TODO: add additional history input parameters - currently only one | 20 # TODO: add additional history input parameters - currently only one |
21 | 21 |
22 | |
23 import argparse | |
24 import logging | |
25 import os | |
26 import re | |
27 import shutil | |
28 import subprocess | |
22 import sys | 29 import sys |
23 import subprocess | 30 import tarfile |
24 import shutil | 31 import tempfile |
25 import os | |
26 import time | 32 import time |
27 import tempfile | 33 |
28 import argparse | |
29 import tarfile | |
30 import re | |
31 import galaxyxml.tool as gxt | 34 import galaxyxml.tool as gxt |
32 import galaxyxml.tool.parameters as gxtp | 35 import galaxyxml.tool.parameters as gxtp |
33 import logging | 36 import lxml |
34 | 37 |
35 | 38 foo = lxml.__name__ # fug you, flake8. Say my name! Please accept the PR, Helena! |
36 | 39 |
37 progname = os.path.split(sys.argv[0])[1] | 40 progname = os.path.split(sys.argv[0])[1] |
38 myversion = 'V2.1 July 2020' | 41 myversion = "V2.1 July 2020" |
39 verbose = True | 42 verbose = True |
40 debug = True | 43 debug = True |
41 toolFactoryURL = 'https://github.com/fubar2/toolfactory' | 44 toolFactoryURL = "https://github.com/fubar2/toolfactory" |
42 ourdelim = '~~~' | 45 ourdelim = "~~~" |
43 | 46 |
44 # --input_files="$input_files~~~$CL~~~$input_formats~~~$input_label~~~$input_help" | 47 # --input_files="$input_files~~~$CL~~~$input_formats~~~$input_label~~~$input_help" |
45 IPATHPOS = 0 | 48 IPATHPOS = 0 |
46 ICLPOS = 1 | 49 ICLPOS = 1 |
47 IFMTPOS = 2 | 50 IFMTPOS = 2 |
52 ONAMEPOS = 0 | 55 ONAMEPOS = 0 |
53 OFMTPOS = 1 | 56 OFMTPOS = 1 |
54 OCLPOS = 2 | 57 OCLPOS = 2 |
55 OOCLPOS = 3 | 58 OOCLPOS = 3 |
56 | 59 |
57 #--additional_parameters="$i.param_name~~~$i.param_value~~~$i.param_label~~~$i.param_help~~~$i.param_type~~~$i.CL" | 60 # --additional_parameters="$i.param_name~~~$i.param_value~~~$i.param_label~~~$i.param_help~~~$i.param_type~~~$i.CL" |
58 ANAMEPOS = 0 | 61 ANAMEPOS = 0 |
59 AVALPOS = 1 | 62 AVALPOS = 1 |
60 ALABPOS = 2 | 63 ALABPOS = 2 |
61 AHELPPOS = 3 | 64 AHELPPOS = 3 |
62 ATYPEPOS = 4 | 65 ATYPEPOS = 4 |
63 ACLPOS = 5 | 66 ACLPOS = 5 |
64 AOCLPOS = 6 | 67 AOCLPOS = 6 |
65 | 68 |
69 | |
66 def timenow(): | 70 def timenow(): |
67 """return current time as a string | 71 """return current time as a string |
68 """ | 72 """ |
69 return time.strftime('%d/%m/%Y %H:%M:%S', time.localtime(time.time())) | 73 return time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(time.time())) |
70 | 74 |
71 | 75 |
72 def quote_non_numeric(s): | 76 def quote_non_numeric(s): |
73 """return a prequoted string for non-numerics | 77 """return a prequoted string for non-numerics |
74 useful for perl and Rscript parameter passing? | 78 useful for perl and Rscript parameter passing? |
78 return s | 82 return s |
79 except ValueError: | 83 except ValueError: |
80 return '"%s"' % s | 84 return '"%s"' % s |
81 | 85 |
82 | 86 |
83 html_escape_table = { | 87 html_escape_table = {"&": "&", ">": ">", "<": "<", "$": r"\$"} |
84 "&": "&", | |
85 ">": ">", | |
86 "<": "<", | |
87 "$": r"\$" | |
88 } | |
89 | 88 |
90 | 89 |
91 def html_escape(text): | 90 def html_escape(text): |
92 """Produce entities within text.""" | 91 """Produce entities within text.""" |
93 return "".join(html_escape_table.get(c, c) for c in text) | 92 return "".join(html_escape_table.get(c, c) for c in text) |
94 | 93 |
95 | 94 |
96 def html_unescape(text): | 95 def html_unescape(text): |
97 """Revert entities within text. Multiple character targets so use replace""" | 96 """Revert entities within text. Multiple character targets so use replace""" |
98 t = text.replace('&', '&') | 97 t = text.replace("&", "&") |
99 t = t.replace('>', '>') | 98 t = t.replace(">", ">") |
100 t = t.replace('<', '<') | 99 t = t.replace("<", "<") |
101 t = t.replace('\\$', '$') | 100 t = t.replace("\\$", "$") |
102 return t | 101 return t |
103 | 102 |
104 | 103 |
105 def parse_citations(citations_text): | 104 def parse_citations(citations_text): |
106 """ | 105 """ |
109 citation_tuples = [] | 108 citation_tuples = [] |
110 for citation in citations: | 109 for citation in citations: |
111 if citation.startswith("doi"): | 110 if citation.startswith("doi"): |
112 citation_tuples.append(("doi", citation[len("doi"):].strip())) | 111 citation_tuples.append(("doi", citation[len("doi"):].strip())) |
113 else: | 112 else: |
114 citation_tuples.append( | 113 citation_tuples.append(("bibtex", citation[len("bibtex"):].strip())) |
115 ("bibtex", citation[len("bibtex"):].strip())) | |
116 return citation_tuples | 114 return citation_tuples |
117 | 115 |
118 | 116 |
119 class ScriptRunner: | 117 class ScriptRunner: |
120 """Wrapper for an arbitrary script | 118 """Wrapper for an arbitrary script |
121 uses galaxyxml | 119 uses galaxyxml |
122 | 120 |
123 """ | 121 """ |
124 | 122 |
125 | |
126 def __init__(self, args=None): | 123 def __init__(self, args=None): |
127 """ | 124 """ |
128 prepare command line cl for running the tool here | 125 prepare command line cl for running the tool here |
129 and prepare elements needed for galaxyxml tool generation | 126 and prepare elements needed for galaxyxml tool generation |
130 """ | 127 """ |
136 self.cleanuppar() | 133 self.cleanuppar() |
137 self.lastclredirect = None | 134 self.lastclredirect = None |
138 self.lastxclredirect = None | 135 self.lastxclredirect = None |
139 self.cl = [] | 136 self.cl = [] |
140 self.xmlcl = [] | 137 self.xmlcl = [] |
138 self.is_positional = self.args.parampass == "positional" | |
141 aCL = self.cl.append | 139 aCL = self.cl.append |
142 assert args.parampass in ['0','argparse','positional'],'Parameter passing in args.parampass must be "0","positional" or "argparse"' | 140 assert args.parampass in [ |
143 self.tool_name = re.sub('[^a-zA-Z0-9_]+', '', args.tool_name) | 141 "0", |
142 "argparse", | |
143 "positional", | |
144 ], 'Parameter passing in args.parampass must be "0","positional" or "argparse"' | |
145 self.tool_name = re.sub("[^a-zA-Z0-9_]+", "", args.tool_name) | |
144 self.tool_id = self.tool_name | 146 self.tool_id = self.tool_name |
145 self.xmlfile = '%s.xml' % self.tool_name | 147 self.xmlfile = "%s.xml" % self.tool_name |
146 if self.args.runmode == "Executable" or self.args.runmode == "system": # binary - no need | 148 if self.args.interpreter_name: |
149 exe = "$runMe" | |
150 else: | |
151 exe = self.args.exe_package | |
152 assert ( | |
153 exe is not None | |
154 ), "No interpeter or executable passed in - nothing to run so cannot build" | |
155 self.tool = gxt.Tool( | |
156 self.args.tool_name, | |
157 self.tool_id, | |
158 self.args.tool_version, | |
159 self.args.tool_desc, | |
160 exe, | |
161 ) | |
162 self.tinputs = gxtp.Inputs() | |
163 self.toutputs = gxtp.Outputs() | |
164 self.testparam = [] | |
165 if ( | |
166 self.args.runmode == "Executable" or self.args.runmode == "system" | |
167 ): # binary - no need | |
147 aCL(self.args.exe_package) # this little CL will just run | 168 aCL(self.args.exe_package) # this little CL will just run |
148 else: | 169 else: |
149 rx = open(self.args.script_path, 'r').readlines() | 170 self.prepScript() |
150 rx = [x.rstrip() for x in rx ] | |
151 rxcheck = [x.strip() for x in rx if x.strip() > ''] | |
152 assert len(rxcheck) > 0,"Supplied script is empty. Cannot run" | |
153 self.script = '\n'.join(rx) | |
154 fhandle, self.sfile = tempfile.mkstemp( | |
155 prefix=self.tool_name, suffix=".%s" % (args.interpreter_name)) | |
156 tscript = open(self.sfile, 'w') | |
157 tscript.write(self.script) | |
158 tscript.close() | |
159 self.indentedScript = " %s" % '\n'.join( | |
160 [' %s' % html_escape(x) for x in rx]) | |
161 self.escapedScript = "%s" % '\n'.join( | |
162 [' %s' % html_escape(x) for x in rx]) | |
163 art = '%s.%s' % (self.tool_name, args.interpreter_name) | |
164 artifact = open(art, 'wb') | |
165 artifact.write(bytes(self.script, "utf8")) | |
166 artifact.close() | |
167 aCL(self.args.interpreter_name) | |
168 aCL(self.sfile) | |
169 self.elog = "%s_error_log.txt" % self.tool_name | 171 self.elog = "%s_error_log.txt" % self.tool_name |
170 self.tlog = "%s_runner_log.txt" % self.tool_name | 172 self.tlog = "%s_runner_log.txt" % self.tool_name |
171 | 173 |
172 if self.args.parampass == '0': | 174 if self.args.parampass == "0": |
173 self.clsimple() | 175 self.clsimple() |
174 else: | 176 else: |
175 clsuffix = [] | 177 clsuffix = [] |
176 xclsuffix = [] | 178 xclsuffix = [] |
177 for i, p in enumerate(self.infiles): | 179 for i, p in enumerate(self.infiles): |
178 appendme = [p[IOCLPOS], p[ICLPOS], p[IPATHPOS]] | 180 appendme = [p[IOCLPOS], p[ICLPOS], p[IPATHPOS]] |
179 clsuffix.append(appendme) | 181 clsuffix.append(appendme) |
180 xclsuffix.append([p[IOCLPOS],p[ICLPOS],'$%s' % p[ICLPOS]]) | 182 xclsuffix.append([p[IOCLPOS], p[ICLPOS], "$%s" % p[ICLPOS]]) |
181 #print('##infile i=%d, appendme=%s' % (i,appendme)) | 183 # print('##infile i=%d, appendme=%s' % (i,appendme)) |
182 for i, p in enumerate(self.outfiles): | 184 for i, p in enumerate(self.outfiles): |
183 if p[OOCLPOS] == "STDOUT": | 185 if p[OOCLPOS] == "STDOUT": |
184 self.lastclredirect = ['>',p[ONAMEPOS]] | 186 self.lastclredirect = [">", p[ONAMEPOS]] |
185 self.lastxclredirect = ['>','$%s' % p[OCLPOS]] | 187 self.lastxclredirect = [">", "$%s" % p[OCLPOS]] |
186 #print('##outfiles i=%d lastclredirect = %s' % (i,self.lastclredirect)) | 188 # print('##outfiles i=%d lastclredirect = %s' % (i,self.lastclredirect)) |
187 else: | 189 else: |
188 appendme = [p[OOCLPOS], p[OCLPOS],p[ONAMEPOS]] | 190 appendme = [p[OOCLPOS], p[OCLPOS], p[ONAMEPOS]] |
189 clsuffix.append(appendme) | 191 clsuffix.append(appendme) |
190 xclsuffix.append([p[OOCLPOS], p[OCLPOS],'$%s' % p[ONAMEPOS]]) | 192 xclsuffix.append([p[OOCLPOS], p[OCLPOS], "$%s" % p[ONAMEPOS]]) |
191 #print('##outfiles i=%d' % i,'appendme',appendme) | 193 # print('##outfiles i=%d' % i,'appendme',appendme) |
192 for p in self.addpar: | 194 for p in self.addpar: |
193 appendme = [p[AOCLPOS], p[ACLPOS], p[AVALPOS]] | 195 appendme = [p[AOCLPOS], p[ACLPOS], p[AVALPOS]] |
194 clsuffix.append(appendme) | 196 clsuffix.append(appendme) |
195 xclsuffix.append([p[AOCLPOS], p[ACLPOS], '"$%s"' % p[ANAMEPOS]]) | 197 xclsuffix.append([p[AOCLPOS], p[ACLPOS], '"$%s"' % p[ANAMEPOS]]) |
196 #print('##adpar %d' % i,'appendme=',appendme) | 198 # print('##adpar %d' % i,'appendme=',appendme) |
197 clsuffix.sort() | 199 clsuffix.sort() |
198 xclsuffix.sort() | 200 xclsuffix.sort() |
199 self.xclsuffix = xclsuffix | 201 self.xclsuffix = xclsuffix |
200 self.clsuffix = clsuffix | 202 self.clsuffix = clsuffix |
201 if self.args.parampass == 'positional': | 203 if self.args.parampass == "positional": |
202 self.clpositional() | 204 self.clpositional() |
203 else: | 205 else: |
204 self.clargparse() | 206 self.clargparse() |
205 | 207 |
208 def prepScript(self): | |
209 aCL = self.cl.append | |
210 rx = open(self.args.script_path, "r").readlines() | |
211 rx = [x.rstrip() for x in rx] | |
212 rxcheck = [x.strip() for x in rx if x.strip() > ""] | |
213 assert len(rxcheck) > 0, "Supplied script is empty. Cannot run" | |
214 self.script = "\n".join(rx) | |
215 fhandle, self.sfile = tempfile.mkstemp( | |
216 prefix=self.tool_name, suffix=".%s" % (self.args.interpreter_name) | |
217 ) | |
218 tscript = open(self.sfile, "w") | |
219 tscript.write(self.script) | |
220 tscript.close() | |
221 self.indentedScript = " %s" % "\n".join([" %s" % html_escape(x) for x in rx]) | |
222 self.escapedScript = "%s" % "\n".join([" %s" % html_escape(x) for x in rx]) | |
223 art = "%s.%s" % (self.tool_name, self.args.interpreter_name) | |
224 artifact = open(art, "wb") | |
225 artifact.write(bytes(self.script, "utf8")) | |
226 artifact.close() | |
227 aCL(self.args.interpreter_name) | |
228 aCL(self.sfile) | |
229 | |
206 def cleanuppar(self): | 230 def cleanuppar(self): |
207 """ positional parameters are complicated by their numeric ordinal""" | 231 """ positional parameters are complicated by their numeric ordinal""" |
208 for i,p in enumerate(self.infiles): | 232 for i, p in enumerate(self.infiles): |
209 if self.args.parampass == 'positional': | 233 if self.args.parampass == "positional": |
210 assert p[ICLPOS].isdigit(), "Positional parameters must be ordinal integers - got %s for %s" % (p[ICLPOS],p[ILABPOS]) | 234 assert p[ICLPOS].isdigit(), ( |
235 "Positional parameters must be ordinal integers - got %s for %s" | |
236 % (p[ICLPOS], p[ILABPOS]) | |
237 ) | |
211 p.append(p[ICLPOS]) | 238 p.append(p[ICLPOS]) |
212 if p[ICLPOS].isdigit() or self.args.parampass == "0": | 239 if p[ICLPOS].isdigit() or self.args.parampass == "0": |
213 scl = 'input%d' % (i+1) | 240 scl = "input%d" % (i + 1) |
214 p[ICLPOS] = scl | 241 p[ICLPOS] = scl |
215 self.infiles[i] = p | 242 self.infiles[i] = p |
216 for i,p in enumerate(self.outfiles): # trying to automagically gather using extensions | 243 for i, p in enumerate( |
217 if self.args.parampass == 'positional' and p[OCLPOS] != "STDOUT": | 244 self.outfiles |
218 assert p[OCLPOS].isdigit(), "Positional parameters must be ordinal integers - got %s for %s" % (p[OCLPOS],p[ONAMEPOS]) | 245 ): # trying to automagically gather using extensions |
246 if self.args.parampass == "positional" and p[OCLPOS] != "STDOUT": | |
247 assert p[OCLPOS].isdigit(), ( | |
248 "Positional parameters must be ordinal integers - got %s for %s" | |
249 % (p[OCLPOS], p[ONAMEPOS]) | |
250 ) | |
219 p.append(p[OCLPOS]) | 251 p.append(p[OCLPOS]) |
220 if p[OCLPOS].isdigit() or p[OCLPOS] == "STDOUT": | 252 if p[OCLPOS].isdigit() or p[OCLPOS] == "STDOUT": |
221 scl = p[ONAMEPOS] | 253 scl = p[ONAMEPOS] |
222 p[OCLPOS] = scl | 254 p[OCLPOS] = scl |
223 self.outfiles[i] = p | 255 self.outfiles[i] = p |
224 for i,p in enumerate(self.addpar): | 256 for i, p in enumerate(self.addpar): |
225 if self.args.parampass == 'positional': | 257 if self.args.parampass == "positional": |
226 assert p[ACLPOS].isdigit(), "Positional parameters must be ordinal integers - got %s for %s" % (p[ACLPOS],p[ANAMEPOS]) | 258 assert p[ACLPOS].isdigit(), ( |
259 "Positional parameters must be ordinal integers - got %s for %s" | |
260 % (p[ACLPOS], p[ANAMEPOS]) | |
261 ) | |
227 p.append(p[ACLPOS]) | 262 p.append(p[ACLPOS]) |
228 if p[ACLPOS].isdigit(): | 263 if p[ACLPOS].isdigit(): |
229 scl = 'input%s' % p[ACLPOS] | 264 scl = "input%s" % p[ACLPOS] |
230 p[ACLPOS] = scl | 265 p[ACLPOS] = scl |
231 self.addpar[i] = p | 266 self.addpar[i] = p |
232 | 267 |
233 | |
234 | |
235 def clsimple(self): | 268 def clsimple(self): |
236 """ no parameters - uses < and > for i/o | 269 """ no parameters - uses < and > for i/o |
237 """ | 270 """ |
238 aCL = self.cl.append | 271 aCL = self.cl.append |
239 aCL('<') | 272 aCL("<") |
240 aCL(self.infiles[0][IPATHPOS]) | 273 aCL(self.infiles[0][IPATHPOS]) |
241 aCL('>') | 274 aCL(">") |
242 aCL(self.outfiles[0][OCLPOS]) | 275 aCL(self.outfiles[0][OCLPOS]) |
243 aXCL = self.xmlcl.append | 276 aXCL = self.xmlcl.append |
244 aXCL('<') | 277 aXCL("<") |
245 aXCL('$%s' % self.infiles[0][ICLPOS]) | 278 aXCL("$%s" % self.infiles[0][ICLPOS]) |
246 aXCL('>') | 279 aXCL(">") |
247 aXCL('$%s' % self.outfiles[0][ONAMEPOS]) | 280 aXCL("$%s" % self.outfiles[0][ONAMEPOS]) |
248 | |
249 | 281 |
250 def clpositional(self): | 282 def clpositional(self): |
251 # inputs in order then params | 283 # inputs in order then params |
252 aCL = self.cl.append | 284 aCL = self.cl.append |
253 for (o_v,k, v) in self.clsuffix: | 285 for (o_v, k, v) in self.clsuffix: |
254 if " " in v: | 286 if " " in v: |
255 aCL("%s" % v) | 287 aCL("%s" % v) |
256 else: | 288 else: |
257 aCL(v) | 289 aCL(v) |
258 aXCL = self.xmlcl.append | 290 aXCL = self.xmlcl.append |
259 for (o_v,k, v) in self.xclsuffix: | 291 for (o_v, k, v) in self.xclsuffix: |
260 aXCL(v) | 292 aXCL(v) |
261 if self.lastxclredirect: | 293 if self.lastxclredirect: |
262 aXCL(self.lastxclredirect[0]) | 294 aXCL(self.lastxclredirect[0]) |
263 aXCL(self.lastxclredirect[1]) | 295 aXCL(self.lastxclredirect[1]) |
264 | |
265 | |
266 | 296 |
267 def clargparse(self): | 297 def clargparse(self): |
268 """ argparse style | 298 """ argparse style |
269 """ | 299 """ |
270 aCL = self.cl.append | 300 aCL = self.cl.append |
271 aXCL = self.xmlcl.append | 301 aXCL = self.xmlcl.append |
272 # inputs then params in argparse named form | 302 # inputs then params in argparse named form |
273 for (o_v,k, v) in self.xclsuffix: | 303 for (o_v, k, v) in self.xclsuffix: |
274 if len(k.strip()) == 1: | 304 if len(k.strip()) == 1: |
275 k = '-%s' % k | 305 k = "-%s" % k |
276 else: | 306 else: |
277 k = '--%s' % k | 307 k = "--%s" % k |
278 aXCL(k) | 308 aXCL(k) |
279 aXCL(v) | 309 aXCL(v) |
280 for (o_v,k, v) in self.clsuffix: | 310 for (o_v, k, v) in self.clsuffix: |
281 if len(k.strip()) == 1: | 311 if len(k.strip()) == 1: |
282 k = '-%s' % k | 312 k = "-%s" % k |
283 else: | 313 else: |
284 k = '--%s' % k | 314 k = "--%s" % k |
285 aCL(k) | 315 aCL(k) |
286 aCL(v) | 316 aCL(v) |
287 | 317 |
288 | 318 def getNdash(self, newname): |
289 | 319 if self.is_positional: |
320 ndash = 0 | |
321 else: | |
322 ndash = 2 | |
323 if len(newname) < 2: | |
324 ndash = 1 | |
325 return ndash | |
326 | |
327 def doXMLparam(self): | |
328 """flake8 made me do this...""" | |
329 for p in self.outfiles: | |
330 newname, newfmt, newcl, oldcl = p | |
331 ndash = self.getNdash(newcl) | |
332 aparm = gxtp.OutputData(newcl, format=newfmt, num_dashes=ndash) | |
333 aparm.positional = self.is_positional | |
334 if self.is_positional: | |
335 if oldcl == "STDOUT": | |
336 aparm.positional = 9999999 | |
337 aparm.command_line_override = "> $%s" % newcl | |
338 else: | |
339 aparm.positional = int(oldcl) | |
340 aparm.command_line_override = "$%s" % newcl | |
341 self.toutputs.append(aparm) | |
342 tp = gxtp.TestOutput(name=newcl, value="%s_sample" % newcl, format=newfmt) | |
343 self.testparam.append(tp) | |
344 for p in self.infiles: | |
345 newname = p[ICLPOS] | |
346 newfmt = p[IFMTPOS] | |
347 ndash = self.getNdash(newname) | |
348 if not len(p[ILABPOS]) > 0: | |
349 alab = p[ICLPOS] | |
350 else: | |
351 alab = p[ILABPOS] | |
352 aninput = gxtp.DataParam( | |
353 newname, | |
354 optional=False, | |
355 label=alab, | |
356 help=p[IHELPOS], | |
357 format=newfmt, | |
358 multiple=False, | |
359 num_dashes=ndash, | |
360 ) | |
361 aninput.positional = self.is_positional | |
362 self.tinputs.append(aninput) | |
363 tparm = gxtp.TestParam(name=newname, value="%s_sample" % newname) | |
364 self.testparam.append(tparm) | |
365 for p in self.addpar: | |
366 newname, newval, newlabel, newhelp, newtype, newcl, oldcl = p | |
367 if not len(newlabel) > 0: | |
368 newlabel = newname | |
369 ndash = self.getNdash(newname) | |
370 if newtype == "text": | |
371 aparm = gxtp.TextParam( | |
372 newname, | |
373 label=newlabel, | |
374 help=newhelp, | |
375 value=newval, | |
376 num_dashes=ndash, | |
377 ) | |
378 elif newtype == "integer": | |
379 aparm = gxtp.IntegerParam( | |
380 newname, | |
381 label=newname, | |
382 help=newhelp, | |
383 value=newval, | |
384 num_dashes=ndash, | |
385 ) | |
386 elif newtype == "float": | |
387 aparm = gxtp.FloatParam( | |
388 newname, | |
389 label=newname, | |
390 help=newhelp, | |
391 value=newval, | |
392 num_dashes=ndash, | |
393 ) | |
394 else: | |
395 raise ValueError( | |
396 'Unrecognised parameter type "%s" for\ | |
397 additional parameter %s in makeXML' | |
398 % (newtype, newname) | |
399 ) | |
400 aparm.positional = self.is_positional | |
401 if self.is_positional: | |
402 aninput.positional = int(oldcl) | |
403 self.tinputs.append(aparm) | |
404 self.tparm = gxtp.TestParam(newname, value=newval) | |
405 self.testparam.append(tparm) | |
406 | |
407 def doNoXMLparam(self): | |
408 alab = self.infiles[0][ILABPOS] | |
409 if len(alab) == 0: | |
410 alab = self.infiles[0][ICLPOS] | |
411 max1s = ( | |
412 "Maximum one input if parampass is 0 - more than one input files supplied - %s" | |
413 % str(self.infiles) | |
414 ) | |
415 assert len(self.infiles) == 1, max1s | |
416 newname = self.infiles[0][ICLPOS] | |
417 aninput = gxtp.DataParam( | |
418 newname, | |
419 optional=False, | |
420 label=alab, | |
421 help=self.infiles[0][IHELPOS], | |
422 format=self.infiles[0][IFMTPOS], | |
423 multiple=False, | |
424 num_dashes=0, | |
425 ) | |
426 aninput.command_line_override = "< $%s" % newname | |
427 aninput.positional = self.is_positional | |
428 self.tinputs.append(aninput) | |
429 tp = gxtp.TestParam(name=newname, value="%s_sample" % newname) | |
430 self.testparam.append(tp) | |
431 newname = self.outfiles[0][OCLPOS] | |
432 newfmt = self.outfiles[0][OFMTPOS] | |
433 anout = gxtp.OutputData(newname, format=newfmt, num_dashes=0) | |
434 anout.command_line_override = "> $%s" % newname | |
435 anout.positional = self.is_positional | |
436 self.toutputs.append(anout) | |
437 tp = gxtp.TestOutput(name=newname, value="%s_sample" % newname, format=newfmt) | |
438 self.testparam.append(tp) | |
290 | 439 |
291 def makeXML(self): | 440 def makeXML(self): |
292 """ | 441 """ |
293 Create a Galaxy xml tool wrapper for the new script | 442 Create a Galaxy xml tool wrapper for the new script |
294 Uses galaxyhtml | 443 Uses galaxyhtml |
295 Hmmm. How to get the command line into correct order... | 444 Hmmm. How to get the command line into correct order... |
296 """ | 445 """ |
297 | 446 self.tool.command_line_override = self.xmlcl |
298 if self.args.interpreter_name: | 447 if self.args.interpreter_name: |
299 exe = "$runMe" | 448 self.tool.interpreter = self.interp |
300 interp = self.args.interpreter_name | |
301 else: | |
302 interp = None | |
303 exe = self.args.exe_package | |
304 assert exe is not None, 'No interpeter or executable passed in to makeXML' | |
305 tool = gxt.Tool(self.args.tool_name, self.tool_id, | |
306 self.args.tool_version, self.args.tool_desc, exe) | |
307 tool.command_line_override = self.xmlcl | |
308 if interp: | |
309 tool.interpreter = interp | |
310 if self.args.help_text: | 449 if self.args.help_text: |
311 helptext = open(self.args.help_text, 'r').readlines() | 450 helptext = open(self.args.help_text, "r").readlines() |
312 helptext = [html_escape(x) for x in helptext] | 451 helptext = [html_escape(x) for x in helptext] |
313 tool.help = ''.join([x for x in helptext]) | 452 self.tool.help = "".join([x for x in helptext]) |
314 else: | 453 else: |
315 tool.help = 'Please ask the tool author (%s) for help \ | 454 self.tool.help = ( |
316 as none was supplied at tool generation\n' % (self.args.user_email) | 455 "Please ask the tool author (%s) for help \ |
317 tool.version_command = None # do not want | 456 as none was supplied at tool generation\n" |
318 tinputs = gxtp.Inputs() | 457 % (self.args.user_email) |
319 toutputs = gxtp.Outputs() | 458 ) |
459 self.tool.version_command = None # do not want | |
320 requirements = gxtp.Requirements() | 460 requirements = gxtp.Requirements() |
321 testparam = [] | 461 |
322 is_positional = (self.args.parampass == 'positional') | |
323 if self.args.interpreter_name: | 462 if self.args.interpreter_name: |
324 if self.args.interpreter_name == 'python': | 463 if self.args.interpreter_name == "python": |
325 requirements.append(gxtp.Requirement( | 464 requirements.append( |
326 'package', 'python', self.args.interpreter_version)) | 465 gxtp.Requirement("package", "python", self.args.interpreter_version) |
327 elif self.args.interpreter_name not in ['bash', 'sh']: | 466 ) |
328 requirements.append(gxtp.Requirement( | 467 elif self.args.interpreter_name not in ["bash", "sh"]: |
329 'package', self.args.interpreter_name, self.args.interpreter_version)) | 468 requirements.append( |
469 gxtp.Requirement( | |
470 "package", | |
471 self.args.interpreter_name, | |
472 self.args.interpreter_version, | |
473 ) | |
474 ) | |
330 else: | 475 else: |
331 if self.args.exe_package and self.args.parampass != "system": | 476 if self.args.exe_package and self.args.parampass != "system": |
332 requirements.append(gxtp.Requirement( | 477 requirements.append( |
333 'package', self.args.exe_package, self.args.exe_package_version)) | 478 gxtp.Requirement( |
334 tool.requirements = requirements | 479 "package", self.args.exe_package, self.args.exe_package_version |
335 if self.args.parampass == '0': | 480 ) |
336 alab = self.infiles[0][ILABPOS] | 481 ) |
337 if len(alab) == 0: | 482 self.tool.requirements = requirements |
338 alab = self.infiles[0][ICLPOS] | 483 if self.args.parampass == "0": |
339 max1s = 'Maximum one input if parampass is 0 - more than one input files supplied - %s' % str(self.infiles) | 484 self.doXMLNoparam() |
340 assert len(self.infiles) == 1,max1s | 485 else: |
341 newname = self.infiles[0][ICLPOS] | 486 self.doXMLParam() |
342 aninput = gxtp.DataParam(newname, optional=False, label=alab, help=self.infiles[0][IHELPOS], | 487 self.tool.outputs = self.toutputs |
343 format=self.infiles[0][IFMTPOS], multiple=False, num_dashes=0) | 488 self.tool.inputs = self.tinputs |
344 aninput.command_line_override = '< $%s' % newname | 489 if self.args.runmode not in ["Executable", "system"]: |
345 aninput.positional = is_positional | |
346 tinputs.append(aninput) | |
347 tp = gxtp.TestParam(name=newname, value='%s_sample' % newname) | |
348 testparam.append(tp) | |
349 newname = self.outfiles[0][OCLPOS] | |
350 newfmt = self.outfiles[0][OFMTPOS] | |
351 anout = gxtp.OutputData(newname, format=newfmt, num_dashes=0) | |
352 anout.command_line_override = '> $%s' % newname | |
353 anout.positional = is_positional | |
354 toutputs.append(anout) | |
355 tp = gxtp.TestOutput(name=newname, value='%s_sample' % newname,format=newfmt) | |
356 testparam.append(tp) | |
357 else: | |
358 for p in self.outfiles: | |
359 newname,newfmt,newcl,oldcl = p | |
360 if is_positional: | |
361 ndash = 0 | |
362 else: | |
363 ndash = 2 | |
364 if len(newcl) < 2: | |
365 ndash = 1 | |
366 aparm = gxtp.OutputData(newcl, format=newfmt, num_dashes=ndash) | |
367 aparm.positional = is_positional | |
368 if is_positional: | |
369 if oldcl == "STDOUT": | |
370 aparm.positional = 9999999 | |
371 aparm.command_line_override = "> $%s" % newcl | |
372 else: | |
373 aparm.positional = int(oldcl) | |
374 aparm.command_line_override = '$%s' % newcl | |
375 toutputs.append(aparm) | |
376 tp = gxtp.TestOutput(name=newcl, value='%s_sample' % newcl ,format=newfmt) | |
377 testparam.append(tp) | |
378 for p in self.infiles: | |
379 newname = p[ICLPOS] | |
380 newfmt = p[IFMTPOS] | |
381 if is_positional: | |
382 ndash = 0 | |
383 else: | |
384 if len(newname) > 1: | |
385 ndash = 2 | |
386 else: | |
387 ndash = 1 | |
388 if not len(p[ILABPOS]) > 0: | |
389 alab = p[ICLPOS] | |
390 else: | |
391 alab = p[ILABPOS] | |
392 aninput = gxtp.DataParam(newname, optional=False, label=alab, help=p[IHELPOS], | |
393 format=newfmt, multiple=False, num_dashes=ndash) | |
394 aninput.positional = is_positional | |
395 if is_positional: | |
396 aninput.positional = is_positional | |
397 tinputs.append(aninput) | |
398 tparm = gxtp.TestParam(name=newname, value='%s_sample' % newname ) | |
399 testparam.append(tparm) | |
400 for p in self.addpar: | |
401 newname, newval, newlabel, newhelp, newtype, newcl, oldcl = p | |
402 if not len(newlabel) > 0: | |
403 newlabel = newname | |
404 if is_positional: | |
405 ndash = 0 | |
406 else: | |
407 if len(newname) > 1: | |
408 ndash = 2 | |
409 else: | |
410 ndash = 1 | |
411 if newtype == "text": | |
412 aparm = gxtp.TextParam( | |
413 newname, label=newlabel, help=newhelp, value=newval, num_dashes=ndash) | |
414 elif newtype == "integer": | |
415 aparm = gxtp.IntegerParam( | |
416 newname, label=newname, help=newhelp, value=newval, num_dashes=ndash) | |
417 elif newtype == "float": | |
418 aparm = gxtp.FloatParam( | |
419 newname, label=newname, help=newhelp, value=newval, num_dashes=ndash) | |
420 else: | |
421 raise ValueError('Unrecognised parameter type "%s" for\ | |
422 additional parameter %s in makeXML' % (newtype, newname)) | |
423 aparm.positional = is_positional | |
424 if is_positional: | |
425 aninput.positional = int(oldcl) | |
426 tinputs.append(aparm) | |
427 tparm = gxtp.TestParam(newname, value=newval) | |
428 testparam.append(tparm) | |
429 tool.outputs = toutputs | |
430 tool.inputs = tinputs | |
431 if not self.args.runmode in ['Executable','system']: | |
432 configfiles = gxtp.Configfiles() | 490 configfiles = gxtp.Configfiles() |
433 configfiles.append(gxtp.Configfile(name="runMe", text=self.script)) | 491 configfiles.append(gxtp.Configfile(name="runMe", text=self.script)) |
434 tool.configfiles = configfiles | 492 self.tool.configfiles = configfiles |
435 tests = gxtp.Tests() | 493 tests = gxtp.Tests() |
436 test_a = gxtp.Test() | 494 test_a = gxtp.Test() |
437 for tp in testparam: | 495 for tp in self.testparam: |
438 test_a.append(tp) | 496 test_a.append(tp) |
439 tests.append(test_a) | 497 tests.append(test_a) |
440 tool.tests = tests | 498 self.tool.tests = tests |
441 tool.add_comment('Created by %s at %s using the Galaxy Tool Factory.' % ( | 499 self.tool.add_comment( |
442 self.args.user_email, timenow())) | 500 "Created by %s at %s using the Galaxy Tool Factory." |
443 tool.add_comment('Source in git at: %s' % (toolFactoryURL)) | 501 % (self.args.user_email, timenow()) |
444 tool.add_comment( | 502 ) |
445 'Cite: Creating re-usable tools from scripts doi: 10.1093/bioinformatics/bts573') | 503 self.tool.add_comment("Source in git at: %s" % (toolFactoryURL)) |
446 exml = tool.export() | 504 self.tool.add_comment( |
447 xf = open(self.xmlfile, 'w') | 505 "Cite: Creating re-usable tools from scripts doi: 10.1093/bioinformatics/bts573" |
506 ) | |
507 exml = self.tool.export() | |
508 xf = open(self.xmlfile, "w") | |
448 xf.write(exml) | 509 xf.write(exml) |
449 xf.write('\n') | 510 xf.write("\n") |
450 xf.close() | 511 xf.close() |
451 # ready for the tarball | 512 # ready for the tarball |
452 | 513 |
453 def makeTooltar(self): | 514 def makeTooltar(self): |
454 """ | 515 """ |
457 NOTE names for test inputs and outputs are munged here so must | 518 NOTE names for test inputs and outputs are munged here so must |
458 correspond to actual input and output names used on the generated cl | 519 correspond to actual input and output names used on the generated cl |
459 """ | 520 """ |
460 retval = self.run() | 521 retval = self.run() |
461 if retval: | 522 if retval: |
462 sys.stderr.write( | 523 sys.stderr.write("## Run failed. Cannot build yet. Please fix and retry") |
463 '## Run failed. Cannot build yet. Please fix and retry') | |
464 sys.exit(1) | 524 sys.exit(1) |
465 tdir = 'tfout' | 525 tdir = "tfout" |
466 if not os.path.exists(tdir): | 526 if not os.path.exists(tdir): |
467 os.mkdir(tdir) | 527 os.mkdir(tdir) |
468 self.makeXML() | 528 self.makeXML() |
469 testdir = os.path.join(tdir,'test-data') | 529 testdir = os.path.join(tdir, "test-data") |
470 if not os.path.exists(testdir): | 530 if not os.path.exists(testdir): |
471 os.mkdir(testdir) # make tests directory | 531 os.mkdir(testdir) # make tests directory |
472 for p in self.infiles: | 532 for p in self.infiles: |
473 pth = p[IPATHPOS] | 533 pth = p[IPATHPOS] |
474 dest = os.path.join(testdir, '%s_sample' % | 534 dest = os.path.join(testdir, "%s_sample" % p[ICLPOS]) |
475 p[ICLPOS]) | |
476 shutil.copyfile(pth, dest) | 535 shutil.copyfile(pth, dest) |
477 for p in self.outfiles: | 536 for p in self.outfiles: |
478 pth = p[OCLPOS] | 537 pth = p[OCLPOS] |
479 if p[OOCLPOS] == 'STDOUT' or self.args.parampass == "0": | 538 if p[OOCLPOS] == "STDOUT" or self.args.parampass == "0": |
480 pth = p[ONAMEPOS] | 539 pth = p[ONAMEPOS] |
481 dest = os.path.join(testdir,'%s_sample' % p[ONAMEPOS]) | 540 dest = os.path.join(testdir, "%s_sample" % p[ONAMEPOS]) |
482 shutil.copyfile(pth, dest) | 541 shutil.copyfile(pth, dest) |
483 dest = os.path.join(tdir, p[ONAMEPOS]) | 542 dest = os.path.join(tdir, p[ONAMEPOS]) |
484 shutil.copyfile(pth, dest) | 543 shutil.copyfile(pth, dest) |
485 else: | 544 else: |
486 pth = p[OCLPOS] | 545 pth = p[OCLPOS] |
487 dest = os.path.join(testdir,'%s_sample' % p[OCLPOS]) | 546 dest = os.path.join(testdir, "%s_sample" % p[OCLPOS]) |
488 shutil.copyfile(pth, dest) | 547 shutil.copyfile(pth, dest) |
489 dest = os.path.join(tdir, p[OCLPOS]) | 548 dest = os.path.join(tdir, p[OCLPOS]) |
490 shutil.copyfile(pth, dest) | 549 shutil.copyfile(pth, dest) |
491 | 550 |
492 if os.path.exists(self.tlog) and os.stat(self.tlog).st_size > 0: | 551 if os.path.exists(self.tlog) and os.stat(self.tlog).st_size > 0: |
493 shutil.copyfile(self.tlog, os.path.join( | 552 shutil.copyfile(self.tlog, os.path.join(testdir, "test1_log.txt")) |
494 testdir, 'test1_log.txt')) | 553 if self.args.runmode not in ["Executable", "system"]: |
495 if not self.args.runmode in ['Executable','system']: | 554 stname = os.path.join(tdir, "%s" % (self.sfile)) |
496 stname = os.path.join(tdir, '%s' % (self.sfile)) | |
497 if not os.path.exists(stname): | 555 if not os.path.exists(stname): |
498 shutil.copyfile(self.sfile, stname) | 556 shutil.copyfile(self.sfile, stname) |
499 xtname = os.path.join(tdir,self.xmlfile) | 557 xtname = os.path.join(tdir, self.xmlfile) |
500 if not os.path.exists(xtname): | 558 if not os.path.exists(xtname): |
501 shutil.copyfile(self.xmlfile, xtname) | 559 shutil.copyfile(self.xmlfile, xtname) |
502 tarpath = 'toolfactory_%s.tgz' % self.tool_name | 560 tarpath = "toolfactory_%s.tgz" % self.tool_name |
503 tf = tarfile.open(tarpath,"w:gz") | 561 tf = tarfile.open(tarpath, "w:gz") |
504 tf.add(name=tdir,arcname=self.tool_name) | 562 tf.add(name=tdir, arcname=self.tool_name) |
505 tf.close() | 563 tf.close() |
506 shutil.copyfile(tarpath, self.args.new_tool) | 564 shutil.copyfile(tarpath, self.args.new_tool) |
507 return retval | 565 return retval |
508 | 566 |
509 def run(self): | 567 def run(self): |
510 """ | 568 """ |
511 Some devteam tools have this defensive stderr read so I'm keeping with the faith | 569 Some devteam tools have this defensive stderr read so I'm keeping with the faith |
512 Feel free to update. | 570 Feel free to update. |
513 """ | 571 """ |
514 s = 'run cl=%s' % str(self.cl) | 572 s = "run cl=%s" % str(self.cl) |
515 | 573 |
516 logging.debug(s) | 574 logging.debug(s) |
517 scl = ' '.join(self.cl) | 575 scl = " ".join(self.cl) |
518 err = None | 576 err = None |
519 if self.args.parampass != '0': | 577 if self.args.parampass != "0": |
520 ste = open(self.elog, 'wb') | 578 ste = open(self.elog, "wb") |
521 if self.lastclredirect: | 579 if self.lastclredirect: |
522 sto = open(self.lastclredirect[1],'wb') # is name of an output file | 580 sto = open(self.lastclredirect[1], "wb") # is name of an output file |
523 else: | 581 else: |
524 sto = open(self.tlog, 'wb') | 582 sto = open(self.tlog, "wb") |
525 sto.write( | 583 sto.write( |
526 bytes('## Executing Toolfactory generated command line = %s\n' % scl, "utf8")) | 584 bytes( |
585 "## Executing Toolfactory generated command line = %s\n" % scl, | |
586 "utf8", | |
587 ) | |
588 ) | |
527 sto.flush() | 589 sto.flush() |
528 p = subprocess.run(self.cl, shell=False, stdout=sto, | 590 p = subprocess.run(self.cl, shell=False, stdout=sto, stderr=ste) |
529 stderr=ste) | |
530 sto.close() | 591 sto.close() |
531 ste.close() | 592 ste.close() |
532 tmp_stderr = open(self.elog, 'rb') | 593 tmp_stderr = open(self.elog, "rb") |
533 err = '' | 594 err = "" |
534 buffsize = 1048576 | 595 buffsize = 1048576 |
535 try: | 596 try: |
536 while True: | 597 while True: |
537 err += str(tmp_stderr.read(buffsize)) | 598 err += str(tmp_stderr.read(buffsize)) |
538 if not err or len(err) % buffsize != 0: | 599 if not err or len(err) % buffsize != 0: |
540 except OverflowError: | 601 except OverflowError: |
541 pass | 602 pass |
542 tmp_stderr.close() | 603 tmp_stderr.close() |
543 retval = p.returncode | 604 retval = p.returncode |
544 else: # work around special case of simple scripts that take stdin and write to stdout | 605 else: # work around special case of simple scripts that take stdin and write to stdout |
545 sti = open(self.infiles[0][IPATHPOS], 'rb') | 606 sti = open(self.infiles[0][IPATHPOS], "rb") |
546 sto = open(self.outfiles[0][ONAMEPOS], 'wb') | 607 sto = open(self.outfiles[0][ONAMEPOS], "wb") |
547 # must use shell to redirect | 608 # must use shell to redirect |
548 p = subprocess.run(self.cl, shell=False, stdout=sto, stdin=sti) | 609 p = subprocess.run(self.cl, shell=False, stdout=sto, stdin=sti) |
549 retval = p.returncode | 610 retval = p.returncode |
550 sto.close() | 611 sto.close() |
551 sti.close() | 612 sti.close() |
553 os.unlink(self.tlog) | 614 os.unlink(self.tlog) |
554 if os.path.isfile(self.elog) and os.stat(self.elog).st_size == 0: | 615 if os.path.isfile(self.elog) and os.stat(self.elog).st_size == 0: |
555 os.unlink(self.elog) | 616 os.unlink(self.elog) |
556 if p.returncode != 0 and err: # problem | 617 if p.returncode != 0 and err: # problem |
557 sys.stderr.write(err) | 618 sys.stderr.write(err) |
558 logging.debug('run done') | 619 logging.debug("run done") |
559 return retval | 620 return retval |
560 | 621 |
561 | 622 |
562 def main(): | 623 def main(): |
563 """ | 624 """ |
565 <command interpreter="python">rgBaseScriptWrapper.py --script_path "$scriptPath" --tool_name "foo" --interpreter "Rscript" | 626 <command interpreter="python">rgBaseScriptWrapper.py --script_path "$scriptPath" --tool_name "foo" --interpreter "Rscript" |
566 </command> | 627 </command> |
567 """ | 628 """ |
568 parser = argparse.ArgumentParser() | 629 parser = argparse.ArgumentParser() |
569 a = parser.add_argument | 630 a = parser.add_argument |
570 a('--script_path', default='') | 631 a("--script_path", default="") |
571 a('--tool_name', default=None) | 632 a("--tool_name", default=None) |
572 a('--interpreter_name', default=None) | 633 a("--interpreter_name", default=None) |
573 a('--interpreter_version', default=None) | 634 a("--interpreter_version", default=None) |
574 a('--exe_package', default=None) | 635 a("--exe_package", default=None) |
575 a('--exe_package_version', default=None) | 636 a("--exe_package_version", default=None) |
576 a('--input_files', default=[], action="append") | 637 a("--input_files", default=[], action="append") |
577 a('--output_files', default=[], action="append") | 638 a("--output_files", default=[], action="append") |
578 a('--user_email', default='Unknown') | 639 a("--user_email", default="Unknown") |
579 a('--bad_user', default=None) | 640 a("--bad_user", default=None) |
580 a('--make_Tool', default=None) | 641 a("--make_Tool", default=None) |
581 a('--help_text', default=None) | 642 a("--help_text", default=None) |
582 a('--tool_desc', default=None) | 643 a("--tool_desc", default=None) |
583 a('--tool_version', default=None) | 644 a("--tool_version", default=None) |
584 a('--citations', default=None) | 645 a("--citations", default=None) |
585 a('--additional_parameters', action='append', default=[]) | 646 a("--additional_parameters", action="append", default=[]) |
586 a('--edit_additional_parameters', action="store_true", default=False) | 647 a("--edit_additional_parameters", action="store_true", default=False) |
587 a('--parampass', default="positional") | 648 a("--parampass", default="positional") |
588 a('--tfout', default="./tfout") | 649 a("--tfout", default="./tfout") |
589 a('--new_tool',default="new_tool") | 650 a("--new_tool", default="new_tool") |
590 a('--runmode',default=None) | 651 a("--runmode", default=None) |
591 args = parser.parse_args() | 652 args = parser.parse_args() |
592 assert not args.bad_user, 'UNAUTHORISED: %s is NOT authorized to use this tool until Galaxy admin adds %s to "admin_users" in the Galaxy configuration file' % ( | 653 assert not args.bad_user, ( |
593 args.bad_user, args.bad_user) | 654 'UNAUTHORISED: %s is NOT authorized to use this tool until Galaxy admin adds %s to "admin_users" in the Galaxy configuration file' |
594 assert args.tool_name, '## Tool Factory expects a tool name - eg --tool_name=DESeq' | 655 % (args.bad_user, args.bad_user) |
595 assert (args.interpreter_name or args.exe_package), '## Tool Factory wrapper expects an interpreter - eg --interpreter_name=Rscript or an executable package findable by the dependency management package' | 656 ) |
596 assert args.exe_package or (len(args.script_path) > 0 and os.path.isfile( | 657 assert args.tool_name, "## Tool Factory expects a tool name - eg --tool_name=DESeq" |
597 args.script_path)), '## Tool Factory wrapper expects a script path - eg --script_path=foo.R if no executable' | 658 assert ( |
598 args.input_files = [x.replace('"', '').replace("'", '') | 659 args.interpreter_name or args.exe_package |
599 for x in args.input_files] | 660 ), "## Tool Factory wrapper expects an interpreter or an executable package" |
661 assert args.exe_package or ( | |
662 len(args.script_path) > 0 and os.path.isfile(args.script_path) | |
663 ), "## Tool Factory wrapper expects a script path - eg --script_path=foo.R if no executable" | |
664 args.input_files = [x.replace('"', "").replace("'", "") for x in args.input_files] | |
600 # remove quotes we need to deal with spaces in CL params | 665 # remove quotes we need to deal with spaces in CL params |
601 for i, x in enumerate(args.additional_parameters): | 666 for i, x in enumerate(args.additional_parameters): |
602 args.additional_parameters[i] = args.additional_parameters[i].replace( | 667 args.additional_parameters[i] = args.additional_parameters[i].replace('"', "") |
603 '"', '') | |
604 r = ScriptRunner(args) | 668 r = ScriptRunner(args) |
605 if args.make_Tool: | 669 if args.make_Tool: |
606 retcode = r.makeTooltar() | 670 retcode = r.makeTooltar() |
607 else: | 671 else: |
608 retcode = r.run() | 672 retcode = r.run() |