Simplify madness code about checking requirements

This commit is contained in:
Alexandre Aubin 2019-09-10 14:06:18 +02:00
parent 80acf377c8
commit 6284ad09c6
3 changed files with 11 additions and 71 deletions

View file

@ -21,7 +21,6 @@
"app_change_url_success": "{app:s} URL is now {domain:s}{path:s}",
"app_extraction_failed": "Could not extract the installation files",
"app_id_invalid": "Invalid app ID",
"app_incompatible": "The app {app} is incompatible with your YunoHost version",
"app_install_files_invalid": "These files cannot be installed",
"app_location_already_used": "The app '{app}' is already installed in ({path})",
"app_make_default_location_already_used": "Can't make the app '{app}' the default on the domain, {domain} is already in use by the other app '{other_app}'",
@ -410,8 +409,6 @@
"no_restore_script": "No restore script found for the app '{app:s}'",
"not_enough_disk_space": "Not enough free space on '{path:s}'",
"operation_interrupted": "The operation was manually interrupted?",
"package_not_installed": "Package '{pkgname}' is not installed",
"package_unexpected_error": "An unexpected error occurred processing the package '{pkgname}'",
"package_unknown": "Unknown package '{pkgname}'",
"packages_upgrade_critical_later": "Critical packages ({packages:s}) will be upgraded later",
"packages_upgrade_failed": "Could not upgrade all the packages",

View file

@ -2461,38 +2461,14 @@ def _check_manifest_requirements(manifest, app_instance_name):
"""Check if required packages are met from the manifest"""
requirements = manifest.get('requirements', dict())
# FIXME: Deprecate min_version key
if 'min_version' in manifest:
requirements['yunohost'] = '>> {0}'.format(manifest['min_version'])
logger.debug("the manifest key 'min_version' is deprecated, "
"use 'requirements' instead.")
# Validate multi-instance app
if is_true(manifest.get('multi_instance', False)):
# Handle backward-incompatible change introduced in yunohost >= 2.3.6
# See https://github.com/YunoHost/issues/issues/156
yunohost_req = requirements.get('yunohost', None)
if (not yunohost_req or
not packages.SpecifierSet(yunohost_req) & '>= 2.3.6'):
raise YunohostError('{0}{1}'.format(
m18n.g('colon', m18n.n('app_incompatible'), app=app_instance_name),
m18n.n('app_package_need_update', app=app_instance_name)))
elif not requirements:
if not requirements:
return
logger.debug(m18n.n('app_requirements_checking', app=app_instance_name))
# Retrieve versions of each required package
try:
versions = packages.get_installed_version(
*requirements.keys(), strict=True, as_dict=True)
except packages.PackageException as e:
raise YunohostError('app_requirements_failed', error=str(e), app=app_instance_name)
# Iterate over requirements
for pkgname, spec in requirements.items():
version = versions[pkgname]
if version not in packages.SpecifierSet(spec):
if not packages.meets_version_specifier(pkgname, spec):
raise YunohostError('app_requirements_unmeet',
pkgname=pkgname, version=version,
spec=spec, app=app_instance_name)

View file

@ -33,36 +33,6 @@ logger = logging.getLogger('yunohost.utils.packages')
# Exceptions -----------------------------------------------------------------
class PackageException(Exception):
"""Base exception related to a package
Represent an exception related to the package named `pkgname`. If no
`message` is provided, it will first try to use the translation key
`message_key` if defined by the derived class. Otherwise, a standard
message will be used.
"""
message_key = 'package_unexpected_error'
def __init__(self, pkgname, message=None):
super(PackageException, self).__init__(
message or m18n.n(self.message_key, pkgname=pkgname))
self.pkgname = pkgname
class UnknownPackage(PackageException):
"""The package is not found in the cache."""
message_key = 'package_unknown'
class UninstalledPackage(PackageException):
"""The package is not installed."""
message_key = 'package_not_installed'
class InvalidSpecifier(ValueError):
"""An invalid specifier was found."""
@ -402,41 +372,38 @@ def get_installed_version(*pkgnames, **kwargs):
"""Get the installed version of package(s)
Retrieve one or more packages named `pkgnames` and return their installed
version as a dict or as a string if only one is requested and `as_dict` is
`False`. If `strict` is `True`, an exception will be raised if a package
is unknown or not installed.
version as a dict or as a string if only one is requested.
"""
versions = OrderedDict()
cache = apt.Cache()
# Retrieve options
as_dict = kwargs.get('as_dict', False)
strict = kwargs.get('strict', False)
with_repo = kwargs.get('with_repo', False)
for pkgname in pkgnames:
try:
pkg = cache[pkgname]
except KeyError:
if strict:
raise UnknownPackage(pkgname)
logger.warning(m18n.n('package_unknown', pkgname=pkgname))
if with_repo:
versions[pkgname] = {
"version": None,
"repo": None,
}
else:
versions[pkgname] = None
continue
try:
version = pkg.installed.version
except AttributeError:
if strict:
raise UninstalledPackage(pkgname)
version = None
try:
# stable, testing, unstable
repo = pkg.installed.origins[0].component
except AttributeError:
if strict:
raise UninstalledPackage(pkgname)
repo = ""
if with_repo:
@ -449,7 +416,7 @@ def get_installed_version(*pkgnames, **kwargs):
else:
versions[pkgname] = version
if len(pkgnames) == 1 and not as_dict:
if len(pkgnames) == 1:
return versions[pkgnames[0]]
return versions