Introduce a separate entity for chroots
Holding together a set of binaries turns out to be a nice abstraction.
This commit is contained in:
parent
ec92670e48
commit
2b779f5113
@ -136,6 +136,33 @@ class Binary:
|
|||||||
self.name, self.epoch, self.version, self.release)
|
self.name, self.epoch, self.version, self.release)
|
||||||
|
|
||||||
|
|
||||||
|
class Chroot:
|
||||||
|
'''Set of binary packages'''
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.provides = collections.defaultdict(set)
|
||||||
|
self.binaries = dict()
|
||||||
|
|
||||||
|
def add(self, binary):
|
||||||
|
name = binary.name
|
||||||
|
if name in self.binaries:
|
||||||
|
LOG.error("Duplicate binaries: %s %s",
|
||||||
|
binary, self.binaries[name])
|
||||||
|
self.binaries[name] = binary
|
||||||
|
for prov in binary.provides:
|
||||||
|
self.provides[prov.name].add(prov)
|
||||||
|
|
||||||
|
def unmets(self):
|
||||||
|
for b in self.binaries.values():
|
||||||
|
for dep in b.requires:
|
||||||
|
if not self.is_provided(dep):
|
||||||
|
yield dep
|
||||||
|
|
||||||
|
def is_provided(self, dep):
|
||||||
|
return any(p.is_provide_for(dep)
|
||||||
|
for p in self.provides.get(dep.name, ()))
|
||||||
|
|
||||||
|
|
||||||
# consider this repository components by default
|
# consider this repository components by default
|
||||||
DEFAULT_COMPONENTS = ('classic', 'checkinstall')
|
DEFAULT_COMPONENTS = ('classic', 'checkinstall')
|
||||||
|
|
||||||
@ -246,20 +273,18 @@ class Repository:
|
|||||||
|
|
||||||
def chroot_for(self, requires, prefer=()):
|
def chroot_for(self, requires, prefer=()):
|
||||||
stack = list(reversed(list(requires)))
|
stack = list(reversed(list(requires)))
|
||||||
chroot_provides = collections.defaultdict(set)
|
chroot = Chroot()
|
||||||
chroot_binaries = []
|
|
||||||
unmets = []
|
|
||||||
|
|
||||||
while stack:
|
while stack:
|
||||||
dep = stack.pop()
|
dep = stack.pop()
|
||||||
if any(p.is_provide_for(dep) for p in chroot_provides[dep.name]):
|
if chroot.is_provided(dep):
|
||||||
continue
|
continue
|
||||||
LOG.debug("looking up %s", dep)
|
LOG.debug("looking up %s", dep)
|
||||||
providers = set(item[1] for item in self.providers(dep))
|
providers = set(item[1] for item in self.providers(dep))
|
||||||
if not providers:
|
if not providers:
|
||||||
providers = set(item[1] for item in self.addon_providers(dep))
|
providers = set(item[1] for item in self.addon_providers(dep))
|
||||||
if not providers:
|
if not providers:
|
||||||
unmets.append(dep)
|
LOG.debug("Unmet dependency: %s", dep)
|
||||||
continue
|
continue
|
||||||
if len(providers) > 1:
|
if len(providers) > 1:
|
||||||
preferred = [p for p in providers
|
preferred = [p for p in providers
|
||||||
@ -272,12 +297,9 @@ class Repository:
|
|||||||
LOG.warning('Ambiguous provide: %s (%s)', dep, providers)
|
LOG.warning('Ambiguous provide: %s (%s)', dep, providers)
|
||||||
# choose an (almost) random provider
|
# choose an (almost) random provider
|
||||||
p = providers.pop()
|
p = providers.pop()
|
||||||
LOG.debug(" installing %s", p)
|
chroot.add(p)
|
||||||
chroot_binaries.append(p)
|
|
||||||
for prov in p.provides:
|
|
||||||
chroot_provides[prov.name].add(prov)
|
|
||||||
stack.extend(p.requires)
|
stack.extend(p.requires)
|
||||||
return unmets, chroot_binaries
|
return chroot
|
||||||
|
|
||||||
|
|
||||||
_SPECIAL_DEPS = (
|
_SPECIAL_DEPS = (
|
||||||
@ -332,14 +354,14 @@ def _raw_build_report(from_repo, to_repo, source_name, ignore=(), prefer=()):
|
|||||||
translate = (to_repo.bits != 64)
|
translate = (to_repo.bits != 64)
|
||||||
|
|
||||||
# find what's missing for the build chroot in to_repo
|
# find what's missing for the build chroot in to_repo
|
||||||
build_unmets, _b = to_repo.chroot_for(
|
chroot = to_repo.chroot_for(
|
||||||
from_repo.sources[source_name].requires, prefer=prefer)
|
from_repo.sources[source_name].requires, prefer=prefer)
|
||||||
|
|
||||||
# distinguish unmets from build requirements that are missing
|
# distinguish unmets from build requirements that are missing
|
||||||
buildreqs = {dep for dep in from_repo.sources[source_name].requires}
|
buildreqs = {dep for dep in from_repo.sources[source_name].requires}
|
||||||
missing_buildreqs = (
|
missing_buildreqs = (
|
||||||
((_BUILDREQ if dep in buildreqs else _BUILD_UNMET), dep)
|
((_BUILDREQ if dep in buildreqs else _BUILD_UNMET), dep)
|
||||||
for dep in build_unmets)
|
for dep in chroot.unmets())
|
||||||
|
|
||||||
# add requirements for the binary packages this source package
|
# add requirements for the binary packages this source package
|
||||||
# produces in the from_repo; if needed, try to translate from 64 to 32 bits
|
# produces in the from_repo; if needed, try to translate from 64 to 32 bits
|
||||||
@ -461,10 +483,10 @@ def recursive_build_report(from_repo, to_repo, *source_names,
|
|||||||
full_req = {}
|
full_req = {}
|
||||||
names = set(build_source_deps)
|
names = set(build_source_deps)
|
||||||
for source in build_source_deps:
|
for source in build_source_deps:
|
||||||
_u, bins = from_repo.chroot_for(from_repo.sources[source].requires,
|
chroot = from_repo.chroot_for(from_repo.sources[source].requires,
|
||||||
prefer=names)
|
prefer=names)
|
||||||
dep_sources = set()
|
dep_sources = set()
|
||||||
for b in bins:
|
for b in chroot.binaries.values():
|
||||||
if b.source_name not in build_source_deps:
|
if b.source_name not in build_source_deps:
|
||||||
continue
|
continue
|
||||||
if (b.source_name, source) in ignore_sort:
|
if (b.source_name, source) in ignore_sort:
|
||||||
|
Loading…
Reference in New Issue
Block a user