Skip to content

Commit

Permalink
Merge pull request #818 from mvdbeek/cross_toolshed_tool_fetching
Browse files Browse the repository at this point in the history
Look up installed tools from different toolshed(s)
  • Loading branch information
jmchilton committed Dec 6, 2015
2 parents 4fe36f8 + 77f0340 commit 3a023f4
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 46 deletions.
2 changes: 1 addition & 1 deletion client/galaxy/scripts/mvc/tool/tools-form-base.js
Expand Up @@ -99,7 +99,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
self._buildForm(new_model['tool_model'] || new_model);
!hide_message && self.form.message.update({
status : 'success',
message : 'Now you are using \'' + self.options.name + '\' version ' + self.options.version + '.',
message : 'Now you are using \'' + self.options.name + '\' version ' + self.options.version + ', id \'' + self.options.id + '\'.',
persistent : false
});
Galaxy.emit.debug('tools-form-base::initialize()', 'Initial tool model ready.', new_model);
Expand Down
4 changes: 4 additions & 0 deletions lib/galaxy/managers/workflows.py
Expand Up @@ -334,6 +334,10 @@ def _workflow_to_dict_editor(self, trans, stored):
# FIXME: Frontend should be able to handle workflow messages
# as a dictionary not just the values
data['upgrade_messages'][step.order_index] = upgrade_message.values()
# Dispay version/tool_id changes
data['upgrade_messages'] = [step.order_index][module.tool.name] = "\n".join( module.version_changes )
elif (hasattr(module, "version_changes")) and (module.version_changes):
data['upgrade_messages'] = {step.order_index: {module.tool.name: "\n".join( module.version_changes )}}
# Get user annotation.
step_annotation = self.get_item_annotation_obj( trans.sa_session, trans.user, step )
annotation_str = ""
Expand Down
13 changes: 6 additions & 7 deletions lib/galaxy/tools/__init__.py
Expand Up @@ -2571,18 +2571,17 @@ def _compare_tool_version( self, trans, job ):
# for some reason jobs don't always keep track of the tool version.
message = ''
else:
message = 'This job was initially run with tool version "%s", which is currently not available. ' % tool_version
message = 'This job was run with tool version "%s", which is not available. ' % tool_version
if len( tools ) > 1:
message += 'You can re-run the job with the selected tool or choose another derivation of the tool.'
message += 'You can re-run the job with the selected tool or choose another version of the tool.'
else:
message += 'You can re-run the job with this tool version, which is a derivation of the original tool.'
message += 'You can re-run the job with this tool version, which is a different version of the original tool.'
else:
message = 'This job was run with tool id "%s", version "%s", which is not available. ' % ( tool_id, tool_version )
if len( tools ) > 1:
message = 'This job was initially run with tool version "%s", which is currently not available. ' % tool_version
message += 'You can re-run the job with the selected tool or choose another derivation of the tool.'
message += 'You can re-run the job with the selected tool id "%s" or choose another derivation of the tool.' % self.id
else:
message = 'This job was initially run with tool id "%s", version "%s", which is ' % ( tool_id, tool_version )
message += 'currently not available. You can re-run the job with this tool, which is a derivation of the original tool.'
message += 'You can re-run the job with tool id "%s", which is a derivation of the original tool.' % self.id
except Exception, e:
raise exceptions.MessageException( str( e ) )
return message
Expand Down
81 changes: 47 additions & 34 deletions lib/galaxy/tools/toolbox/base.py
Expand Up @@ -7,6 +7,7 @@

from sqlalchemy import and_
from markupsafe import escape
from urlparse import urlparse

from galaxy.model.item_attrs import Dictifiable

Expand Down Expand Up @@ -373,40 +374,52 @@ def get_tool( self, tool_id, tool_version=None, get_all_versions=False, exact=Fa
if get_all_versions and exact:
raise AssertionError("Cannot specify get_tool with both get_all_versions and exact as True")

if tool_id in self._tools_by_id and not get_all_versions:
if tool_version and tool_version in self._tool_versions_by_id[ tool_id ]:
return self._tool_versions_by_id[ tool_id ][ tool_version ]
# tool_id exactly matches an available tool by id (which is 'old' tool_id or guid)
return self._tools_by_id[ tool_id ]
# exact tool id match not found, or all versions requested, search for other options, e.g. migrated tools or different versions
rval = []
tool_lineage = self._lineage_map.get( tool_id )
if tool_lineage:
lineage_tool_versions = tool_lineage.get_versions( )
for lineage_tool_version in lineage_tool_versions:
lineage_tool = self._tool_from_lineage_version( lineage_tool_version )
if lineage_tool:
rval.append( lineage_tool )
if not rval:
# still no tool, do a deeper search and try to match by old ids
for tool in self._tools_by_id.itervalues():
if tool.old_id == tool_id:
rval.append( tool )
if rval:
if get_all_versions:
return rval
else:
if tool_version:
# return first tool with matching version
for tool in rval:
if tool.version == tool_version:
return tool
# No tool matches by version, simply return the first available tool found
return rval[0]
# We now likely have a Toolshed guid passed in, but no supporting database entries
# If the tool exists by exact id and is loaded then provide exact match within a list
if tool_id in self._tools_by_id:
return[ self._tools_by_id[ tool_id ] ]
if "/repos/" in tool_id: # test if tool came from a toolshed
tool_id_without_tool_shed = tool_id.split("/repos/")[1]
available_tool_sheds = self.app.tool_shed_registry.tool_sheds.values()
available_tool_sheds = [ urlparse(tool_shed) for tool_shed in available_tool_sheds ]
available_tool_sheds = [ url.geturl().replace(url.scheme + "://", '', 1) for url in available_tool_sheds]
tool_ids = [ tool_shed + "repos/" + tool_id_without_tool_shed for tool_shed in available_tool_sheds]
if tool_id in tool_ids: # move original tool_id to the top of tool_ids
tool_ids.remove(tool_id)
tool_ids.insert(0, tool_id)
else:
tool_ids = [tool_id]
for tool_id in tool_ids:
if tool_id in self._tools_by_id and not get_all_versions:
if tool_version and tool_version in self._tool_versions_by_id[ tool_id ]:
return self._tool_versions_by_id[ tool_id ][ tool_version ]
# tool_id exactly matches an available tool by id (which is 'old' tool_id or guid)
return self._tools_by_id[ tool_id ]
# exact tool id match not found, or all versions requested, search for other options, e.g. migrated tools or different versions
rval = []
tool_lineage = self._lineage_map.get( tool_id )
if tool_lineage:
lineage_tool_versions = tool_lineage.get_versions( )
for lineage_tool_version in lineage_tool_versions:
lineage_tool = self._tool_from_lineage_version( lineage_tool_version )
if lineage_tool:
rval.append( lineage_tool )
if not rval:
# still no tool, do a deeper search and try to match by old ids
for tool in self._tools_by_id.itervalues():
if tool.old_id == tool_id:
rval.append( tool )
if rval:
if get_all_versions:
return rval
else:
if tool_version:
# return first tool with matching version
for tool in rval:
if tool.version == tool_version:
return tool
# No tool matches by version, simply return the first available tool found
return rval[0]
# We now likely have a Toolshed guid passed in, but no supporting database entries
# If the tool exists by exact id and is loaded then provide exact match within a list
if tool_id in self._tools_by_id:
return[ self._tools_by_id[ tool_id ] ]
return None

def has_tool( self, tool_id, tool_version=None, exact=False ):
Expand Down
12 changes: 10 additions & 2 deletions lib/galaxy/workflow/modules.py
Expand Up @@ -517,8 +517,12 @@ def from_dict( Class, trans, d, secure=True ):
module = Class( trans, tool_id, tool_version=tool_version )
module.state = galaxy.tools.DefaultToolState()
if module.tool is not None:
message = ""
if tool_id != module.tool_id:
message += "The tool (id '%s') specified in this step is not available. Using the tool with id %s instead." % (tool_id, module.tool_id)
if d.get('tool_version', 'Unspecified') != module.get_tool_version():
message = "%s: using version '%s' instead of version '%s' indicated in this workflow." % ( tool_id, d.get( 'tool_version', 'Unspecified' ), module.get_tool_version() )
message += "%s: using version '%s' instead of version '%s' specified in this workflow." % ( tool_id, d.get( 'tool_version', 'Unspecified' ), module.get_tool_version() )
if message:
log.debug(message)
module.version_changes.append(message)
if d[ "tool_state" ]:
Expand All @@ -545,8 +549,12 @@ def from_workflow_step( Class, trans, step ):
return module_factory.from_dict(trans, loads(step.config), secure=False)
tool_version = step.tool_version
module = Class( trans, tool_id, tool_version=tool_version )
message = ""
if step.tool_id != module.tool_id:
message += "The tool with the id '%s' is not available. Using the tool with id '%s' instead." % (step.tool_id, module.tool_id)
if step.tool_version and (step.tool_version != module.tool.version):
message = "%s: using version '%s' instead of version '%s' indicated in this workflow." % (tool_id, module.tool.version, step.tool_version)
message += "%s: using version '%s' instead of version '%s' specified in this workflow." % (tool_id, module.tool.version, step.tool_version)
if message:
log.debug(message)
module.version_changes.append(message)
module.recover_state( step.tool_inputs )
Expand Down

0 comments on commit 3a023f4

Please sign in to comment.