comparison DockerToolFactory.py @ 4:de4889098f45 default tip

Allow whitespace in gene name and fix missing creation of output section.
author mvdbeek
date Wed, 14 Jan 2015 17:19:16 +0100
parents 5b930e77b1f3
children
comparison
equal deleted inserted replaced
3:477eac6c4cea 4:de4889098f45
152 self.temp_warned = False # we want only one warning if $TMP not set 152 self.temp_warned = False # we want only one warning if $TMP not set
153 self.treatbashSpecial = treatbashSpecial 153 self.treatbashSpecial = treatbashSpecial
154 self.image_tag = image_tag 154 self.image_tag = image_tag
155 os.chdir(abspath(opts.output_dir)) 155 os.chdir(abspath(opts.output_dir))
156 self.thumbformat = 'png' 156 self.thumbformat = 'png'
157 self.toolname = re.sub('[^a-zA-Z0-9_]+', '', opts.tool_name) # a sanitizer now does this but.. 157 self.toolname_sanitized = re.sub('[^a-zA-Z0-9_]+', '_', opts.tool_name) # a sanitizer now does this but..
158 self.toolname = opts.tool_name
158 self.toolid = self.toolname 159 self.toolid = self.toolname
159 self.myname = sys.argv[0] # get our name because we write ourselves out as a tool later 160 self.myname = sys.argv[0] # get our name because we write ourselves out as a tool later
160 self.pyfile = self.myname # crude but efficient - the cruft won't hurt much 161 self.pyfile = self.myname # crude but efficient - the cruft won't hurt much
161 self.xmlfile = '%s.xml' % self.toolname 162 self.xmlfile = '%s.xml' % self.toolname_sanitized
162 s = open(self.opts.script_path,'r').readlines() 163 s = open(self.opts.script_path,'r').readlines()
163 s = [x.rstrip() for x in s] # remove pesky dos line endings if needed 164 s = [x.rstrip() for x in s] # remove pesky dos line endings if needed
164 self.script = '\n'.join(s) 165 self.script = '\n'.join(s)
165 fhandle,self.sfile = tempfile.mkstemp(prefix=self.toolname,suffix=".%s" % (opts.interpreter)) 166 fhandle,self.sfile = tempfile.mkstemp(prefix=self.toolname_sanitized,suffix=".%s" % (opts.interpreter))
166 tscript = open(self.sfile,'w') # use self.sfile as script source for Popen 167 tscript = open(self.sfile,'w') # use self.sfile as script source for Popen
167 tscript.write(self.script) 168 tscript.write(self.script)
168 tscript.close() 169 tscript.close()
169 self.indentedScript = '\n'.join([' %s' % html_escape(x) for x in s]) # for restructured text in help 170 self.indentedScript = '\n'.join([' %s' % html_escape(x) for x in s]) # for restructured text in help
170 self.escapedScript = '\n'.join([html_escape(x) for x in s]) 171 self.escapedScript = '\n'.join([html_escape(x) for x in s])
171 self.elog = os.path.join(self.opts.output_dir,"%s_error.log" % self.toolname) 172 self.elog = os.path.join(self.opts.output_dir,"%s_error.log" % self.toolname_sanitized)
172 if opts.output_dir: # may not want these complexities 173 if opts.output_dir: # may not want these complexities
173 self.tlog = os.path.join(self.opts.output_dir,"%s_runner.log" % self.toolname) 174 self.tlog = os.path.join(self.opts.output_dir,"%s_runner.log" % self.toolname_sanitized)
174 art = '%s.%s' % (self.toolname,opts.interpreter) 175 art = '%s.%s' % (self.toolname_sanitized,opts.interpreter)
175 artpath = os.path.join(self.opts.output_dir,art) # need full path 176 artpath = os.path.join(self.opts.output_dir,art) # need full path
176 artifact = open(artpath,'w') # use self.sfile as script source for Popen 177 artifact = open(artpath,'w') # use self.sfile as script source for Popen
177 artifact.write(self.script) 178 artifact.write(self.script)
178 artifact.close() 179 artifact.close()
179 self.cl = [] 180 self.cl = []
185 else: 186 else:
186 a('-') # stdin 187 a('-') # stdin
187 for input in opts.input_tab: 188 for input in opts.input_tab:
188 a(input) 189 a(input)
189 if opts.output_tab == 'None': #If tool generates only HTML, set output name to toolname 190 if opts.output_tab == 'None': #If tool generates only HTML, set output name to toolname
190 a(str(self.toolname)+'.out') 191 a(str(self.toolname_sanitized)+'.out')
191 a(opts.output_tab) 192 a(opts.output_tab)
192 for param in opts.additional_parameters: 193 for param in opts.additional_parameters:
193 param, value=param.split(',') 194 param, value=param.split(',')
194 a('--'+param) 195 a('--'+param)
195 a(value) 196 a(value)
196 #print self.cl 197 #print self.cl
197 self.outFormats = opts.output_format 198 self.outFormats = opts.output_format
198 self.inputFormats = [formats for formats in opts.input_formats] 199 self.inputFormats = [formats for formats in opts.input_formats]
199 self.test1Input = '%s_test1_input.xls' % self.toolname 200 self.test1Input = '%s_test1_input.xls' % self.toolname_sanitized
200 self.test1Output = '%s_test1_output.xls' % self.toolname 201 self.test1Output = '%s_test1_output.xls' % self.toolname_sanitized
201 self.test1HTML = '%s_test1_output.html' % self.toolname 202 self.test1HTML = '%s_test1_output.html' % self.toolname_sanitized
202 203
203 def makeXML(self): 204 def makeXML(self):
204 """ 205 """
205 Create a Galaxy xml tool wrapper for the new script as a string to write out 206 Create a Galaxy xml tool wrapper for the new script as a string to write out
206 fixme - use templating or something less fugly than this example of what we produce 207 fixme - use templating or something less fugly than this example of what we produce
272 <help> 273 <help>
273 274
274 %(help)s 275 %(help)s
275 276
276 </help> 277 </help>
277 </tool>""" # needs a dict with toolname, toolid, interpreter, scriptname, command, inputs as a multi line string ready to write, outputs ditto, help ditto 278 </tool>""" # needs a dict with toolname, toolname_sanitized, toolid, interpreter, scriptname, command, inputs as a multi line string ready to write, outputs ditto, help ditto
278 279
279 newCommand=""" 280 newCommand="""
280 %(toolname)s.py --script_path "$runMe" --interpreter "%(interpreter)s" 281 %(toolname_sanitized)s.py --script_path "$runMe" --interpreter "%(interpreter)s"
281 --tool_name "%(toolname)s" %(command_inputs)s %(command_outputs)s """ 282 --tool_name "%(toolname)s" %(command_inputs)s %(command_outputs)s """
282 # may NOT be an input or htmlout - appended later 283 # may NOT be an input or htmlout - appended later
283 tooltestsTabOnly = """ 284 tooltestsTabOnly = """
284 <tests> 285 <tests>
285 <test> 286 <test>
353 else: 354 else:
354 xdict['command_inputs'] = '' # assume no input - eg a random data generator 355 xdict['command_inputs'] = '' # assume no input - eg a random data generator
355 xdict['inputs'] = '' 356 xdict['inputs'] = ''
356 # I find setting the job name not very logical. can be changed in workflows anyway. xdict['inputs'] += '<param name="job_name" type="text" label="Supply a name for the outputs to remind you what they contain" value="%s"/> \n' % self.toolname 357 # I find setting the job name not very logical. can be changed in workflows anyway. xdict['inputs'] += '<param name="job_name" type="text" label="Supply a name for the outputs to remind you what they contain" value="%s"/> \n' % self.toolname
357 xdict['toolname'] = self.toolname 358 xdict['toolname'] = self.toolname
359 xdict['toolname_sanitized'] = self.toolname_sanitized
358 xdict['toolid'] = self.toolid 360 xdict['toolid'] = self.toolid
359 xdict['interpreter'] = self.opts.interpreter 361 xdict['interpreter'] = self.opts.interpreter
360 xdict['scriptname'] = self.sfile 362 xdict['scriptname'] = self.sfile
361 if self.opts.make_HTML: 363 if self.opts.make_HTML:
362 xdict['command_outputs'] += ' --output_dir "$html_file.files_path" --output_html "$html_file" --make_HTML "yes"' 364 xdict['command_outputs'] += ' --output_dir "$html_file.files_path" --output_html "$html_file" --make_HTML "yes"'
363 xdict['outputs'] += ' <data format="html" name="html_file"/>\n' 365 xdict['outputs'] += ' <data format="html" name="html_file"/>\n'
364 else: 366 else:
365 xdict['command_outputs'] += ' --output_dir "./"' 367 xdict['command_outputs'] += ' --output_dir "./"'
366 #print self.opts.output_tab 368 #print self.opts.output_tab
367 if not self.opts.output_tab: 369 if self.opts.output_tab!="None":
368 xdict['command_outputs'] += ' --output_tab "$tab_file"' 370 xdict['command_outputs'] += ' --output_tab "$tab_file"'
369 xdict['outputs'] += ' <data format="%s" name="tab_file"/>\n' % self.outFormats 371 xdict['outputs'] += ' <data format="%s" name="tab_file"/>\n' % self.outFormats
370 xdict['command'] = newCommand % xdict 372 xdict['command'] = newCommand % xdict
371 #print xdict['outputs'] 373 #print xdict['outputs']
372 xmls = newXML % xdict 374 xmls = newXML % xdict
378 380
379 381
380 def makeTooltar(self): 382 def makeTooltar(self):
381 """ 383 """
382 a tool is a gz tarball with eg 384 a tool is a gz tarball with eg
383 /toolname/tool.xml /toolname/tool.py /toolname/test-data/test1_in.foo ... 385 /toolname_sanitized/tool.xml /toolname_sanitized/tool.py /toolname_sanitized/test-data/test1_in.foo ...
384 """ 386 """
385 retval = self.run() 387 retval = self.run()
386 if retval: 388 if retval:
387 print >> sys.stderr,'## Run failed. Cannot build yet. Please fix and retry' 389 print >> sys.stderr,'## Run failed. Cannot build yet. Please fix and retry'
388 sys.exit(1) 390 sys.exit(1)
389 tdir = self.toolname 391 tdir = self.toolname_sanitized
390 os.mkdir(tdir) 392 os.mkdir(tdir)
391 self.makeXML() 393 self.makeXML()
392 if self.opts.make_HTML: 394 if self.opts.make_HTML:
393 if self.opts.help_text: 395 if self.opts.help_text:
394 hlp = open(self.opts.help_text,'r').read() 396 hlp = open(self.opts.help_text,'r').read()
410 shutil.copyfile(self.opts.output_tab,os.path.join(testdir,self.test1Output)) 412 shutil.copyfile(self.opts.output_tab,os.path.join(testdir,self.test1Output))
411 if self.opts.make_HTML: 413 if self.opts.make_HTML:
412 shutil.copyfile(self.opts.output_html,os.path.join(testdir,self.test1HTML)) 414 shutil.copyfile(self.opts.output_html,os.path.join(testdir,self.test1HTML))
413 if self.opts.output_dir: 415 if self.opts.output_dir:
414 shutil.copyfile(self.tlog,os.path.join(testdir,'test1_out.log')) 416 shutil.copyfile(self.tlog,os.path.join(testdir,'test1_out.log'))
415 outpif = '%s.py' % self.toolname # new name 417 outpif = '%s.py' % self.toolname_sanitized # new name
416 outpiname = os.path.join(tdir,outpif) # path for the tool tarball 418 outpiname = os.path.join(tdir,outpif) # path for the tool tarball
417 pyin = os.path.basename(self.pyfile) # our name - we rewrite ourselves (TM) 419 pyin = os.path.basename(self.pyfile) # our name - we rewrite ourselves (TM)
418 notes = ['# %s - a self annotated version of %s generated by running %s\n' % (outpiname,pyin,pyin),] 420 notes = ['# %s - a self annotated version of %s generated by running %s\n' % (outpiname,pyin,pyin),]
419 notes.append('# to make a new Galaxy tool called %s\n' % self.toolname) 421 notes.append('# to make a new Galaxy tool called %s\n' % self.toolname)
420 notes.append('# User %s at %s\n' % (self.opts.user_email,timenow())) 422 notes.append('# User %s at %s\n' % (self.opts.user_email,timenow()))
428 if not os.path.exists(stname): 430 if not os.path.exists(stname):
429 shutil.copyfile(self.sfile, stname) 431 shutil.copyfile(self.sfile, stname)
430 xtname = os.path.join(tdir,self.xmlfile) 432 xtname = os.path.join(tdir,self.xmlfile)
431 if not os.path.exists(xtname): 433 if not os.path.exists(xtname):
432 shutil.copyfile(self.xmlfile,xtname) 434 shutil.copyfile(self.xmlfile,xtname)
433 tarpath = "%s.gz" % self.toolname 435 tarpath = "%s.gz" % self.toolname_sanitized
434 tar = tarfile.open(tarpath, "w:gz") 436 tar = tarfile.open(tarpath, "w:gz")
435 tar.add(tdir,arcname=self.toolname) 437 tar.add(tdir,arcname=self.toolname_sanitized)
436 tar.close() 438 tar.close()
437 shutil.copyfile(tarpath,self.opts.new_tool) 439 shutil.copyfile(tarpath,self.opts.new_tool)
438 shutil.rmtree(tdir) 440 shutil.rmtree(tdir)
439 ## TODO: replace with optional direct upload to local toolshed? 441 ## TODO: replace with optional direct upload to local toolshed?
440 return retval 442 return retval