comparison rgToolFactory.py @ 9:4b62ea84c318 draft

Uploaded
author fubar
date Thu, 01 Jan 2015 21:54:37 -0500
parents ef0297b352d8
children
comparison
equal deleted inserted replaced
8:4e4f094c338c 9:4b62ea84c318
111 111
112 class ScriptRunner: 112 class ScriptRunner:
113 """class is a wrapper for an arbitrary script 113 """class is a wrapper for an arbitrary script
114 """ 114 """
115 115
116 def __init__(self,opts=None,treatbashSpecial=True): 116 def __init__(self,opts=None):
117 """ 117 """
118 cleanup inputs, setup some outputs 118 cleanup inputs, setup some outputs
119 119
120 """ 120 """
121 self.useGM = cmd_exists('gm') 121 self.useGM = cmd_exists('gm')
122 self.useIM = cmd_exists('convert') 122 self.useIM = cmd_exists('convert')
123 self.useGS = cmd_exists('gs') 123 self.useGS = cmd_exists('gs')
124 self.temp_warned = False # we want only one warning if $TMP not set 124 self.temp_warned = False # we want only one warning if $TMP not set
125 self.treatbashSpecial = treatbashSpecial
126 if opts.output_dir: # simplify for the tool tarball 125 if opts.output_dir: # simplify for the tool tarball
127 os.chdir(opts.output_dir) 126 os.chdir(opts.output_dir)
128 self.thumbformat = 'png' 127 self.thumbformat = 'png'
129 self.opts = opts 128 self.opts = opts
130 self.toolname = re.sub('[^a-zA-Z0-9_]+', '', opts.tool_name) # a sanitizer now does this but.. 129 self.toolname = re.sub('[^a-zA-Z0-9_]+', '', opts.tool_name) # a sanitizer now does this but..
147 art = '%s.%s' % (self.toolname,opts.interpreter) 146 art = '%s.%s' % (self.toolname,opts.interpreter)
148 artpath = os.path.join(self.opts.output_dir,art) # need full path 147 artpath = os.path.join(self.opts.output_dir,art) # need full path
149 artifact = open(artpath,'w') # use self.sfile as script source for Popen 148 artifact = open(artpath,'w') # use self.sfile as script source for Popen
150 artifact.write(self.script) 149 artifact.write(self.script)
151 artifact.close() 150 artifact.close()
152 self.cl = []
153 self.html = [] 151 self.html = []
154 a = self.cl.append 152 self.cl = (opts.interpreter,self.sfile)
155 a(opts.interpreter)
156 # cannot use pipe input on test - change so always eg Rscript myscript.R
157 #if self.treatbashSpecial and opts.interpreter in ['bash','sh']:
158 # a(self.sfile)
159 #else:
160 # a('-') # stdin
161 #a(opts.input_tab)
162 #a(opts.output_tab)
163 a(self.sfile)
164 self.outFormats = 'tabular' # TODO make this an option at tool generation time 153 self.outFormats = 'tabular' # TODO make this an option at tool generation time
165 self.inputFormats = 'tabular' # TODO make this an option at tool generation time 154 self.inputFormats = 'tabular' # TODO make this an option at tool generation time
166 self.test1Input = '%s_test1_input.xls' % self.toolname 155 self.test1Input = '%s_test1_input.xls' % self.toolname
167 self.test1Output = '%s_test1_output.xls' % self.toolname 156 self.test1Output = '%s_test1_output.xls' % self.toolname
168 self.test1HTML = '%s_test1_output.html' % self.toolname 157 self.test1HTML = '%s_test1_output.html' % self.toolname
543 def run(self): 532 def run(self):
544 """ 533 """
545 scripts must be small enough not to fill the pipe! 534 scripts must be small enough not to fill the pipe!
546 """ 535 """
547 my_env = os.environ.copy() 536 my_env = os.environ.copy()
548 if self.treatbashSpecial and self.opts.interpreter in ['bash','sh']: 537 if self.opts.output_dir:
549 retval = self.runBash() 538 ste = open(self.elog,'w')
550 else: 539 sto = open(self.tlog,'w')
551 if self.opts.output_dir: 540 sto.write('## Toolfactory running %s as %s script\n' % (self.toolname,self.opts.interpreter))
552 ste = open(self.elog,'w') 541 sto.flush()
553 sto = open(self.tlog,'w') 542 p = subprocess.Popen(self.cl,shell=False,stdout=sto,stderr=ste,cwd=self.opts.output_dir,env=my_env)
554 sto.write('## Toolfactory running %s as %s script\n' % (self.toolname,self.opts.interpreter))
555 sto.flush()
556 p = subprocess.Popen(self.cl,shell=False,stdout=sto,stderr=ste,cwd=self.opts.output_dir,env=my_env)
557 else:
558 p = subprocess.Popen(self.cl,shell=False,cwd=self.opts.output_dir,env=my_env)
559 # p.stdin.write(self.script)
560 #print >> p.stdin, self.script
561 #p.stdin.close()
562 retval = p.wait() 543 retval = p.wait()
563 if self.opts.output_dir: 544 sto.close()
564 sto.close() 545 ste.close()
565 ste.close() 546 # get stderr, allowing for case where it's very large
566 # get stderr, allowing for case where it's very large 547 tmp_stderr = open( self.elog, 'rb' )
567 tmp_stderr = open( self.elog, 'rb' ) 548 stderr = ''
568 stderr = '' 549 try:
569 try: 550 while True:
570 while True: 551 stderr += tmp_stderr.read( buffsize )
571 stderr += tmp_stderr.read( buffsize ) 552 if not stderr or len( stderr ) % buffsize != 0:
572 if not stderr or len( stderr ) % buffsize != 0: 553 break
573 break 554 except OverflowError:
574 except OverflowError: 555 pass
575 pass 556 tmp_stderr.close()
576 tmp_stderr.close() 557 else:
577 if self.opts.make_HTML: 558 p = subprocess.Popen(self.cl,shell=False,env=my_env)
578 self.makeHtml() 559 retval = p.wait()
560 if self.opts.make_HTML:
561 self.makeHtml()
579 return retval 562 return retval
580 563
581 def old_run(self): 564
582 """ 565 def remove_me_runBash(self):
583 can't use pipe as stdin on test. go figure
584 scripts must be small enough not to fill the pipe!
585 """
586 my_env = os.environ.copy()
587 if self.treatbashSpecial and self.opts.interpreter in ['bash','sh']:
588 retval = self.runBash()
589 else:
590 if self.opts.output_dir:
591 ste = open(self.elog,'w')
592 sto = open(self.tlog,'w')
593 sto.write('## Toolfactory running %s as %s script\n' % (self.toolname,self.opts.interpreter))
594 sto.flush()
595 p = subprocess.Popen(self.cl,shell=False,stdout=sto,stderr=ste,stdin=subprocess.PIPE,cwd=self.opts.output_dir,env=my_env)
596 else:
597 p = subprocess.Popen(self.cl,shell=False,stdin=subprocess.PIPE,env=my_env)
598 # p.stdin.write(self.script)
599 print >> p.stdin, self.script
600 p.stdin.close()
601 retval = p.wait()
602 if self.opts.output_dir:
603 sto.close()
604 ste.close()
605 # get stderr, allowing for case where it's very large
606 tmp_stderr = open( self.elog, 'rb' )
607 stderr = ''
608 try:
609 while True:
610 stderr += tmp_stderr.read( buffsize )
611 if not stderr or len( stderr ) % buffsize != 0:
612 break
613 except OverflowError:
614 pass
615 tmp_stderr.close()
616 if self.opts.make_HTML:
617 self.makeHtml()
618 return retval
619
620 def runBash(self):
621 """ 566 """
622 cannot use - for bash so use self.sfile 567 cannot use - for bash so use self.sfile
623 """ 568 """
624 if self.opts.output_dir: 569 if self.opts.output_dir:
625 s = '## Toolfactory generated command line = %s\n' % ' '.join(self.cl) 570 s = '## Toolfactory generated command line = %s\n' % ' '.join(self.cl)
643 if not stderr or len( stderr ) % buffsize != 0: 588 if not stderr or len( stderr ) % buffsize != 0:
644 break 589 break
645 except OverflowError: 590 except OverflowError:
646 pass 591 pass
647 tmp_stderr.close() 592 tmp_stderr.close()
648 if self.opts.make_HTML:
649 self.makeHtml()
650 return retval 593 return retval
651 594
652 595
653 def main(): 596 def main():
654 u = """ 597 u = """
655 This is a Galaxy wrapper. It expects to be called by a special purpose tool.xml as: 598 This is a Galaxy wrapper. It expects to be called by a special purpose tool.xml as (eg):
656 <command interpreter="python">rgBaseScriptWrapper.py --script_path "$scriptPath" --tool_name "foo" --interpreter "Rscript" 599 <command interpreter="python">rgToolFactory.py --script_path "$scriptPath" --tool_name "foo" --interpreter "Rscript"
657 </command> 600 </command>
601 The tool writes a script to a scriptPath using a configfile.
602 Some things in the script are templates.
603 The idea here is that depending on how this code is called, it uses the specified interpreter
604 to run a (hopefully correct) script/template. Optionally generates a clone of itself
605 which will run that same script/template as a toolshed repository tarball for uploading to a toolshed.
606 There's now an updated version which allows arbitrary parameters.
607 And so it goes.
658 """ 608 """
659 op = optparse.OptionParser() 609 op = optparse.OptionParser()
660 a = op.add_option 610 a = op.add_option
661 a('--script_path',default=None) 611 a('--script_path',default=None)
662 a('--tool_name',default=None) 612 a('--tool_name',default=None)