""" 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): """ hold pacakge name""" @property @abc.abstractmethod def url(self): """ hold pacakge URL (or path for local package)""" @property @abc.abstractmethod def package_list(self): """ return the pacakge list (cached)""" @abc.abstractmethod def package_fetch_versions(self, pkg): """ pacakge version fetch (cache)""" @abc.abstractmethod def package_clone(self, pkg, prefix=None): """ 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 ) 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