diff env/lib/python3.9/site-packages/galaxy/tool_util/deps/resolvers/unlinked_tool_shed_packages.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/env/lib/python3.9/site-packages/galaxy/tool_util/deps/resolvers/unlinked_tool_shed_packages.py	Mon Mar 22 18:12:50 2021 +0000
@@ -0,0 +1,206 @@
+"""
+Backup resolvers for when dependencies can not be loaded from the database.
+Mainly suited for testing stage.
+
+Ideally all dependencies will be stored in the database
+when a tool is added from a Tool Shed.
+
+That should remain the preferred way of locating dependencies.
+
+In cases where that is not possible
+for example during testing this resolver can act as a backup.
+
+This resolver looks not just for manually added dependencies
+but also ones added from a Tool Shed.
+
+This tool is still under development so the default behaviour could change.
+It has been tested when placed in the same directory as galaxy_packages.py
+
+At the time of writing July 3 2015 this resolver has to be plugged in.
+See bottom for instructions on how to add this resolver.
+
+"""
+import logging
+from os import listdir
+from os.path import (
+    exists,
+    getmtime,
+    join
+)
+
+from . import (
+    Dependency,
+    NullDependency
+)
+from .galaxy_packages import BaseGalaxyPackageDependencyResolver
+
+log = logging.getLogger(__name__)
+
+MANUAL = "manual"
+PREFERRED_OWNERS = MANUAL + ",iuc,devteam"
+
+
+class UnlinkedToolShedPackageDependencyResolver(BaseGalaxyPackageDependencyResolver):
+    dict_collection_visible_keys = BaseGalaxyPackageDependencyResolver.dict_collection_visible_keys + ['preferred_owners', 'select_by_owner']
+    resolver_type = "unlinked_tool_shed_packages"
+
+    def __init__(self, dependency_manager, **kwds):
+        super().__init__(dependency_manager, **kwds)
+        # Provide a list of preferred owners whose dependency to use
+        self.preferred_owners = kwds.get('preferred_owners', PREFERRED_OWNERS).split(",")
+        # Option to ignore owner and just use last modified time
+        self.select_by_owner = str(kwds.get('select_by_owner', "true")).lower() != "false"
+
+    def _find_dep_versioned(self, name, version, type='package', **kwds):
+        try:
+            possibles = self._find_possible_dependencies(name, version, type)
+            if len(possibles) == 0:
+                log.debug("Unable to find dependency,'%s' '%s' '%s'", name, version, type)
+                return NullDependency(version=version, name=name)
+            elif len(possibles) == 1:
+                # Only one candidate found so ignore any preference rules
+                return possibles[0].dependency
+            else:
+                # Pick the preferred one
+                return self._select_preferred_dependency(possibles).dependency
+        except Exception:
+            log.exception("Unexpected error hunting for dependency '%s' '%s''%s'", name, version, type)
+            return NullDependency(version=version, name=name)
+
+    # Finds all possible dependency to use
+    # Should be extended as required
+    # Returns CandidateDependency objects with data for preference picking
+    def _find_possible_dependencies(self, name, version, type):
+        possibles = []
+        if exists(self.base_path):
+            path = join(self.base_path, name, version)
+            if exists(path):
+                # First try the way without owner/name/revision
+                package = self._galaxy_package_dep(path, version, name, type, True)
+                if not isinstance(package, NullDependency):
+                    log.debug("Found dependency '%s' '%s' '%s' at '%s'", name, version, type, path)
+                    possibles.append(CandidateDependency(package, path))
+                # now try with an owner/name/revision
+                for owner in listdir(path):
+                    owner_path = join(path, owner)
+                    for package_name in listdir(owner_path):
+                        if package_name.lower().startswith("package_" + name.lower()):
+                            package_path = join(owner_path, package_name)
+                            for revision in listdir(package_path):
+                                revision_path = join(package_path, revision)
+                                package = self._galaxy_package_dep(revision_path, version, name, type, True)
+                                if not isinstance(package, NullDependency):
+                                    log.debug("Found dependency '%s' '%s' '%s' at '%s'", name, version, type, revision_path)
+                                    possibles.append(CandidateDependency(package, package_path, owner))
+        return possibles
+
+    def _select_preferred_dependency(self, possibles, by_owner=None):
+        if by_owner is None:
+            by_owner = self.select_by_owner
+        preferred = []
+        if by_owner:
+            for owner in self.preferred_owners:
+                for candidate in possibles:
+                    if candidate.owner == owner:
+                        preferred.append(candidate)
+                if len(preferred) == 1:
+                    log.debug("Picked dependency based on owner '%s'", owner)
+                    return preferred[0]
+                elif len(preferred) > 1:
+                    log.debug("Multiple dependency found with owner '%s'", owner)
+                    break
+        if len(preferred) == 0:
+            preferred = possibles
+        latest_modified = 0
+        for candidate in preferred:
+            modified = getmtime(candidate.path)
+            if latest_modified < modified:
+                latest_candidate = candidate
+                latest_modified = modified
+        log.debug("Picking dependency at '%s' as it was the last modified", latest_candidate.path)
+        return latest_candidate
+
+    """
+    #Currently no need has been found for expand the verionsless method
+    #This is an example of how it could be done
+    def _find_dep_default( self, name, type='package', **kwds ):
+        try:
+            possibles = TODO
+            if len(possibles) == 0:
+                log.debug("Unable to find dependency,'%s' default '%s'", name, type)
+                return NullDependency(version=None, name=name)
+            elif len(possibles) == 1:
+                #Only one candidate found so ignore any preference rules
+                return possibles[0].dependency
+            else:
+                #Pick the preferred one
+                return self._select_preferred_dependency(possibles, by_owner=False).dependency
+        except Exception:
+            log.exception("Unexpected error hunting for dependency '%s' default '%s'", name, type)
+            return NullDependency(version=None, name=name)
+    """
+
+
+class CandidateDependency(Dependency):
+    dict_collection_visible_keys = Dependency.dict_collection_visible_keys + ['dependency', 'path', 'owner']
+    dependency_type = 'unlinked_tool_shed_package'
+
+    @property
+    def exact(self):
+        return self.dependency.exact
+
+    def __init__(self, dependency, path, owner=MANUAL):
+        self.dependency = dependency
+        self.path = path
+        self.owner = owner
+
+    def shell_commands(self):
+        """
+        Return shell commands to enable this dependency.
+        """
+        return self.dependency.shell_commands()
+
+
+__all__ = ('UnlinkedToolShedPackageDependencyResolver', )
+
+"""
+At the time of writing July 3 2015 this resolver has to be plugged in.
+
+Adding resolver instructions:
+
+1. create a dependency_resolvers_config.xml file
+<dependency_resolvers>
+  <tool_shed_packages />
+  <galaxy_packages />
+  <galaxy_packages versionless="true" />
+  <unlinked_tool_shed_packages />
+</dependency_resolvers>
+
+
+1a. ALWAYS add <tool_shed_packages /> first!!!!
+
+1b. <galaxy_packages /> is optional as
+    this resolver will also find dependency found by that resolver
+1bi Current default is to use a dependency to find that way first!
+1bii So an alternative version of dependency_resolvers_config.xml
+<dependency_resolvers>
+  <tool_shed_packages />
+  <unlinked_tool_shed_packages />
+  <unlinked_tool_shed_packages versionless="true" />
+</dependency_resolvers>
+
+1c. See __init__ for optional config values
+1ci versionless currently is handled by the super class
+    GalaxyPackageDependencyResolver
+
+2. Add a parameter to config.ini
+dependency_resolvers_config_file = ./config/dependency_resolvers_config.xml
+
+2a. File name/path can be different
+2b. config key must be dependency_resolvers_config_file
+
+3. For planemo it may be required to specify:
+--dependency_resolvers_config_file (xml file described in 1 above)
+--tool_dependency_dir (root of dependencies typically galaxy/dependency_dir)
+See planemo test --help for more information
+"""