Fix display of repository dependency status

that broke with the introduction of the all-at-once dependency
resolution in #3391 and addresses in part #3398. I have only restored
the (collapsed) display of dependencies for all requirements in a
repository, so breaking the information out on a per tool basis remains
on the TODO list.
This commit is contained in:
mvdbeek
2017-01-14 21:22:45 +01:00
parent 537d6e645a
commit 2ed131d206
6 changed files with 38 additions and 29 deletions
+2 -2
View File
@@ -1401,7 +1401,7 @@ class Tool( object, Dictifiable ):
"""
Return all requiremens of type package
"""
reqs = [req.to_dict() for req in self.requirements if req.type == 'package']
reqs = [req for req in self.requirements if req.type == 'package']
return reqs
@property
@@ -1409,7 +1409,7 @@ class Tool( object, Dictifiable ):
"""
Return a list of dictionaries for all tool dependencies with their associated status
"""
return self._view.get_requirements_status(self.tool_requirements, self.installed_tool_dependencies)
return self._view.get_requirements_status({self.id: self.tool_requirements}, self.installed_tool_dependencies)
def build_redirect_url_params( self, param_dict ):
"""
+3
View File
@@ -123,6 +123,7 @@ class DependencyManager( object ):
requirement_to_dependency = OrderedDict()
index = kwds.get('index', None)
require_exact = kwds.get('exact', False)
return_null_dependencies = kwds.get('return_null', False)
resolvable_requirements = []
for requirement in requirements:
@@ -164,6 +165,8 @@ class DependencyManager( object ):
log.debug(dependency.resolver_msg)
if not isinstance(dependency, NullDependency):
requirement_to_dependency[requirement] = dependency
elif return_null_dependencies and (resolver == self.dependency_resolvers[-1] or i == index):
requirement_to_dependency[requirement] = dependency
return requirement_to_dependency
+3
View File
@@ -28,6 +28,9 @@ class ToolRequirement( object ):
def __eq__(self, other):
return self.name == other.name and self.type == other.type and self.version == other.version
def __hash__(self):
return hash((self.name, self.type, self.version))
DEFAULT_CONTAINER_TYPE = "docker"
DEFAULT_CONTAINER_RESOLVE_DEPENDENCIES = False
+22 -1
View File
@@ -45,6 +45,16 @@ class DependencyResolversView(object):
def resolver_dependency(self, index, **kwds):
return self._dependency(**kwds)
def show_dependencies(self, requirements, installed_tool_dependencies=None):
"""
Resolves dependencies to build a requirements status in the admin panel/API
"""
kwds = {'install': False,
'return_null': True,
'installed_tool_dependencies': installed_tool_dependencies}
dependencies_per_tool = {tool: self._dependency_manager.requirements_to_dependencies(dependencies, **kwds) for tool, dependencies in requirements.items()}
return dependencies_per_tool
def install_dependencies(self, requirements):
return self._dependency_manager._requirements_to_dependencies_dict(requirements, **{'install': True})
@@ -129,7 +139,18 @@ class DependencyResolversView(object):
return [index for index, resolver in enumerate(self._dependency_resolvers) if hasattr(resolver, "install_dependency") and not resolver.disabled ]
def get_requirements_status(self, requested_requirements, installed_tool_dependencies=None):
return [self.manager_dependency(installed_tool_dependencies=installed_tool_dependencies, **req) for req in requested_requirements]
dependencies = self.show_dependencies(requested_requirements, installed_tool_dependencies)
# dependencies is a dict keyed on tool_ids, values are lists of ToolRequirements for that tool.
# we collapse requested requirements to single set,
# then use collapsed requirements to get resolved dependencies without duplicates.
flat_tool_requirements = set([r for requirement_list in requested_requirements.values() for r in requirement_list])
flat_dependencies = []
for requirements_odict in dependencies.values():
for requirement in requirements_odict:
if requirement in flat_tool_requirements:
flat_dependencies.append(requirements_odict[requirement])
flat_tool_requirements.remove(requirement)
return [d.to_dict() for d in flat_dependencies]
def clean(self, index=None, **kwds):
if index:
@@ -781,7 +781,7 @@ class AdminToolshed( AdminGalaxy ):
reinstalling=False,
required_repo_info_dicts=None )
view = views.DependencyResolversView(self.app)
requirements = suc.get_unique_requirements_from_repository(repository)
requirements = suc.get_requirements_from_repository(repository)
requirements_status = view.get_requirements_status(requirements, repository.installed_tool_dependencies)
return trans.fill_template( '/admin/tool_shed_repository/manage_repository.mako',
repository=repository,
+7 -25
View File
@@ -9,6 +9,7 @@ import sqlalchemy.orm.exc
from sqlalchemy import and_, false, true
from galaxy import util
from galaxy.tools.deps.requirements import ToolRequirement
from galaxy.util import checkers
from galaxy.web import url_for
from tool_shed.util import (
@@ -219,37 +220,18 @@ def get_tool_shed_repo_requirements(app, tool_shed_url, repositories=None, repo_
valid_tools = json_response[1].get('valid_tools', [])
if valid_tools:
tools.extend(valid_tools)
return get_unique_requirements_from_tools(tools)
return get_requirements_from_tools(tools)
def get_unique_requirements_from_tools(tools):
requirements = []
for tool in tools:
if tool['requirements']:
requirements.append(tool['requirements'])
return get_unique_requirements(requirements)
def get_requirements_from_tools(tools):
return {tool['id']: [ToolRequirement.from_dict(r) for r in tool['requirements']] for tool in tools}
def get_unique_requirements(requirements):
uniq_reqs = dict()
for tool_requirements in requirements:
for req in tool_requirements:
name = req.get("name", None)
if not name:
continue # A requirement without a name can't be resolved, so let's skip those
version = req.get("version", "versionless")
type = req.get("type", None)
if not type == "package":
continue
uniq_reqs["%s_%s" % (name, version)] = {'name': name, 'version': version, 'type': type}
return list(uniq_reqs.values())
def get_unique_requirements_from_repository(repository):
def get_requirements_from_repository(repository):
if not repository.includes_tools:
return []
return {}
else:
return get_unique_requirements_from_tools(repository.metadata.get('tools', []))
return get_requirements_from_tools(repository.metadata.get('tools', []))
def get_ctx_rev( app, tool_shed_url, name, owner, changeset_revision ):