""" Package find backend abstraction """ from core.logger import log from core.pkg.backend import PKG_CORE_BACKEND_REMOTE, PKG_CORE_BACKEND_LOCAL __all__ = [ 'pkg_find' ] #--- # Internals #--- def _pkg_find_merge_result(pkg_list_remote, pkg_list_local): """ Merge two custom package information list @arg > pkg_list_remote (list,dict) - package list > pkg_list_local (list,dict) - package list @return > The first list modified """ for pkg_local in pkg_list_local: pkg_found = False for pkg_remote in pkg_list_remote: if pkg_remote['name'] != pkg_local['name']: continue pkg_found = True for pkg_ver_local in pkg_local['versions']: version_found = False for pkg_ver_remote in pkg_remote['versions']: if pkg_ver_remote.name != pkg_ver_local.name: continue pkg_ver_remote.addSource('local') version_found = True break if not version_found: pkg_remote['versions'].append(pkg_ver_local) if not pkg_found: pkg_list_remote.append(pkg_local) return pkg_list_remote def _pkg_find_select_best(pkg_remote, pkg_local): """ Select the best version @arg > pkg_remote (dict) - pacakge information > pkg_local (dict) - pacakge information @return > a list with the best pacakge information version """ if not 'version' in pkg_remote or not 'version' in pkg_local: log.warn("[log] misformed package search result, silently ignored") return [] if pkg_remote['version'].compare(pkg_local['version'].name) > 0: pkg_remote['version'] = pkg_local['version'] return [pkg_remote] #--- # Public #--- def pkg_find(name, version=None, local=False, remote=True): r""" Find the most appropriate package information This function will request to the remote backend the list of all version of the pacakge, which is basically all tags and branches. Then, we will check all of these until a version match with the `version` query. Note that the version query can contains special operation as described in @args > name (str) - exact valid package name > version (str) - version query string > local (bool) - enable local search > remote (bool) - enable remote search @return > a list of all matched package dictionnary : [ { 'name' : , 'path' : 'versions' : [ ... ] ] > None if error """ if not local and not remote: return [] # perform explicit request for each backend pkg_list_local = [] pkg_list_remote = [] if remote: pkg_list_remote = PKG_CORE_BACKEND_REMOTE.package_find(name, version) if local: pkg_list_local = PKG_CORE_BACKEND_LOCAL.package_find(name, version) # verify useless checking and merging operation if not pkg_list_remote: return pkg_list_local if not pkg_list_local: return pkg_list_remote # if a version is provided, each backend will return only one dictionary # with the best match in local and remote one. We will select the best # between these two. if version: return _pkg_find_select_best( pkg_list_remote[0], pkg_list_local[0], ) # if no version information as been specified each `pkg_list_remote` and # `pkg_list_local` will contains a list of all matched package information. # So, we need to merge these two list. return _pkg_find_merge_result(pkg_list_remote, pkg_list_local)