# HG changeset patch
# User ross lazarus ross.lazarus@gmail.com
# Date 1338631331 -36000
# Node ID 220885b2d7eebaac73d5f38449bb929ca08004dd
# Parent 7221619caefa0554e01f69d19af7d407b626fec2
End to end test works. Add tests next
diff -r 7221619caefa -r 220885b2d7ee rgToolFactory.py
--- a/rgToolFactory.py Sat Jun 02 10:43:08 2012 +1000
+++ b/rgToolFactory.py Sat Jun 02 20:02:11 2012 +1000
@@ -30,26 +30,14 @@
import optparse
import tarfile
import re
+import shutil
+
progname = os.path.split(sys.argv[0])[1]
myversion = 'V000.1 May 2012'
verbose = False
debug = False
-galhtmlprefix = """
-
-
-
-
-
-
-
-
-\n"""
-
def timenow():
"""return current time as a string
"""
@@ -97,19 +85,22 @@
__cr____cn__sessionInfo()
__cr____cn__
"""
- self.myname = sys.argv[0] # get our name because we write ourselves out as a tool later
+ if opts.output_dir: # simplify for the tool tarball
+ os.chdir(opts.output_dir)
self.thumbformat = 'jpg'
self.opts = opts
self.toolname = re.sub('[^a-zA-Z0-9_]+', '', opts.tool_name)
+ self.toolid = self.toolname
s = open(self.opts.script_path,'r').read()
self.script = restore_text(s)
- self.pyfile = self.myname
- self.xmlfile = '%s.xml' % os.path.splitext(self.pyfile)[0] # punt
+ self.myname = sys.argv[0] # get our name because we write ourselves out as a tool later
+ self.pyfile = self.myname # crude but efficient - the cruft won't hurt much
+ self.xmlfile = '%s.xml' % self.toolname
self.sfile = '%s.%s' % (self.toolname,opts.interpreter)
localscript = open(self.sfile,'w')
localscript.write(self.script)
localscript.close()
- if opts.output_dir or self.opts.makeTool: # may not want these complexities if a simple script
+ if opts.output_dir or self.opts.make_Tool: # may not want these complexities if a simple script
self.tlog = os.path.join(opts.output_dir,"%s_runner.log" % self.toolname)
artifactpath = os.path.join(opts.output_dir,'%s_run.script' % self.toolname)
artifact = open(artifactpath,'w')
@@ -123,6 +114,77 @@
a('-') # use stdin
a(opts.input_tab)
a(opts.output_tab)
+ self.outFormats = 'tabular' # TODO make this an option at tool generation time
+ self.inputFormats = 'tabular' # TODO make this an option at tool generation time
+
+
+ def makeXML(self):
+ """
+ Create a Galaxy xml tool wrapper for the new script as a string to write out
+ """
+ newXML="""
+ %(tooldesc)s
+ %(command)s
+
+ %(inputs)s
+
+
+ %(outputs)s
+
+
+ %(help)s
+
+
+
+ %(script)s
+
+
+ """ # needs a dict with toolname, toolid, interpreter, scriptname, command, inputs as a multi line string ready to write, outputs ditto, help ditto
+
+ newCommand="""
+ %(toolname)s.py --script_path "$runMe" --interpreter "%(interpreter)s"
+ --tool_name "%(toolname)s" %(command_inputs)s %(command_outputs)s
+ """ # may NOT be an input or htmlout
+
+ xdict = {}
+ xdict['script'] = self.script # we pass this as a configfile because it's less painful that galaxy_tool_data_dir
+ # embed script in tool - remove dependence on something else outside in the wilds
+ if self.opts.help_text:
+ h = open(self.opts.help_text,'r').read()
+ xdict['help'] = restore_text(h)
+ else:
+ xdict['help'] = 'Please ask the tool author for help as none was supplied at tool generation'
+ if self.opts.tool_desc:
+ xdict['tooldesc'] = '%s ' % self.opts.tool_desc
+ else:
+ xdict['tooldesc'] = ''
+ xdict['command_outputs'] = '' # will probably be some!
+ xdict['outputs'] = '' # will probably be some!
+ if self.opts.input_tab:
+ xdict['command_inputs'] = '--input_tab "$input1"'
+ xdict['inputs'] = ' ' % self.inputFormats
+ else:
+ xdict['command_inputs'] = '' # assume no input - eg a random data generator
+ xdict['inputs'] = ''
+ xdict['inputs'] += ' \n' % self.toolname
+ xdict['toolname'] = self.toolname
+ xdict['toolid'] = self.toolid
+ xdict['interpreter'] = self.opts.interpreter
+ xdict['scriptname'] = self.sfile
+ if self.opts.make_HTML:
+ xdict['command_outputs'] += '--output_dir "$html_file.files_path" --output_html "$html_file"'
+ xdict['outputs'] += ' \n'
+ if self.opts.output_tab:
+ xdict['command_outputs'] += '--output_tab "$tab_file"'
+ xdict['outputs'] += ' \n' % self.outFormats
+ xdict['command'] = newCommand % xdict
+ xmls = newXML % xdict
+ xf = open(self.xmlfile,'w')
+ xf.write(xmls)
+ xf.write('\n')
+ xf.close()
+ # ready for the tarball
+
def makeTooltar(self):
"""
@@ -133,13 +195,19 @@
if retval:
print >> sys.stderr,'## Run failed. Cannot build yet. Please fix and retry'
sys.exit(1)
- tarpath = os.path.join(self.opts.output_dir,"%s.gz" % self.toolname)
+ self.makeXML()
+ tdir = self.toolname
+ os.mkdir(tdir)
+ shutil.copyfile(self.xmlfile,os.path.join(tdir,self.xmlfile))
+ shutil.copyfile(self.pyfile,os.path.join(tdir,'%s.py' % self.toolname))
+ shutil.copyfile(self.sfile,os.path.join(tdir,self.sfile))
+ tarpath = "%s.gz" % self.toolname
tar = tarfile.open(tarpath, "w:gz")
- tar.add(self.xmlfile,arcname='%s.xml' % self.toolname)
- tar.add(self.pyfile,arcname=os.path.basename(self.pyfile))
- tar.add(self.sfile,arcname=self.sfile)
+ tar.add(tdir,arcname=self.toolname)
tar.close()
- self.makeHtml()
+ shutil.rmtree(tdir)
+ self.makeHtml() # call this to return the new gzip inside the autogenerated html file
+ ## TODO: replace with optional direct upload to local toolshed?
return retval
def compressPDF(self,inpdf=None,thumbformat='png'):
@@ -181,17 +249,32 @@
return size
def makeHtml(self):
- """
- """
- flist = os.listdir(self.opts.output_dir)
- flist = [x for x in flist if x <> 'Rplots.pdf']
- flist.sort()
- html = [galhtmlprefix % progname,]
- html.append('Galaxy %s outputs run at %s \n' % (self.toolname,timenow()))
- fhtml = []
- if len(flist) > 0:
- html.append('\n')
- for fname in flist:
+ """ Create an HTML file content to list all the artefacts found in the output_dir
+ """
+
+ galhtmlprefix = """
+
+
+
+
+
+
+
+
+ \n"""
+
+ flist = os.listdir(self.opts.output_dir)
+ flist = [x for x in flist if x <> 'Rplots.pdf']
+ flist.sort()
+ html = [galhtmlprefix % progname,]
+ html.append('Galaxy %s outputs run at %s \n' % (self.toolname,timenow()))
+ fhtml = []
+ if len(flist) > 0:
+ html.append('\n')
+ for fname in flist:
dname,e = os.path.splitext(fname)
sfsize = self.getfSize(fname,self.opts.output_dir)
if e.lower() == '.pdf' : # compress and make a thumbnail
@@ -204,32 +287,31 @@
fhtml.append('%s %s ' % (fname,fname,sfsize))
else:
fhtml.append('%s %s ' % (fname,fname,sfsize))
- html.append('
\n')
- if len(fhtml) > 0:
- fhtml.insert(0,'')
- html += fhtml # add all non-pdf files to the end of the display
- else:
- html.append('### Error - %s returned no files - please confirm that parameters are sane' % self.opts.interpreter)
- html.append('%s log follows below \n' % self.opts.interpreter)
- rlog = open(self.tlog,'r').readlines()
- html += rlog
- html.append('%s CL = %s\n' % (self.toolname,' '.join(sys.argv)))
- html.append('CL = %s\n' % (' '.join(self.cl)))
- html.append(' \n')
- html.append(galhtmlattr % (progname,timenow()))
- html.append(galhtmlpostfix)
- htmlf = file(self.opts.output_html,'w')
- htmlf.write('\n'.join(html))
- htmlf.write('\n')
- htmlf.close()
- self.html = html
+ html.append('
\n')
+ if len(fhtml) > 0:
+ fhtml.insert(0,'')
+ html += fhtml # add all non-pdf files to the end of the display
+ else:
+ html.append('### Error - %s returned no files - please confirm that parameters are sane' % self.opts.interpreter)
+ html.append('%s log follows below \n' % self.opts.interpreter)
+ rlog = open(self.tlog,'r').readlines()
+ html += rlog
+ html.append('%s CL = %s \n' % (self.toolname,' '.join(sys.argv)))
+ html.append(' \n')
+ html.append(galhtmlattr % (progname,timenow()))
+ html.append(galhtmlpostfix)
+ htmlf = file(self.opts.output_html,'w')
+ htmlf.write('\n'.join(html))
+ htmlf.write('\n')
+ htmlf.close()
+ self.html = html
def run(self):
"""
"""
- if self.opts.output_dir or self.opts.makeTool:
+ if self.opts.output_dir or self.opts.make_Tool:
sto = open(self.tlog,'w')
p = subprocess.Popen(' '.join(self.cl),shell=True,stdout=sto,stderr=sto,stdin=subprocess.PIPE,cwd=self.opts.output_dir)
else:
@@ -237,7 +319,7 @@
p.stdin.write(self.script)
p.stdin.close()
retval = p.wait()
- if self.opts.output_dir or self.opts.makeTool:
+ if self.opts.make_HTML or self.opts.make_Tool:
sto.close()
self.makeHtml()
return retval
@@ -256,11 +338,14 @@
a('--interpreter',default=None)
a('--output_dir',default=None)
a('--output_html',default=None)
- a('--input_tab',default='NONE')
- a('--output_tab',default='NONE')
+ a('--input_tab',default=None)
+ a('--output_tab',default=None)
a('--user_email',default=None)
a('--bad_user',default=None)
- a('--makeTool',default=None)
+ a('--make_Tool',default=None)
+ a('--make_HTML',default=None)
+ a('--help_text',default=None)
+ a('--tool_desc',default=None)
opts, args = op.parse_args()
assert not opts.bad_user,'%s is NOT authorized to use this tool. Please ask your friendly admin' % opts.bad_user
assert opts.tool_name,'## Tool Factory expects a tool name - eg --tool_name=DESeq'
@@ -272,7 +357,7 @@
except:
pass
r = ScriptRunner(opts)
- if opts.makeTool:
+ if opts.make_Tool:
retcode = r.makeTooltar()
else:
retcode = r.run()
diff -r 7221619caefa -r 220885b2d7ee rgToolFactory.xml
--- a/rgToolFactory.xml Sat Jun 02 10:43:08 2012 +1000
+++ b/rgToolFactory.xml Sat Jun 02 20:02:11 2012 +1000
@@ -5,15 +5,20 @@
rgToolFactory.py --bad_user $__user_email__
#else:
rgToolFactory.py --script_path "$runme" --interpreter "$interpreter"
- --tool_name "$tool_name" --input_tab "$input1" --user_email "${__user_email__}"
- #if $makeHTML.value=="yes" or $makeTool.value=="yes":
+ --tool_name "$tool_name" --input_tab "$input1"
+ #if $make_HTML.value=="yes" or $factory.make_Tool=="yes":
--output_dir "$html_file.files_path" --output_html "$html_file"
#end if
- #if $makeTAB.value=="yes":
+ #if $make_HTML.value=="yes":
+ --make_HTML "yes"
+ #end if
+ #if $make_TAB.value=="yes":
--output_tab "$tab_file"
#end if
- #if $makeTool.value=="yes":
- --makeTool "$makeTool"
+ #if $factory.make_Tool=="yes":
+ --make_Tool "$factory.make_Tool"
+ --help_text "$helpme"
+ --tool_desc "$factory.tool_desc"
#end if
#end if
@@ -21,17 +26,28 @@
-
+
+
Yes
Not yet, it's still broken
-
-
+
+
+
+
+
+
+
+
+
+
+
+
Yes
No
-
Yes
No
@@ -42,20 +58,32 @@
perl
+ help="Expect FIRST CL parameter = the optional input tabular file path (or NONE if not specified). Ensure your script writes tabular output to the path in the SECOND command line parameter it gets.">
+
+
+
+
+
+
- makeTAB=="yes"
+ make_TAB=="yes"
- makeHTML=="yes" or makeTool=="yes"
+ make_HTML=="yes" or make_Tool=="yes"
${dynScript}
+#if $factory.make_Tool == "yes":
+
+$factory.help_text
+
+#end if
+
**What it does**