repos: build_report
This is the initial version of cross-repository report that tries to give an approximate answer to the question: "What other packages we should build with this one, and why?"
This commit is contained in:
parent
c84192c52a
commit
c373caeb99
@ -52,6 +52,18 @@ class Dependency(collections.namedtuple(
|
||||
self.name, self.version, self.flags,
|
||||
other.name, other.version, other.flags))
|
||||
|
||||
def is_setversion(self):
|
||||
return self.version and self.version.startswith(b'set:')
|
||||
|
||||
def pretty_str(self):
|
||||
if not self.flags and not self.version:
|
||||
return '{}[ANY]'.format(self.name.decode())
|
||||
if self.is_setversion():
|
||||
return '{}[set:<>]'.format(self.name.decode())
|
||||
return '{}[{} {}]'.format(
|
||||
self.name.decode(), self.flags,
|
||||
self.version.decode() if self.version else None)
|
||||
|
||||
|
||||
class Source:
|
||||
|
||||
@ -162,7 +174,93 @@ class Repository:
|
||||
return result
|
||||
|
||||
|
||||
_SPECIAL_DEPS = (
|
||||
# ABI parts:
|
||||
b'(GCC_', b'(CXXABI_', b'(GLIBC_',
|
||||
# elf loaders:
|
||||
b'/lib64/ld', b'/lib/ld', b'ld-linux')
|
||||
|
||||
|
||||
def _from_64bit_dep(dep):
|
||||
if dep.name.endswith(b'()(64bit)'):
|
||||
new_name = dep.name[:-9]
|
||||
elif dep.name.endswith(b'(64bit)'):
|
||||
new_name = dep.name[:-7]
|
||||
elif b'/lib64/' in dep.name:
|
||||
new_name = dep.name.replace(b'/lib64/', b'/lib/')
|
||||
else:
|
||||
return dep
|
||||
return Dependency(new_name, dep.flags, dep.version)
|
||||
|
||||
|
||||
def have_same_source(repoA, repoB, source_name):
|
||||
sourceA = repoA.sources.get(source_name)
|
||||
sourceB = repoB.sources.get(source_name)
|
||||
return (sourceA and sourceB and
|
||||
sourceA.epoch == sourceB.epoch and
|
||||
sourceA.version == sourceB.version and
|
||||
sourceA.release == sourceB.release)
|
||||
|
||||
|
||||
def build_report(from_repo, to_repo, source_name):
|
||||
result = set()
|
||||
srpm = from_repo.sources[source_name]
|
||||
# XXX: assumes from_repo is x86_64
|
||||
translate = '64' not in to_repo.name
|
||||
|
||||
missing_buidreqs = (dep for dep in srpm.requires
|
||||
if not any(to_repo.providers(dep)))
|
||||
for dep in missing_buidreqs:
|
||||
for _dep, provider in from_repo.providers(dep):
|
||||
result.add(('0000-BR', dep, provider))
|
||||
|
||||
for b in from_repo.binaries.values():
|
||||
if b.source_name != source_name:
|
||||
continue
|
||||
# now, we have a binary that was built from the srpm
|
||||
for dep in b.requires:
|
||||
# skip some platform-specific stuff
|
||||
if any(x in dep.name for x in _SPECIAL_DEPS):
|
||||
continue
|
||||
# if needed, try to translate from 64 to 32 bits
|
||||
the_dep = _from_64bit_dep(dep) if translate else dep
|
||||
# skip dependencies already present in to_repo
|
||||
if any(to_repo.providers(the_dep)):
|
||||
continue
|
||||
# skip inter-sub-package dependencies
|
||||
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():
|
||||
if any(have_same_source(from_repo, to_repo, p.source_name)
|
||||
for _d, p in from_repo.providers(dep)):
|
||||
continue
|
||||
# ok, it's true missing dependency
|
||||
for _dep, provider in from_repo.providers(dep):
|
||||
result.add((b.name.decode(), dep, provider))
|
||||
|
||||
# format and the result
|
||||
by_source = collections.defaultdict(list)
|
||||
lines = ['\n== %s ==\n' % source_name.decode()]
|
||||
for item in result:
|
||||
by_source[item[2].source_rpm].append(item)
|
||||
for that_source in sorted(by_source):
|
||||
lines.append(that_source.decode())
|
||||
by_knp = collections.defaultdict(list)
|
||||
for kind, dep, provider in by_source[that_source]:
|
||||
by_knp[(kind, provider.name.decode())].append(dep.pretty_str())
|
||||
for (kind, pname), pdep in sorted(by_knp.items()):
|
||||
lines.append('\t {} {} {}'.format(kind, pname, ' '.join(pdep)))
|
||||
lines.append('')
|
||||
return '\n'.join(lines)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from port_stats.utils import interactive_setup
|
||||
from pydoc import pager
|
||||
CONFIG = interactive_setup()
|
||||
repo = Repository.load_from_config('sisyphus_riscv64', CONFIG)
|
||||
riscv64 = Repository.load_from_config('sisyphus_riscv64', CONFIG)
|
||||
x86_64 = Repository.load_from_config('sisyphus', CONFIG)
|
||||
mipsel = Repository.load_from_config('sisyphus_mipsel', CONFIG)
|
||||
|
Loading…
x
Reference in New Issue
Block a user