Skip to content

Commit

Permalink
add support for list
Browse files Browse the repository at this point in the history
And some other flags
  • Loading branch information
chrboe committed Nov 16, 2021
1 parent 5091e56 commit dc9ab88
Showing 1 changed file with 108 additions and 36 deletions.
144 changes: 108 additions & 36 deletions dnfjson.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import argparse
import json
import sys

import dnf
from dnf.cli.option_parser import OptionParser

Expand All @@ -23,6 +25,7 @@
dnf.callback.TRANS_POST: 'TRANS_POST',
}


class JsonProgressMeter(dnf.callback.DownloadProgress):
def __init__(self):
self.done_files = 0
Expand All @@ -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
Expand All @@ -72,62 +76,117 @@ 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,
'epoch': pkg.epoch,
'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')
Expand All @@ -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:
Expand All @@ -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()

0 comments on commit dc9ab88

Please sign in to comment.