135 lines
4.4 KiB
Python
135 lines
4.4 KiB
Python
"""
|
|
Vhex package core abstract class
|
|
"""
|
|
import abc
|
|
|
|
from core.logger import log
|
|
|
|
__all__ = [
|
|
'VxRemoteBackendCore'
|
|
]
|
|
|
|
class VxRemoteBackendCore(abc.ABC):
|
|
r"""Represent a remote backend 'core' class.
|
|
|
|
This class is a simple abstract class that should be used by all internal
|
|
'backend' wich should expose some common methods and property:
|
|
|
|
================================== =========================================
|
|
Property Description
|
|
================================== =========================================
|
|
name (str) Backend name (for debug)
|
|
url (str) Backend URL (for internal use)
|
|
================================== =========================================
|
|
|
|
================================== =========================================
|
|
Method Description
|
|
================================== =========================================
|
|
find() find packages
|
|
clone() clone a package
|
|
================================== =========================================
|
|
"""
|
|
def __init__(self, url):
|
|
self._url = url
|
|
self._pkg_list = []
|
|
|
|
@property
|
|
@abc.abstractmethod
|
|
def name(self):
|
|
"""<property> hold pacakge name"""
|
|
|
|
@property
|
|
@abc.abstractmethod
|
|
def url(self):
|
|
"""<property> hold pacakge URL (or path for local package)"""
|
|
|
|
@property
|
|
@abc.abstractmethod
|
|
def package_list(self):
|
|
"""<property> return the pacakge list (cached)"""
|
|
|
|
@abc.abstractmethod
|
|
def package_fetch_versions(self, pkg):
|
|
"""<method> pacakge version fetch (cache)"""
|
|
|
|
@abc.abstractmethod
|
|
def package_clone(self, pkg, prefix=None):
|
|
"""<method> package primtive """
|
|
|
|
def package_find(self, name, version=None):
|
|
r"""Try to find package
|
|
|
|
This method will try to find a particular package with a specific
|
|
version if the `version` argument is provided. Otherwise, the version
|
|
argument can holds special version requirement if the package use a
|
|
versionning sementic (more information in <vxsdk/core/pkg/version.py>)
|
|
|
|
If name is empty, all package will be returned
|
|
|
|
@args
|
|
> names (str) - package name
|
|
> versions (str) - version pattern
|
|
|
|
Return:
|
|
> A list of dictionary with (at least):
|
|
[
|
|
{
|
|
'name' (str) : package name
|
|
'full_name' (str) : full named package (author+name)
|
|
'description' (str) : package description
|
|
'versions' (list) : [
|
|
List of :obj:VxVersion that match the `version` argument
|
|
]
|
|
},
|
|
...
|
|
]
|
|
"""
|
|
# check if we need to return the complet list
|
|
if not name:
|
|
ret = []
|
|
for pkg in self.package_list:
|
|
if not self.package_fetch_versions(pkg):
|
|
continue
|
|
pkg_cpy = pkg.copy()
|
|
pkg_cpy['version'] = None
|
|
ret.append(pkg_cpy)
|
|
return ret
|
|
|
|
# handle package name and version verification
|
|
# @note
|
|
# - return on the first matched package
|
|
for pkg in self.package_list:
|
|
# check package name
|
|
if pkg['name'] != name:
|
|
continue
|
|
|
|
# fetch version information
|
|
if not self.package_fetch_versions(pkg):
|
|
log.warn("[pkg] '{pkg['name']}' unable to fetch versions")
|
|
continue
|
|
|
|
# if the version is None, we just need to fetch available
|
|
# versions then return
|
|
if not version:
|
|
pkg_cpy = pkg.copy()
|
|
pkg_cpy['version'] = None
|
|
return [pkg_cpy]
|
|
|
|
# perform version checking and select the best fit
|
|
ver_found = None
|
|
for ver in pkg['versions']:
|
|
if not ver.validate(version):
|
|
continue
|
|
if not ver_found or ver.compare(ver_found.name) < 0:
|
|
ver_found = ver
|
|
if not ver_found:
|
|
return []
|
|
|
|
# isolate the best version
|
|
pkg_cpy = pkg.copy()
|
|
pkg_cpy['version'] = ver_found
|
|
return [pkg_cpy]
|
|
|
|
# not requested package found, return
|
|
return None
|