b674458df2
Reports still use bytes/strs interchangeably, but at least we can load things.
126 lines
3.6 KiB
Python
126 lines
3.6 KiB
Python
|
|
from __future__ import print_function
|
|
|
|
import json
|
|
import logging
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
from collections import defaultdict
|
|
|
|
import rpm
|
|
|
|
from port_stats import colorize
|
|
from port_stats import lists
|
|
from port_stats import utils
|
|
|
|
|
|
LOG = logging.getLogger('deps_cmp')
|
|
|
|
|
|
IGNORE_PATTERNS = tuple(
|
|
re.compile(p) for p in (
|
|
r'^rtld\(',
|
|
r'^rpmlib\(',
|
|
# glibc and gcc parts:
|
|
r'^ld.*so',
|
|
r'^/lib/ld.*so',
|
|
r'^/lib64/ld.*so',
|
|
r'^libc\.so',
|
|
r'^libm\.so',
|
|
# r'^libgcc_s\.so',
|
|
r'^libatomic\.so',
|
|
r'^libpthread\.so',
|
|
# r'^libstdc...so\.6',
|
|
))
|
|
|
|
|
|
def _gen_requires(header):
|
|
for dep in header[rpm.RPMTAG_REQUIRENAME]:
|
|
if dep.startswith('.'):
|
|
# strict interdeps -- we want to extract the name part
|
|
dep = '-'.join(dep.split('-')[1:-2])
|
|
if any(p.search(dep) for p in IGNORE_PATTERNS):
|
|
continue
|
|
yield dep
|
|
|
|
|
|
def source_name(header):
|
|
return header[rpm.RPMTAG_SOURCERPM].rsplit('-', 2)[0]
|
|
|
|
|
|
def read_pkg_lists(repo_dict):
|
|
result = []
|
|
prefix = repo_dict['path']
|
|
for arch in repo_dict['arch']:
|
|
path = os.path.join(prefix, arch, 'base', 'pkglist.classic.xz')
|
|
result.extend(lists.read_pkglist_headers_rpm(path))
|
|
return result
|
|
|
|
|
|
def main(config_path, colorize_name, result_prefix='bin_'):
|
|
logging.basicConfig(
|
|
format='%(asctime)s %(levelname)-5s %(name)s - %(message)s',
|
|
datefmt='%Y-%m-%d %H:%M:%S',
|
|
stream=sys.stderr, level=logging.INFO)
|
|
|
|
LOG.info('Coparing deps for %s, config=%s', colorize_name, config_path)
|
|
|
|
with open(config_path) as f:
|
|
config = json.load(f)
|
|
|
|
names = None
|
|
for clrz in config['colorize']:
|
|
if clrz['name'] == colorize_name:
|
|
names = clrz
|
|
break
|
|
if not names:
|
|
LOG.error('Unknown colorize name: %s', colorize_name)
|
|
return 1
|
|
|
|
base_by_name = {}
|
|
for header in read_pkg_lists(config['repos'][names['base']]):
|
|
base_by_name[header[rpm.RPMTAG_NAME]] = header
|
|
new_bin_headers = sorted(
|
|
read_pkg_lists(config['repos'][names['new']]),
|
|
key=lambda h: h[rpm.RPMTAG_NAME])
|
|
LOG.info('Loaded %s base binary packages, %s new binary packages',
|
|
len(base_by_name), len(new_bin_headers))
|
|
|
|
for_deps = []
|
|
|
|
with open(result_prefix + 'colors.tsv', 'w') as out:
|
|
for nh in new_bin_headers:
|
|
n_nevr = lists.NEVR.from_header(nh)
|
|
bh = base_by_name.get(n_nevr.name)
|
|
b_nevr = lists.NEVR.from_header(bh) if bh else None
|
|
color = colorize.colorize_pair(b_nevr, n_nevr)
|
|
if color in ('SLATE', 'GREEN'):
|
|
for_deps.append((bh, nh, color))
|
|
print(color, n_nevr.name,
|
|
lists.format_evr(b_nevr), lists.format_evr(n_nevr),
|
|
sep='\t', file=out)
|
|
LOG.info("Found %s pairs to compare", len(for_deps))
|
|
|
|
diffs = defaultdict(list)
|
|
for bh, nh, color in for_deps:
|
|
b_reqs = sorted(_gen_requires(bh))
|
|
n_reqs = sorted(_gen_requires(nh))
|
|
if b_reqs != n_reqs:
|
|
name = nh[rpm.RPMTAG_NAME]
|
|
common = set(n_reqs) & set(b_reqs)
|
|
b_left = [r for r in b_reqs if r not in common]
|
|
n_left = [r for r in n_reqs if r not in common]
|
|
for x in b_left:
|
|
diffs[x + '\t--'].append(name)
|
|
for x in n_left:
|
|
diffs[x + '\t++'].append(name)
|
|
|
|
for k, v in sorted(utils.items(diffs)):
|
|
print(k, ' '.join(v), sep='\t')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main(*sys.argv[1:]))
|