Skip to content

Instantly share code, notes, and snippets.

@aswild
Created May 30, 2019 00:51
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save aswild/fc851c19e56c6bdd2371a082c5f5b417 to your computer and use it in GitHub Desktop.
Save aswild/fc851c19e56c6bdd2371a082c5f5b417 to your computer and use it in GitHub Desktop.
Script to visualize the most-upgraded packages on a pacman based system
#!/usr/bin/env python3
"""
pacman-upgrades-graph.py: a script to visualize the most-upgraded packages on an pacman-based system.
"""
import argparse, os, re, shutil, subprocess, sys
parser = argparse.ArgumentParser()
parser.add_argument('-w', '--width', type=int, default=-1,
help='Max total width of graph. Defaults to terminal size, ' +
'or no limit if stdout is not a terminal. 0 for no limit regardless')
parser.add_argument('-n', '--limit', type=int, default=0, metavar='N',
help='Show only the top N packages. 0 for no limit (default)')
parser.add_argument('-i', '--installed', action='store_true', help='Limit results to currently installed packages')
parser.add_argument('pacmanlog', nargs='*', default=['/var/log/pacman.log'],
help='pacman.log files to parse, all will be combined. Default /var/log/pacman.log')
args = parser.parse_args()
width = shutil.get_terminal_size(fallback=(0,0)).columns if args.width == -1 else args.width
installed = set(subprocess.check_output(['pacman', '-Qq'], universal_newlines=True).splitlines()) \
if args.installed else None
d = {} # dict of pkgname -> upgrade count mappings
for fn in args.pacmanlog:
with open(fn, 'r') as fp:
for line in fp:
m = re.search(r'\[ALPM\] upgraded (\S+)', line)
if m is None:
continue
pkg = m.group(1)
if pkg in d:
d[pkg] += 1
else:
d[pkg] = 1
if not d:
sys.exit('[no data found]')
# sort packages by count, descending
pkgs = sorted(d.keys(), key=lambda x: d[x], reverse=True)
if installed:
# filter on currently installed packages
pkgs = [p for p in pkgs if p in installed]
if args.limit:
# limit to top N packages
pkgs = pkgs[:args.limit]
maxlen = max(len(p) for p in pkgs) # max pkgname length
maxcount = max(d[p] for p in pkgs) # max upgrade count
cwidth = 1 # number of digits we need for the max count
while ((10 ** cwidth) - 1) < d[pkgs[0]]:
cwidth += 1
labelwidth = maxlen + cwidth + 2
barwidth = (width - labelwidth) if width else 0
for pkg in pkgs:
barsize = int((d[pkg] / d[pkgs[0]]) * barwidth) if barwidth else d[pkg]
print('%*s %*d %s'%(maxlen, pkg, cwidth, d[pkg], '#'*barsize))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment