Skip to content

Instantly share code, notes, and snippets.

@ignatenkobrain
Last active August 4, 2019 20:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ignatenkobrain/2ae6a21e112ad5ebd5b7ec87fe3e94ad to your computer and use it in GitHub Desktop.
Save ignatenkobrain/2ae6a21e112ad5ebd5b7ec87fe3e94ad to your computer and use it in GitHub Desktop.
#!/usr/bin/python3
import argparse
import collections
import humanize
import solv
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--favor', nargs='+', default=[])
parser.add_argument('--disable', nargs='+', default=[])
parser.add_argument('pkgs', nargs='+', metavar='PKG')
args = parser.parse_args()
pool = solv.Pool()
pool.setarch()
repo = pool.add_repo('rawhide')
f = solv.xfopen('/var/cache/dnf/koji.solv')
repo.add_solv(f)
f.close()
pool.addfileprovides()
pool.createwhatprovides()
considered = pool.get_considered_list()
for n in args.disable:
sel = pool.select(n, solv.Selection.SELECTION_NAME)
for s in sel.solvables():
try:
considered.remove(s.id)
except ValueError:
pass
pool.set_considered_list(considered)
pool.createwhatprovides()
solver = pool.Solver()
solver.set_flag(solv.Solver.SOLVER_FLAG_IGNORE_RECOMMENDED, True)
jobs = [pool.Job(solv.Job.SOLVER_INSTALL | solv.Job.SOLVER_SOLVABLE_NAME | solv.Job.SOLVER_SOLVABLE_PROVIDES, pool.str2id(p))
for p in args.pkgs]
jobs += [pool.Job(solv.Job.SOLVER_FAVOR | solv.Job.SOLVER_SOLVABLE_NAME, pool.str2id(p))
for p in args.favor]
pool.setpooljobs(jobs)
problems = solver.solve([])
if problems:
for pb in problems:
for rule in pb.findallproblemrules():
for info in rule.allinfos():
print(info.problemstr())
import sys; sys.exit(1)
def sz(solver):
trans = solver.transaction().newsolvables()
size = {str(p): p.lookup_num(solv.SOLVABLE_INSTALLSIZE)
for p in trans}
total = humanize.naturalsize(sum(size.values()))
sizes = collections.OrderedDict({k: humanize.naturalsize(v) for k, v in reversed(sorted(size.items(), key=lambda kv: kv[1]))})
return total, sizes
total, sizes = sz(solver)
for alt in solver.all_alternatives():
if set(args.favor) & set(s.name for s in alt.choices()):
continue
rinfo = alt.rule.info()
if rinfo.type == solv.Solver.SOLVER_RULE_JOB:
print(f'{rinfo.dep} is specified in job:')
else:
print(f'{rinfo.solvable.name} requires {rinfo.dep}:')
for choice in alt.choices():
solver.solve([pool.Job(solv.Job.SOLVER_FAVOR | solv.Job.SOLVER_SOLVABLE, choice.id)])
if choice == alt.chosen:
print(' - (default)', end=' ')
else:
print(' - ', end='')
print(f'{choice.name} → {sz(solver)[0]}')
print()
print(f'=== default ({total}) ===')
print()
for p, sz in sizes.items():
print(f' - {p}: {sz}')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment