repos: Prefer requested sources for recursive report
This commit is contained in:
parent
79a92c2358
commit
fe17158f69
@ -227,7 +227,7 @@ class Repository:
|
|||||||
del self.binaries[name]
|
del self.binaries[name]
|
||||||
self.update_indexes()
|
self.update_indexes()
|
||||||
|
|
||||||
def chroot_for(self, requires):
|
def chroot_for(self, requires, prefer=()):
|
||||||
stack = list(reversed(list(requires)))
|
stack = list(reversed(list(requires)))
|
||||||
chroot_provides = collections.defaultdict(set)
|
chroot_provides = collections.defaultdict(set)
|
||||||
chroot_binaries = []
|
chroot_binaries = []
|
||||||
@ -242,9 +242,16 @@ class Repository:
|
|||||||
if not providers:
|
if not providers:
|
||||||
unmets.append(dep)
|
unmets.append(dep)
|
||||||
continue
|
continue
|
||||||
|
if len(providers) > 1:
|
||||||
|
preferred = [p for p in providers
|
||||||
|
if p.source_name in prefer]
|
||||||
|
if preferred and len(preferred) < len(providers):
|
||||||
|
LOG.info("Using preferred providers: %s %s",
|
||||||
|
dep, preferred)
|
||||||
|
providers = preferred
|
||||||
if len(providers) > 1:
|
if len(providers) > 1:
|
||||||
LOG.warning('Ambiguous provide: %s (%s)', dep, providers)
|
LOG.warning('Ambiguous provide: %s (%s)', dep, providers)
|
||||||
# that's almost random if ambigous:
|
# choose an (almost) random provider
|
||||||
p = providers.pop()
|
p = providers.pop()
|
||||||
LOG.debug(" installing %s", p)
|
LOG.debug(" installing %s", p)
|
||||||
chroot_binaries.append(p)
|
chroot_binaries.append(p)
|
||||||
@ -290,16 +297,7 @@ def have_same_source(repoA, repoB, source_name):
|
|||||||
_BUILDREQ = '0000-BR'
|
_BUILDREQ = '0000-BR'
|
||||||
|
|
||||||
|
|
||||||
def _missing_requires(from_repo, to_repo, requires, kind, ignore):
|
def _raw_build_report(from_repo, to_repo, source_name, ignore=(), prefer=()):
|
||||||
missing_buidreqs = (dep for dep in requires
|
|
||||||
if not any(to_repo.providers(dep)))
|
|
||||||
for dep in missing_buidreqs:
|
|
||||||
for _dep, provider in from_repo.providers(dep):
|
|
||||||
if provider.source_name not in ignore:
|
|
||||||
yield kind, dep, provider
|
|
||||||
|
|
||||||
|
|
||||||
def _raw_build_report(from_repo, to_repo, source_name, ignore=()):
|
|
||||||
"""Build report for one source, by name
|
"""Build report for one source, by name
|
||||||
|
|
||||||
Returns an iterable over tuples (kind, dep, provider).
|
Returns an iterable over tuples (kind, dep, provider).
|
||||||
@ -308,36 +306,50 @@ def _raw_build_report(from_repo, to_repo, source_name, ignore=()):
|
|||||||
assert from_repo.bits == 64
|
assert from_repo.bits == 64
|
||||||
translate = (to_repo.bits != 64)
|
translate = (to_repo.bits != 64)
|
||||||
|
|
||||||
result = set(_missing_requires(
|
missing_buildreqs = ((_BUILDREQ, dep)
|
||||||
from_repo, to_repo, from_repo.sources[source_name].requires,
|
for dep in from_repo.sources[source_name].requires)
|
||||||
_BUILDREQ, ignore))
|
missing_binreqs = itertools.chain.from_iterable(
|
||||||
|
((b.name.decode(), dep) for dep in b.requires)
|
||||||
|
for b in from_repo.binaries_from(source_name))
|
||||||
|
result = set()
|
||||||
|
|
||||||
for b in from_repo.binaries_from(source_name):
|
for kind, dep in itertools.chain(missing_buildreqs, missing_binreqs):
|
||||||
for dep in b.requires:
|
# skip some platform-specific stuff
|
||||||
# skip some platform-specific stuff
|
if any(x in dep.name for x in _SPECIAL_DEPS):
|
||||||
if any(x in dep.name for x in _SPECIAL_DEPS):
|
continue
|
||||||
continue
|
# if needed, try to translate from 64 to 32 bits
|
||||||
# if needed, try to translate from 64 to 32 bits
|
the_dep = _from_64bit_dep(dep) if translate else dep
|
||||||
the_dep = _from_64bit_dep(dep) if translate else dep
|
# skip dependencies already present in to_repo
|
||||||
# skip dependencies already present in to_repo
|
if any(to_repo.providers(the_dep)):
|
||||||
if any(to_repo.providers(the_dep)):
|
continue
|
||||||
continue
|
# skip inter-sub-package dependencies
|
||||||
# skip inter-sub-package dependencies
|
if any(p.source_name == source_name
|
||||||
if any(p.source_name == source_name
|
for _d, p in from_repo.providers(dep)):
|
||||||
|
continue
|
||||||
|
# set-versions may be platform-dependent.
|
||||||
|
# double-check that if have the same source
|
||||||
|
if (dep.is_setversion()
|
||||||
|
or _GHC_HASHLIB.match(dep.name)
|
||||||
|
or _GHC_HASHDEP.fullmatch(dep.name)):
|
||||||
|
if any(have_same_source(from_repo, to_repo, p.source_name)
|
||||||
for _d, p in from_repo.providers(dep)):
|
for _d, p in from_repo.providers(dep)):
|
||||||
continue
|
continue
|
||||||
# set-versions may be platform-dependent.
|
# ok, it's true missing dependency
|
||||||
# double-check that if have the same source
|
# let's look up providers
|
||||||
if (dep.is_setversion()
|
providers = set(provider
|
||||||
or _GHC_HASHLIB.match(dep.name)
|
for _dep, provider in from_repo.providers(dep)
|
||||||
or _GHC_HASHDEP.fullmatch(dep.name)):
|
if provider.source_name not in ignore)
|
||||||
if any(have_same_source(from_repo, to_repo, p.source_name)
|
if not providers:
|
||||||
for _d, p in from_repo.providers(dep)):
|
LOG.warning("No providers for %s", dep)
|
||||||
continue
|
elif len(providers) > 1:
|
||||||
# ok, it's true missing dependency
|
LOG.warning("%d provider(s) for %s: %s",
|
||||||
for _dep, provider in from_repo.providers(dep):
|
len(providers), dep, list(providers))
|
||||||
if provider.source_name not in ignore:
|
preferred = [p for p in providers
|
||||||
result.add((b.name.decode(), dep, provider))
|
if p.source_name in prefer]
|
||||||
|
if preferred and len(preferred) < len(providers):
|
||||||
|
LOG.info("Using preferred providers: %s", preferred)
|
||||||
|
providers = preferred
|
||||||
|
result.update((kind, dep, provider) for provider in providers)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@ -387,7 +399,8 @@ def recursive_build_report(from_repo, to_repo, *source_names,
|
|||||||
|
|
||||||
while stack:
|
while stack:
|
||||||
cur = stack.pop()
|
cur = stack.pop()
|
||||||
report = _raw_build_report(from_repo, to_repo, cur, ignore)
|
report = _raw_build_report(from_repo, to_repo, cur,
|
||||||
|
ignore, prefer=seen)
|
||||||
cur_in_to = to_repo.sources.get(cur)
|
cur_in_to = to_repo.sources.get(cur)
|
||||||
cur_source_srpm = cur_in_to.source_rpm if cur_in_to else b'NONE'
|
cur_source_srpm = cur_in_to.source_rpm if cur_in_to else b'NONE'
|
||||||
reports.append('\n== %s ==\n%s has %s\n' % (
|
reports.append('\n== %s ==\n%s has %s\n' % (
|
||||||
@ -408,8 +421,10 @@ def recursive_build_report(from_repo, to_repo, *source_names,
|
|||||||
|
|
||||||
# expand the build requires with the pkg reqs of dependencies:
|
# expand the build requires with the pkg reqs of dependencies:
|
||||||
full_req = {}
|
full_req = {}
|
||||||
|
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)
|
_u, bins = from_repo.chroot_for(from_repo.sources[source].requires,
|
||||||
|
prefer=names)
|
||||||
dep_sources = set()
|
dep_sources = set()
|
||||||
for b in bins:
|
for b in bins:
|
||||||
if b.source_name not in build_source_deps:
|
if b.source_name not in build_source_deps:
|
||||||
@ -472,20 +487,6 @@ def recursive_build_report(from_repo, to_repo, *source_names,
|
|||||||
return '\n'.join(reports)
|
return '\n'.join(reports)
|
||||||
|
|
||||||
|
|
||||||
def requires_build_report(from_repo, to_repo, *requires,
|
|
||||||
ignore=(), ignore_sort=()):
|
|
||||||
missing_reqs = list(_missing_requires(
|
|
||||||
from_repo, to_repo,
|
|
||||||
[Dependency.wrap(r) for r in requires],
|
|
||||||
ignore, ignore_sort))
|
|
||||||
reports = [format_triplet_report(missing_reqs, 'Requested')]
|
|
||||||
source_names = set(p.source_name for _k, _d, p in missing_reqs)
|
|
||||||
reports.append(recursive_build_report(
|
|
||||||
from_repo, to_repo, *source_names,
|
|
||||||
ignore=ignore, ignore_sort=ignore_sort))
|
|
||||||
return '\n'.join(reports)
|
|
||||||
|
|
||||||
|
|
||||||
def _unmets_without(repo, kind, *source_names):
|
def _unmets_without(repo, kind, *source_names):
|
||||||
next_repo = repo.copy('removal_test_' + repo.name)
|
next_repo = repo.copy('removal_test_' + repo.name)
|
||||||
next_repo.delete_sources(*source_names)
|
next_repo.delete_sources(*source_names)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user