From dc9ab882cf83cb093a83a49f7f0bd184fd179733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=B6hmwalder?= Date: Tue, 16 Nov 2021 12:16:27 +0100 Subject: [PATCH] add support for list And some other flags --- dnfjson.py | 144 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 108 insertions(+), 36 deletions(-) diff --git a/dnfjson.py b/dnfjson.py index 00d32fe..d1e7e0c 100755 --- a/dnfjson.py +++ b/dnfjson.py @@ -2,6 +2,8 @@ import argparse import json +import sys + import dnf from dnf.cli.option_parser import OptionParser @@ -23,6 +25,7 @@ dnf.callback.TRANS_POST: 'TRANS_POST', } + class JsonProgressMeter(dnf.callback.DownloadProgress): def __init__(self): self.done_files = 0 @@ -49,6 +52,7 @@ def end(self, payload, status, err_msg): 'total_size': self.total_size, })) + class JsonTransactionProgress(dnf.callback.TransactionProgress): def __init__(self, total_pkgs): self.done_steps = 0 @@ -72,13 +76,26 @@ def progress(self, package, action, ti_done, ti_total, ts_done, ts_total): 'total_pkgs': self.total_pkgs, })) -def prepare_dnf(exclude=[]): + +def prepare_dnf(args=None): base = dnf.Base() - base.conf.exclude_pkgs(exclude) + base.conf.exclude_pkgs(args.excludepkgs if args else None) base.read_all_repos() + + if args and args.repofrompath: + for label, path in args.repofrompath.items(): + this_repo = base.repos.add_new_repo(label, base.conf, baseurl=[path]) + this_repo._configure_from_options(args) + + if args and args.repos: + base.repos.all().disable() + for repo in args.repos: + base.repos.get_matching(repo).enable() + base.fill_sack() return base + def json_package(pkg): return { 'name': pkg.name, @@ -86,48 +103,90 @@ def json_package(pkg): 'version': pkg.version, 'release': pkg.release, 'arch': pkg.arch, + 'repo': pkg.reponame, } -def install(packages, pretend=False, exclude=[]): - base = prepare_dnf(exclude=exclude) - base.install_specs(packages) - base.resolve() - - if pretend: - json_pkgs = [] - for pkg in base.transaction.install_set: - json_pkgs.append(json_package(pkg)) - print(json.dumps({ - 'packages': json_pkgs, - })) - return - base.download_packages(base.transaction.install_set, progress=JsonProgressMeter()) - base.do_transaction(JsonTransactionProgress(len(base.transaction.install_set))) +def install(packages, args=None): + with prepare_dnf(args) as base: + base.install_specs(packages) + base.resolve() -def upgrade(packages, pretend=False, exclude=[]): - base = prepare_dnf(exclude=exclude) + if args and args.pretend: + json_pkgs = [] + for pkg in base.transaction.install_set: + json_pkgs.append(json_package(pkg)) + print(json.dumps({ + 'packages': json_pkgs, + })) + return - if len(packages) == 0: - base.upgrade_all() - else: - base.upgrade(packages) - base.resolve() + base.download_packages(base.transaction.install_set, progress=JsonProgressMeter()) + base.do_transaction(JsonTransactionProgress(len(base.transaction.install_set))) + + +def upgrade(packages, args=None): + with prepare_dnf(args) as base: + if len(packages) == 0: + base.upgrade_all() + else: + base.upgrade(packages) + base.resolve() + + if args and args.pretend: + json_pkgs = [] + for pkg in base.transaction.install_set: + json_pkgs.append(json_package(pkg)) + print(json.dumps({ + 'packages': json_pkgs, + })) + return - if pretend: - json_pkgs = [] - for pkg in base.transaction.install_set: - json_pkgs.append(json_package(pkg)) - print(json.dumps({ - 'packages': json_pkgs, - })) - return + base.download_packages(base.transaction.install_set, progress=JsonProgressMeter()) + base.do_transaction(JsonTransactionProgress(len(base.transaction.install_set))) + + +def list_pkgs(packages=None, args=None): + with prepare_dnf(args) as base: + # by default (both False), display all packages + if args and (not args.installed and not args.available): + args.installed = True + args.available = True + j = {} + + def apply_filters(q): + if packages: + q = q.filter(name__glob=packages) + if args and args.latest: + q = q.latest(args.latest) + return q + + if args and args.available: + q_available = base.sack.query().available() + q_available = apply_filters(q_available) + available_pkgs = q_available.run() + j['available'] = [json_package(x) for x in available_pkgs] + if args and args.installed: + q_installed = base.sack.query().installed() + q_installed = apply_filters(q_installed) + installed_pkgs = q_installed.run() + j['installed'] = [json_package(x) for x in installed_pkgs] + print(json.dumps(j)) - base.download_packages(base.transaction.install_set, progress=JsonProgressMeter()) - base.do_transaction(JsonTransactionProgress(len(base.transaction.install_set))) def main(): parser = argparse.ArgumentParser() + parser.add_argument('--repo', '--repoid', default=[], + dest='repos', action=OptionParser._SplitCallback) + parser.add_argument('--repofrompath', default={}, + action=OptionParser._SplitExtendDictCallback, + metavar='[repo,path]', + help='label and path to an additional repository to use (same ' + 'path as in a baseurl), can be specified multiple times.') + parser.add_argument("--setopt", dest="setopts", default=[], + action=OptionParser._SetoptsCallback, + help="set arbitrary config and repo options") + subparsers = parser.add_subparsers(dest='command') install_group = subparsers.add_parser('install') @@ -142,6 +201,14 @@ def main(): dest='excludepkgs', action=OptionParser._SplitCallback) upgrade_group.add_argument('package', nargs='*') + list_group = subparsers.add_parser('list') + list_group.add_argument('-x', '--exclude', '--excludepkgs', default=[], + dest='excludepkgs', action=OptionParser._SplitCallback) + list_group.add_argument('--installed', action='store_true') + list_group.add_argument('--available', action='store_true') + list_group.add_argument('--latest', type=int) + list_group.add_argument('package', nargs='*') + args = parser.parse_args() if not args.command: @@ -152,12 +219,17 @@ def main(): args.excludepkgs = [] if args.command == 'install': - install(args.package, pretend=args.pretend, exclude=args.excludepkgs) + install(args.package, args=args) return if args.command == 'upgrade': - upgrade(args.package, pretend=args.pretend, exclude=args.excludepkgs) + upgrade(args.package, args=args) return + if args.command == 'list': + list_pkgs(packages=args.package, args=args) + return + + if __name__ == '__main__': main()