mirror of
https://git.launchpad.net/~ubuntu-release/britney/+git/britney2-ubuntu
synced 2025-02-23 11:21:13 +00:00
console: Provide helpers to locate BinaryPackageIDs
Signed-off-by: Niels Thykier <niels@thykier.net>
This commit is contained in:
parent
3329f73535
commit
c3ca2bc703
@ -1,19 +1,111 @@
|
||||
import code
|
||||
import collections
|
||||
|
||||
|
||||
class SubInterpreterExit(SystemExit):
|
||||
pass
|
||||
|
||||
|
||||
def fuzzy_match(string, collection, thing_being_matched):
|
||||
if len(collection) < 1:
|
||||
raise ValueError("No valid candidates to match!?")
|
||||
matches = collection
|
||||
if string:
|
||||
if string in collection:
|
||||
return string
|
||||
matches = [x for x in collection if string in x]
|
||||
if not matches:
|
||||
raise ValueError("No matches for %s (%s), possible valid values are: %s" % (
|
||||
string, thing_being_matched, sorted(collection)))
|
||||
if string is not None and len(matches) > 1:
|
||||
matches = [x for x in collection if x.starts(string)]
|
||||
if len(matches) > 1:
|
||||
if string is None:
|
||||
raise ValueError("More than one item and no search criteria for %s, possible valid values are: %s" % (
|
||||
thing_being_matched, sorted(matches)))
|
||||
raise ValueError("Too many matches for %s (%s), matching candidates are: %s" % (
|
||||
string, thing_being_matched, sorted(matches)))
|
||||
return next(iter(matches))
|
||||
|
||||
|
||||
class ConsoleUtils(object):
|
||||
|
||||
def __init__(self, britney):
|
||||
self._britney = britney
|
||||
self._pkgid_cache = collections.defaultdict(list)
|
||||
self._build_cache()
|
||||
|
||||
def _build_cache(self):
|
||||
for pkg_id in self._britney.all_binaries:
|
||||
self._pkgid_cache[pkg_id.package_name].append(pkg_id)
|
||||
|
||||
def pkg_id(self, package_name, package_version=None, package_architecture=None, *,
|
||||
fuzzy_match_version=True, fuzzy_match_arch=True):
|
||||
"""Look up BinaryPackageID
|
||||
|
||||
Example:
|
||||
pkg_id("lintian", "2.5", "amd64") -> BinaryPackageID("lintian", "2.5.10", "amd64")
|
||||
(Note that difference in version is intentional and a part of the fuzzy matching)
|
||||
|
||||
:param package_name: Name of the package (e.g. "lintian")
|
||||
:param package_version: Version of the package (e.g. "2.5")
|
||||
:param package_architecture: Architecture of the package (note arch:all packages are always split
|
||||
in to a per-architecture package)
|
||||
:param fuzzy_match_version: If true, any version string is accepted as long as it uniquely identified
|
||||
the package.
|
||||
:param fuzzy_match_arch: If true, any architecture string is accepted as long as it uniquely identified
|
||||
the package.
|
||||
:return: Exactly one BinaryPackageId
|
||||
"""
|
||||
if package_name not in self._pkgid_cache:
|
||||
raise ValueError("Unknown package name: %s" % package_name)
|
||||
|
||||
package_candidates = self._pkgid_cache[package_name]
|
||||
unique_versions = {x.version for x in package_candidates}
|
||||
|
||||
real_version = package_version
|
||||
if package_version is None or package_version not in unique_versions:
|
||||
if not fuzzy_match_version:
|
||||
if unique_versions is None:
|
||||
raise ValueError("unique_versions cannot be None when fuzzy_match_version is False")
|
||||
raise ValueError("Unknown version %s, valid options are: %s" % (
|
||||
package_version, sorted(unique_versions)))
|
||||
real_version = fuzzy_match(package_architecture, unique_versions, 'package_version')
|
||||
|
||||
unique_architectures = {x.architecture for x in package_candidates if x.version == real_version}
|
||||
|
||||
real_architecture = package_architecture
|
||||
if package_architecture is None or package_architecture not in unique_architectures:
|
||||
if not fuzzy_match_arch:
|
||||
if package_architecture is None:
|
||||
raise ValueError("package_architecture cannot be None when fuzzy_match_arch is False")
|
||||
raise ValueError("Unknown architecture %s" % package_architecture)
|
||||
real_architecture = fuzzy_match(package_architecture, unique_architectures, 'package_architecture')
|
||||
|
||||
match = [x for x in package_candidates if x.version == real_version and x.architecture == real_architecture]
|
||||
if len(match) != 1:
|
||||
if not match:
|
||||
raise ValueError("Package %s, version %s (%s) is not available on architecture %s (%s)" %
|
||||
package_name, package_version, real_version, package_architecture, real_architecture)
|
||||
raise ValueError("The terms %s, %s (%s) and %s (%s) did not result in a unique package!? All matches: %s" %
|
||||
package_name, package_version, real_version, package_architecture, real_architecture,
|
||||
sorted(match))
|
||||
|
||||
return match[0]
|
||||
|
||||
|
||||
def console_quit():
|
||||
raise SubInterpreterExit()
|
||||
|
||||
|
||||
def run_python_console(britney_obj):
|
||||
console_utils = ConsoleUtils(britney_obj)
|
||||
console_locals = {
|
||||
'britney': britney_obj,
|
||||
'__name__': '__console__',
|
||||
'__doc__': None,
|
||||
'all_bin_pkg_ids': britney_obj.all_binaries.keys(),
|
||||
'pkg_id': console_utils.pkg_id,
|
||||
'quit': console_quit,
|
||||
'exit': console_quit,
|
||||
}
|
||||
@ -23,6 +115,8 @@ Interactive python (REPL) shell in britney.
|
||||
|
||||
Locals available
|
||||
* britney: Instance of the Britney object.
|
||||
* all_bin_pkg_ids: Set of all BinaryPackageIDs
|
||||
* pkg_id: Lookup a BinaryPackageID
|
||||
* quit()/exit(): leave this REPL console.
|
||||
"""
|
||||
try:
|
||||
|
Loading…
x
Reference in New Issue
Block a user