127 lines
3.8 KiB
Python
127 lines
3.8 KiB
Python
"""
|
|
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
|
|
<core/pkg/version>
|
|
|
|
@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' : <package name>,
|
|
'path' : <paclage path or URL>
|
|
'versions' : [
|
|
<list of all available (or matched) version (VxVersion)>
|
|
...
|
|
]
|
|
]
|
|
> 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)
|