mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Do not remove tools from other installed revisions when uninstalling TS repo
Multiple installed revisions of a repository can provide the same version of a tool, e.g. for the repository https://toolshed.g2.bx.psu.edu/view/nilesh/rseqc only one tool out of 22 has a different version in revision 57 with respect to revision 56. In this case, when uninstalling one repository, the tools with the same guid were removed also from the other repository revisions in the `shed_tool_conf` file. This can be prevented by checking also the tool path.
This commit is contained in:
@@ -372,7 +372,7 @@ class ToolPanelManager(object):
|
||||
new_tool_panel_section_label=new_tool_panel_section_label)
|
||||
return tool_section, tool_panel_section_key
|
||||
|
||||
def remove_from_shed_tool_config(self, shed_tool_conf_dict, guids_to_remove):
|
||||
def remove_from_shed_tool_config(self, shed_tool_conf_dict, metadata):
|
||||
"""
|
||||
A tool shed repository is being uninstalled so change the
|
||||
shed_tool_conf file. Parse the config file to generate the entire list
|
||||
@@ -380,6 +380,13 @@ class ToolPanelManager(object):
|
||||
subset of the entire list if one or more repositories have been
|
||||
deactivated.
|
||||
"""
|
||||
if 'tools' not in metadata:
|
||||
return
|
||||
# We need to use the tool path to uniquely identify the tools to remove,
|
||||
# since multiple installable revisions of a repository can provide the
|
||||
# same version of a tool (i.e. there may be another tool with the same
|
||||
# guid that we should not remove from shed_tool_conf).
|
||||
guid_paths_to_remove = [(_['guid'], _['tool_config']) for _ in metadata['tools']]
|
||||
shed_tool_conf = shed_tool_conf_dict['config_filename']
|
||||
tool_path = shed_tool_conf_dict['tool_path']
|
||||
config_elems = []
|
||||
@@ -393,7 +400,7 @@ class ToolPanelManager(object):
|
||||
if config_elem.tag == 'section':
|
||||
tool_elems_to_remove = []
|
||||
for tool_elem in config_elem:
|
||||
if tool_elem.get('guid') in guids_to_remove:
|
||||
if (tool_elem.get('guid'), tool_elem.get('file')) in guid_paths_to_remove:
|
||||
tool_elems_to_remove.append(tool_elem)
|
||||
for tool_elem in tool_elems_to_remove:
|
||||
# Remove all of the appropriate tool sub-elements from the section element.
|
||||
@@ -402,7 +409,7 @@ class ToolPanelManager(object):
|
||||
# Keep a list of all empty section elements so they can be removed.
|
||||
config_elems_to_remove.append(config_elem)
|
||||
elif config_elem.tag == 'tool':
|
||||
if config_elem.get('guid') in guids_to_remove:
|
||||
if (tool_elem.get('guid'), tool_elem.get('file')) in guid_paths_to_remove:
|
||||
config_elems_to_remove.append(config_elem)
|
||||
for config_elem in config_elems_to_remove:
|
||||
config_elems.remove(config_elem)
|
||||
@@ -424,18 +431,15 @@ class ToolPanelManager(object):
|
||||
# Create a list of guids for all tools that will be removed from the in-memory tool panel
|
||||
# and config file on disk.
|
||||
guids_to_remove = list(tool_panel_dict.keys())
|
||||
self.remove_guids(guids_to_remove, shed_tool_conf, uninstall)
|
||||
|
||||
def remove_guids(self, guids_to_remove, shed_tool_conf, uninstall):
|
||||
toolbox = self.app.toolbox
|
||||
# Remove the tools from the toolbox's tools_by_id dictionary.
|
||||
for guid_to_remove in guids_to_remove:
|
||||
# remove_from_tool_panel to false, will handling that logic below.
|
||||
toolbox.remove_tool_by_id(guid_to_remove, remove_from_panel=False)
|
||||
shed_tool_conf_dict = self.get_shed_tool_conf_dict(shed_tool_conf)
|
||||
# Always remove from the shed_tool_conf file on disk. Used to test for uninstall, not sure there is a legitimate use for this?!
|
||||
if uninstall:
|
||||
self.remove_from_shed_tool_config(shed_tool_conf_dict, guids_to_remove)
|
||||
# Remove from the shed_tool_conf file on disk.
|
||||
self.remove_from_shed_tool_config(shed_tool_conf_dict, repository.metadata)
|
||||
|
||||
def update_tool_panel_dict(self, tool_panel_dict, tool_panel_section_mapping, repository_tools_tups):
|
||||
for tool_guid in tool_panel_dict:
|
||||
|
||||
@@ -128,7 +128,7 @@ class ToolPanelManagerTestCase(BaseToolBoxTestCase):
|
||||
assert "github.com/galaxyproject/example/test_tool/0.2" not in open(os.path.join(self.test_directory, "tool_conf.xml"), "r").read()
|
||||
self._verify_tool_confs()
|
||||
|
||||
self._remove_guids(["github.com/galaxyproject/example/test_tool/0.1"], uninstall=True)
|
||||
self._remove_repository_contents("github.com/galaxyproject/example/test_tool/0.1", uninstall=True)
|
||||
|
||||
# Now no versions of this tool are returned by new toolbox.
|
||||
new_toolbox = self.get_new_toolbox()
|
||||
@@ -144,7 +144,7 @@ class ToolPanelManagerTestCase(BaseToolBoxTestCase):
|
||||
self._setup_two_versions_in_config(section=True)
|
||||
self._setup_two_versions()
|
||||
self.toolbox
|
||||
self._remove_guids(["github.com/galaxyproject/example/test_tool/0.2"], uninstall=uninstall)
|
||||
self._remove_repository_contents("github.com/galaxyproject/example/test_tool/0.2", uninstall=uninstall)
|
||||
|
||||
def _verify_version_2_removed_from_panel(self, section=True):
|
||||
# Check that test_tool now only has one version...
|
||||
@@ -164,9 +164,11 @@ class ToolPanelManagerTestCase(BaseToolBoxTestCase):
|
||||
next(iter(self.toolbox._tool_panel.values())).id == "github.com/galaxyproject/example/test_tool/0.1"
|
||||
assert "github.com/galaxyproject/example/test_tool/0.2" not in new_toolbox._integrated_tool_panel
|
||||
|
||||
def _remove_guids(self, guids, uninstall, shed_tool_conf="tool_conf.xml"):
|
||||
self.tpm.remove_guids(
|
||||
guids_to_remove=guids,
|
||||
def _remove_repository_contents(self, guid, uninstall, shed_tool_conf="tool_conf.xml"):
|
||||
tool = self.toolbox.get_tool(guid)
|
||||
repository = tool.tool_shed_repository
|
||||
self.tpm.remove_repository_contents(
|
||||
repository=repository,
|
||||
shed_tool_conf=shed_tool_conf,
|
||||
uninstall=uninstall,
|
||||
)
|
||||
|
||||
@@ -71,7 +71,13 @@ class BaseToolBoxTestCase(unittest.TestCase, UsesApp, UsesTools):
|
||||
self.config_files = []
|
||||
|
||||
def _repo_install(self, changeset, config_filename=None):
|
||||
metadata = {}
|
||||
metadata = {
|
||||
'tools': [{
|
||||
'add_to_tool_panel': False, # to have repository.includes_tools_for_display_in_tool_panel=False in InstalledRepositoryManager.activate_repository()
|
||||
'guid': "github.com/galaxyproject/example/test_tool/0.%s" % changeset,
|
||||
'tool_config': 'tool.xml'
|
||||
}],
|
||||
}
|
||||
if config_filename:
|
||||
metadata['shed_config_filename'] = config_filename
|
||||
repository = tool_shed_install.ToolShedRepository(metadata=metadata)
|
||||
@@ -98,7 +104,6 @@ class BaseToolBoxTestCase(unittest.TestCase, UsesApp, UsesTools):
|
||||
version2 = tool_shed_install.ToolVersion()
|
||||
version2.tool_id = "github.com/galaxyproject/example/test_tool/0.2"
|
||||
version2.repository = repository2
|
||||
|
||||
self.app.install_model.context.add(version2)
|
||||
self.app.install_model.context.flush()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user