# HG changeset patch # User fubar # Date 1598766327 14400 # Node ID bf432f4486c730fbc68fa6414f2d4d03708a8c11 # Parent 35a912ce0c83b80d2a2cf73a94cc30eb6e460ce3 Uploaded diff -r 35a912ce0c83 -r bf432f4486c7 toolfactory/rgToolFactory2.py --- a/toolfactory/rgToolFactory2.py Thu Aug 27 23:11:01 2020 -0400 +++ b/toolfactory/rgToolFactory2.py Sun Aug 30 01:45:27 2020 -0400 @@ -23,7 +23,6 @@ # Be simpler to write the tool, then run it with planemo and soak up the test outputs. - import argparse import logging import os @@ -47,7 +46,7 @@ debug = True toolFactoryURL = "https://github.com/fubar2/toolfactory" ourdelim = "~~~" -ALOT = 10000000 # srsly. command or test overrides use read() so just in case +ALOT = 10000000 # srsly. command or test overrides use read() so just in case STDIOXML = """ """ @@ -172,15 +171,13 @@ ], 'args.parampass must be "0","positional" or "argparse"' self.tool_name = re.sub("[^a-zA-Z0-9_]+", "", args.tool_name) self.tool_id = self.tool_name - self.tool = gxt.Tool( + self.newtool = gxt.Tool( self.args.tool_name, self.tool_id, self.args.tool_version, self.args.tool_desc, - FAKEEXE, + FAKEEXE, ) - if self.args.script_path: - self.tool.interpreter = self.executeme self.tooloutdir = "tfout" self.repdir = "TF_run_report_tempdir" self.testdir = os.path.join(self.tooloutdir, "test-data") @@ -205,7 +202,7 @@ self.test_override = [x.rstrip() for x in stos] else: self.test_override = None - if self.args.cl_prefix: # DIY CL start + if self.args.cl_prefix: # DIY CL start clp = self.args.cl_prefix.split(" ") for c in clp: aCL(c) @@ -215,6 +212,7 @@ if self.args.script_path: aCL(self.executeme) aCL(self.sfile) + aXCL(self.executeme) aXCL("$runme") else: aCL(self.executeme) # this little CL will just run @@ -223,12 +221,13 @@ if self.args.script_path: aCL(self.executeme) aCL(self.sfile) + aXCL(self.executeme) aXCL("$runme") else: aCL(self.executeme) # this little CL will just run aXCL(self.executeme) - self.elog = os.path.join(self.repdir,"%s_error_log.txt" % self.tool_name) - self.tlog = os.path.join(self.repdir,"%s_runner_log.txt" % self.tool_name) + self.elog = os.path.join(self.repdir, "%s_error_log.txt" % self.tool_name) + self.tlog = os.path.join(self.repdir, "%s_runner_log.txt" % self.tool_name) if self.args.parampass == "0": self.clsimple() @@ -412,15 +411,21 @@ self.toutputs.append(aparm) usetest = None ld = None - if test > '': - if test.startswith('diff'): - usetest = 'diff' - if test.split(':')[1].isdigit: - ld = int(test.split(':')[1]) + if test > "": + if test.startswith("diff"): + usetest = "diff" + if test.split(":")[1].isdigit: + ld = int(test.split(":")[1]) else: usetest = test - tp = gxtp.TestOutput(name=newcl, value="%s_sample" % newcl, format=newfmt, - compare=usetest, lines_diff=ld, delta=None,) + tp = gxtp.TestOutput( + name=newcl, + value="%s_sample" % newcl, + format=newfmt, + compare=usetest, + lines_diff=ld, + delta=None, + ) self.testparam.append(tp) for p in self.infiles: newname = p[ICLPOS] @@ -526,22 +531,28 @@ Hmmm. How to get the command line into correct order... """ if self.command_override: - self.tool.command_line_override = self.command_override # config file + self.newtool.command_line_override = self.command_override # config file else: - self.tool.command_line_override = self.xmlcl - # if self.args.interpreter_name: - # self.tool.interpreter = self.args.interpreter_name + self.newtool.command_line_override = self.xmlcl if self.args.help_text: helptext = open(self.args.help_text, "r").readlines() - helptext = [html_escape(x) for x in helptext] - self.tool.help = "".join([x for x in helptext]) + safertext = [html_escape(x) for x in helptext] + if self.args.script_path: + scrpt = self.script.split('\n') + scrpt.append("```\n") + if len(scrpt) > 300: + safertext = safertext + scrpt[:100] + ['>500 lines - stuff deleted','......'] + scrpt[-100:] + else: + safertext = safertext + scrpt + safertext.append("\n```") + self.newtool.help = "".join([x for x in safertext]) else: - self.tool.help = ( + self.newtool.help = ( "Please ask the tool author (%s) for help \ as none was supplied at tool generation\n" % (self.args.user_email) ) - self.tool.version_command = None # do not want + self.newtool.version_command = None # do not want requirements = gxtp.Requirements() if self.args.packages: for d in self.args.packages.split(","): @@ -550,41 +561,43 @@ else: packg = d ver = "" - requirements.append(gxtp.Requirement("package", packg.strip(), ver.strip())) - self.tool.requirements = requirements + requirements.append( + gxtp.Requirement("package", packg.strip(), ver.strip()) + ) + self.newtool.requirements = requirements if self.args.parampass == "0": self.doNoXMLparam() else: self.doXMLparam() - self.tool.outputs = self.toutputs - self.tool.inputs = self.tinputs - if ( - self.args.script_path - ): + self.newtool.outputs = self.toutputs + self.newtool.inputs = self.tinputs + if self.args.script_path: configfiles = gxtp.Configfiles() configfiles.append(gxtp.Configfile(name="runme", text=self.script)) - self.tool.configfiles = configfiles + self.newtool.configfiles = configfiles tests = gxtp.Tests() test_a = gxtp.Test() for tp in self.testparam: test_a.append(tp) tests.append(test_a) - self.tool.tests = tests - self.tool.add_comment( + self.newtool.tests = tests + self.newtool.add_comment( "Created by %s at %s using the Galaxy Tool Factory." % (self.args.user_email, timenow()) ) - self.tool.add_comment("Source in git at: %s" % (toolFactoryURL)) - self.tool.add_comment( + self.newtool.add_comment("Source in git at: %s" % (toolFactoryURL)) + self.newtool.add_comment( "Cite: Creating re-usable tools from scripts doi: \ 10.1093/bioinformatics/bts573" ) - exml0 = self.tool.export() + exml0 = self.newtool.export() exml = exml0.replace(FAKEEXE, "") # temporary work around until PR accepted - if self.test_override: # cannot do this inside galaxyxml as it expects lxml objects for tests - part1 = exml.split('')[0] - part2 = exml.split('')[1] - fixed = '%s\n%s\n%s' % (part1,self.test_override,part2) + if ( + self.test_override + ): # cannot do this inside galaxyxml as it expects lxml objects for tests + part1 = exml.split("")[0] + part2 = exml.split("")[1] + fixed = "%s\n%s\n%s" % (part1, self.test_override, part2) exml = fixed xf = open("%s.xml" % self.tool_name, "w") xf.write(exml) @@ -592,63 +605,14 @@ xf.close() # ready for the tarball - def makeTool(self): - """write xmls and samples into place - """ - self.makeXML() - if self.args.script_path: - stname = os.path.join(self.tooloutdir, "%s" % (self.sfile)) - if not os.path.exists(stname): - shutil.copyfile(self.sfile, stname) - xreal = "%s.xml" % self.tool_name - xout = os.path.join(self.tooloutdir, xreal) - shutil.copyfile(xreal, xout) - for p in self.infiles: - pth = p[IPATHPOS] - dest = os.path.join(self.testdir, "%s_sample" % p[ICLPOS]) - shutil.copyfile(pth, dest) - - def makeToolTar(self): - self.newtarpath = "toolfactory_%s.tgz" % self.tool_name - tf = tarfile.open(self.newtarpath, "w:gz") - tf.add(name=self.tooloutdir, arcname=self.tool_name) - tf.close() - shutil.copyfile(self.newtarpath, self.args.new_tool) - if os.path.exists(self.tlog) and os.stat(self.tlog).st_size > 0: - shutil.copyfile( - self.tlog, os.path.join(self.tooloutdir, "test1_log_outfiletxt") - ) - - def moveRunOutputs(self): - """need to move files into toolfactory collection after any run - planemo or not - """ - for p in self.outfiles: - naym = p[ONAMEPOS] - src = os.path.join(self.tooloutdir,naym) - if os.path.isfile(src): - dest = os.path.join(self.testdir, "%s_sample" % naym) - shutil.copyfile(naym, dest) - else: - print('### problem - output file %s not found in tooloutdir %s' % (src,self.tooloutdir)) - with os.scandir(self.tooloutdir) as outs: - for entry in outs: - if not entry.is_file() or entry.name.startswith('.'): - continue - if "." in entry.name: - nayme,ext = os.path.splitext(entry.name) - else: - ext = ".txt" - ofn = "%s%s" % (entry.name.replace(".", "_"), ext) - dest = os.path.join(self.repdir, ofn) - src = os.path.join(self.tooloutdir,entry.name) - shutil.copyfile(src, dest) - def run(self): """ - + generate test outputs by running a command line + won't work if command or test override in play - planemo is the + easiest way to generate test outputs for that case so is + automagically selected """ s = "run cl=%s" % str(self.cl) - logging.debug(s) scl = " ".join(self.cl) err = None @@ -703,12 +667,14 @@ planemo shed_update --check_diff --shed_target testtoolshed """ if os.path.exists(self.tlog): - tout = open(self.tlog,'a') + tout = open(self.tlog, "a") else: - tout = open(self.tlog,'w') + tout = open(self.tlog, "w") cll = ["planemo", "shed_create", "--shed_target", "local"] try: - p = subprocess.run(cll, shell=False, cwd=self.tooloutdir, stdout=tout, stderr = tout) + p = subprocess.run( + cll, shell=True, cwd=self.tooloutdir, stdout=tout, stderr=tout + ) except: pass if p.returncode != 0: @@ -729,20 +695,21 @@ "--tar", self.newtarpath, ] - print("Run", " ".join(cll)) - p = subprocess.run(cll, shell=False) + p = subprocess.run(cll, shell=True) print("Ran", " ".join(cll), "got", p.returncode) tout.close() return p.returncode def planemo_test(self, genoutputs=True): - """planemo is a requirement so is available + """planemo is a requirement so is available for testing + and for generating test outputs if command or test overrides are supplied + test outputs are sent to repdir for display """ xreal = "%s.xml" % self.tool_name if os.path.exists(self.tlog): - tout = open(self.tlog,'a') + tout = open(self.tlog, "a") else: - tout = open(self.tlog,'w') + tout = open(self.tlog, "w") if genoutputs: cll = [ "planemo", @@ -750,24 +717,42 @@ "--galaxy_root", self.args.galaxy_root, "--update_test_data", + "--galaxy_python_version", + "3.6", + "--no_conda_auto_install", + "--no_conda_auto_init", xreal, ] else: - cll = ["planemo", "test", "--galaxy_root", self.args.galaxy_root, xreal] - try: - p = subprocess.run(cll, shell=False, cwd=self.tooloutdir, stderr=tout, stdout=tout) - except: - pass + cll = ["planemo", "test", "--galaxy_python_version", + "3.6", "--galaxy_root", + self.args.galaxy_root, + "--no_conda_auto_install", + "--no_conda_auto_init", + xreal,] + p = subprocess.run( + cll, shell=True, cwd=self.tooloutdir, stderr=tout, stdout=tout + ) + if genoutputs: + with os.scandir(self.testdir) as outs: + for entry in outs: + if entry.is_file(): + dest = os.path.join(self.repdir, entry.name) + src = os.path.join(self.testdir, entry.name) + shutil.copyfile(src, dest) + tout.write( + "Copied output %s to %s after planemo test\n" % (src, dest) + ) tout.close() return p.returncode def eph_galaxy_load(self): - """ + """load the new tool from the local toolshed after planemo uploads it """ if os.path.exists(self.tlog): - tout = open(self.tlog,'a') + tout = open(self.tlog, "a") else: - tout = open(self.tlog,'w') + tout = open(self.tlog, "w") cll = [ "shed-tools", "install", @@ -799,6 +784,8 @@ return p.returncode def writeShedyml(self): + """for planemo + """ yuser = self.args.user_email.split("@")[0] yfname = os.path.join(self.tooloutdir, ".shed.yml") yamlf = open(yfname, "w") @@ -807,22 +794,67 @@ "owner": yuser, "type": "unrestricted", "description": self.args.tool_desc, + "synopsis": self.args.tool_desc, + "category": "TF Generated Tools", } yaml.dump(odict, yamlf, allow_unicode=True) yamlf.close() + def makeTool(self): + """write xmls and input samples into place + """ + self.makeXML() + if self.args.script_path: + stname = os.path.join(self.tooloutdir, "%s" % (self.sfile)) + if not os.path.exists(stname): + shutil.copyfile(self.sfile, stname) + xreal = "%s.xml" % self.tool_name + xout = os.path.join(self.tooloutdir, xreal) + shutil.copyfile(xreal, xout) + for p in self.infiles: + pth = p[IPATHPOS] + dest = os.path.join(self.testdir, "%s_sample" % p[ICLPOS]) + shutil.copyfile(pth, dest) + dest = os.path.join(self.repdir, "%s.%s" % (p[ICLPOS], p[IFMTPOS])) + shutil.copyfile(pth, dest) - def install_load(self): - _ = self.planemo_test(genoutputs=True) - testres = self.planemo_test(genoutputs=False) - if testres == 0: - if self.args.make_Tool == "install": - self.planemo_shedload() - self.eph_galaxy_load() - else: - os.stderr.write( - "Planemo test failed - tool %s was not installed" % self.args.tool_name - ) + def makeToolTar(self): + """ move outputs into test-data and prepare the tarball + """ + for p in self.outfiles: + src = p[ONAMEPOS] + if os.path.isfile(src): + dest = os.path.join(self.testdir, "%s_sample" % src) + shutil.copyfile(src, dest) + dest = os.path.join(self.repdir, "%s.%s" % (src, p[OFMTPOS])) + shutil.copyfile(src, dest) + else: + print( + "### problem - output file %s not found in tooloutdir %s" + % (src, self.tooloutdir) + ) + self.newtarpath = "toolfactory_%s.tgz" % self.tool_name + tf = tarfile.open(self.newtarpath, "w:gz") + tf.add(name=self.tooloutdir, arcname=self.tool_name) + tf.close() + shutil.copyfile(self.newtarpath, self.args.new_tool) + + def moveRunOutputs(self): + """need to move planemo or run outputs into toolfactory collection + """ + with os.scandir(self.tooloutdir) as outs: + for entry in outs: + if not entry.is_file() or entry.name.startswith("."): + continue + if "." in entry.name: + nayme, ext = os.path.splitext(entry.name) + else: + ext = ".txt" + ofn = "%s%s" % (entry.name.replace(".", "_"), ext) + dest = os.path.join(self.repdir, ofn) + src = os.path.join(self.tooloutdir, entry.name) + shutil.copyfile(src, dest) + def main(): """ @@ -857,10 +889,10 @@ a("--new_tool", default="new_tool") a("--runmode", default=None) a("--galaxy_url", default="http://localhost:8080") - a("--galaxy_api_key", default="fbdd3c2eecd191e88939fffc02eeeaf8") + a("--galaxy_api_key", default="fakekey") a("--toolshed_url", default="http://localhost:9009") - a("--toolshed_api_key", default="d46e5ed0e242ed52c6e1f506b5d7f9f7") - a("--galaxy_root", default="/home/ross/galaxy") + a("--toolshed_api_key", default="fakekey") + a("--galaxy_root", default="/galaxy-central") args = parser.parse_args() assert not args.bad_user, ( @@ -878,7 +910,16 @@ r = ScriptRunner(args) r.writeShedyml() r.makeTool() - if args.make_Tool == "runonly": + if args.command_override or args.test_override: + retcode = r.planemo_test(genoutputs=True) # this fails :( - see PR + r.moveRunOutputs() + r.makeToolTar() + retcode = r.planemo_test(genoutputs=False) + r.moveRunOutputs() + if args.make_Tool == "gentestinstall": + r.planemo_shedload() + r.eph_galaxy_load() + else: retcode = r.run() if retcode: sys.stderr.write( @@ -888,32 +929,13 @@ sys.exit(1) else: r.moveRunOutputs() - elif args.make_Tool in ["gentestinstall", "generate", "gentest"]: - retcode = r.run() - if retcode: - sys.stderr.write( - "## Run failed with return code %d. Cannot build yet. Please fix and retry" - % retcode - ) - sys.exit(1) - r.moveRunOutputs() - r.makeToolTar() - if args.make_Tool in ["gentestinstall","gentest"]: - r.planemo_test(genoutputs=False) - r.moveRunOutputs() - r.planemo_shedload() - r.eph_galaxy_load() - else: - retcode = r.planemo_test(genoutputs=True) # this fails :( - r.moveRunOutputs() - r.makeToolTar() - retcode = r.planemo_test(genoutputs=False) - r.moveRunOutputs() - if args.make_Tool == "planemotestinstall": - r.planemo_shedload() - r.eph_galaxy_load() - # if retcode: - # sys.exit(retcode) # indicate failure to job runner + r.makeToolTar() + if args.make_Tool in ["gentestinstall", "gentest"]: + r.planemo_test(genoutputs=False) + r.moveRunOutputs() + if args.make_Tool == "gentestinstall": + r.planemo_shedload() + r.eph_galaxy_load() if __name__ == "__main__": diff -r 35a912ce0c83 -r bf432f4486c7 toolfactory/rgToolFactory2.xml --- a/toolfactory/rgToolFactory2.xml Thu Aug 27 23:11:01 2020 -0400 +++ b/toolfactory/rgToolFactory2.xml Sun Aug 30 01:45:27 2020 -0400 @@ -1,7 +1,7 @@ Scripts into tools - + - - python - perl - r-base - galaxyxml - planemo - yaml - lxml - - + planemoenv + + 3: --cl_prefix "$cl_prefix" #end if @@ -191,9 +185,7 @@ ]]> -#if $usescript.choosescript == 'yes': $usescript.dynScript -#end if #if $cover.commover == "yes" and len(str($cover.command_override).strip()) > 1: @@ -239,32 +231,32 @@ - - + + - + - - + - + - + @@ -275,9 +267,9 @@ - + - + @@ -296,8 +288,8 @@ - - + + @@ -324,30 +316,22 @@ - - - - - - - + + + + + - + - + - - - - - - - + @@ -361,11 +345,10 @@ - - + @@ -377,13 +360,14 @@ - - + + + + - @@ -472,13 +456,10 @@ o.close() -Paper_ : -Creating re-usable tools from scripts: The Galaxy Tool Factory -Ross Lazarus; Antony Kaspi; Mark Ziemann; The Galaxy Team -Bioinformatics 2012; doi: 10.1093/bioinformatics/bts573 +Paper_ -**Licensing** +*Licensing* Copyright Ross Lazarus (ross period lazarus at gmail period com) May 2012 All rights reserved. diff -r 35a912ce0c83 -r bf432f4486c7 toolfactory/tool_dependencies.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolfactory/tool_dependencies.xml Sun Aug 30 01:45:27 2020 -0400 @@ -0,0 +1,16 @@ + + + + + + + planemo==0.72.0.dev0 + bioblend==0.14.0 + ephemeris==0.10.6 + galaxyxml==0.4.10 + lxml==4.5.1 + + + + +