92
|
1 import copy
|
|
2 import logging
|
|
3
|
|
4 from galaxyxml import GalaxyXML, Util
|
|
5 from galaxyxml.tool.parameters import XMLParam
|
|
6
|
|
7 from lxml import etree
|
|
8
|
|
9 VALID_TOOL_TYPES = ("data_source", "data_source_async")
|
|
10 VALID_URL_METHODS = ("get", "post")
|
|
11
|
|
12 logging.basicConfig(level=logging.INFO)
|
|
13 logger = logging.getLogger(__name__)
|
|
14
|
|
15
|
|
16 class Tool(GalaxyXML):
|
|
17
|
|
18 def __init__(
|
|
19 self,
|
|
20 name,
|
|
21 id,
|
|
22 version,
|
|
23 description,
|
|
24 executable,
|
|
25 hidden=False,
|
|
26 tool_type=None,
|
|
27 URL_method=None,
|
|
28 workflow_compatible=True,
|
|
29 interpreter=None,
|
|
30 version_command="interpreter filename.exe --version",
|
|
31 command_override=None,
|
|
32 ):
|
|
33
|
|
34 self.executable = executable
|
|
35 self.interpreter = interpreter
|
|
36 self.command_override = command_override
|
|
37 kwargs = {
|
|
38 "name": name,
|
|
39 "id": id,
|
|
40 "version": version,
|
|
41 "hidden": hidden,
|
|
42 "workflow_compatible": workflow_compatible,
|
|
43 }
|
|
44 self.version_command = version_command
|
|
45
|
|
46 # Remove some of the default values to make tools look a bit nicer
|
|
47 if not hidden:
|
|
48 del kwargs["hidden"]
|
|
49 if workflow_compatible:
|
|
50 del kwargs["workflow_compatible"]
|
|
51
|
|
52 kwargs = Util.coerce(kwargs)
|
|
53 self.root = etree.Element("tool", **kwargs)
|
|
54
|
|
55 if tool_type is not None:
|
|
56 if tool_type not in VALID_TOOL_TYPES:
|
|
57 raise Exception("Tool type must be one of %s" % ",".join(VALID_TOOL_TYPES))
|
|
58 else:
|
|
59 kwargs["tool_type"] = tool_type
|
|
60
|
|
61 if URL_method is not None:
|
|
62 if URL_method in VALID_URL_METHODS:
|
|
63 kwargs["URL_method"] = URL_method
|
|
64 else:
|
|
65 raise Exception("URL_method must be one of %s" % ",".join(VALID_URL_METHODS))
|
|
66
|
|
67 description_node = etree.SubElement(self.root, "description")
|
|
68 description_node.text = description
|
|
69
|
|
70 def add_comment(self, comment_txt):
|
|
71 comment = etree.Comment(comment_txt)
|
|
72 self.root.insert(0, comment)
|
|
73
|
|
74 def append_version_command(self):
|
|
75 version_command = etree.SubElement(self.root, "version_command")
|
|
76 try:
|
|
77 version_command.text = etree.CDATA(self.version_command)
|
|
78 except Exception:
|
|
79 pass
|
|
80
|
|
81 def append(self, sub_node):
|
|
82 if issubclass(type(sub_node), XMLParam):
|
|
83 self.root.append(sub_node.node)
|
|
84 else:
|
|
85 self.root.append(sub_node)
|
|
86
|
|
87 def clean_command_string(self, command_line):
|
|
88 clean = []
|
|
89 for x in command_line:
|
|
90 if x is not [] and x is not [""]:
|
|
91 clean.append(x)
|
|
92
|
|
93 return "\n".join(clean)
|
|
94
|
|
95 def export(self, keep_old_command=False): # noqa
|
|
96
|
|
97 export_xml = copy.deepcopy(self)
|
|
98
|
|
99 try:
|
|
100 export_xml.append(export_xml.edam_operations)
|
|
101 except Exception:
|
|
102 pass
|
|
103
|
|
104 try:
|
|
105 export_xml.append(export_xml.edam_topics)
|
|
106 except Exception:
|
|
107 pass
|
|
108
|
|
109 try:
|
|
110 export_xml.append(export_xml.requirements)
|
|
111 except Exception:
|
|
112 pass
|
|
113
|
|
114 try:
|
|
115 export_xml.append(export_xml.configfiles)
|
|
116 except Exception:
|
|
117 pass
|
|
118
|
|
119 if self.command_override:
|
|
120 command_line = self.command_override
|
|
121 else:
|
|
122 command_line = []
|
|
123 try:
|
|
124 command_line.append(export_xml.inputs.cli())
|
|
125 except Exception as e:
|
|
126 logger.warning(str(e))
|
|
127
|
|
128 try:
|
|
129 command_line.append(export_xml.outputs.cli())
|
|
130 except Exception:
|
|
131 pass
|
|
132
|
|
133 # Add stdio section
|
|
134 stdio = etree.SubElement(export_xml.root, "stdio")
|
|
135 etree.SubElement(stdio, "exit_code", range="1:", level="fatal")
|
|
136
|
|
137 # Append version command
|
|
138 export_xml.append_version_command()
|
|
139
|
|
140 # Steal interpreter from kwargs
|
|
141 command_kwargs = {}
|
|
142 if export_xml.interpreter is not None:
|
|
143 command_kwargs["interpreter"] = export_xml.interpreter
|
|
144
|
|
145 # Add command section
|
|
146 command_node = etree.SubElement(export_xml.root, "command", **command_kwargs)
|
|
147
|
|
148 if keep_old_command:
|
|
149 if getattr(self, "command", None):
|
|
150 command_node.text = etree.CDATA(export_xml.command)
|
|
151 else:
|
|
152 logger.warning("The tool does not have any old command stored. " + "Only the command line is written.")
|
|
153 command_node.text = export_xml.executable
|
|
154 else:
|
|
155 if self.command_override:
|
|
156 actual_cli = export_xml.clean_command_string(command_line)
|
|
157 else:
|
|
158 actual_cli = "%s %s" % (export_xml.executable, export_xml.clean_command_string(command_line))
|
|
159 command_node.text = etree.CDATA(actual_cli.strip())
|
|
160
|
|
161 try:
|
|
162 export_xml.append(export_xml.inputs)
|
|
163 except Exception:
|
|
164 pass
|
|
165
|
|
166 try:
|
|
167 export_xml.append(export_xml.outputs)
|
|
168 except Exception:
|
|
169 pass
|
|
170
|
|
171 try:
|
|
172 export_xml.append(export_xml.tests)
|
|
173 except Exception:
|
|
174 pass
|
|
175
|
|
176 help_element = etree.SubElement(export_xml.root, "help")
|
|
177 help_element.text = etree.CDATA(export_xml.help)
|
|
178
|
|
179 try:
|
|
180 export_xml.append(export_xml.citations)
|
|
181 except Exception:
|
|
182 pass
|
|
183
|
|
184 return super(Tool, export_xml).export()
|