From 3e6e42705589379547480c63d3f863b2d9e361c8 Mon Sep 17 00:00:00 2001 From: Max Rees Date: Sat, 11 Apr 2020 17:42:24 -0500 Subject: Overhaul with multiple formats/orders + libapk for version comparison --- pkgver_test.py | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 pkgver_test.py (limited to 'pkgver_test.py') diff --git a/pkgver_test.py b/pkgver_test.py new file mode 100644 index 0000000..9566908 --- /dev/null +++ b/pkgver_test.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python3 +# Adélie Linux architecture package tester +# Ensure all packages are all on arches +# +# Copyright © 2018-2020 Adélie Linux team. All rights reserved. +# NCSA license. +# +import argparse +import os +import sys +from pathlib import Path + +from apkkit.base.index import Index + +from output import FORMATTERS, Yes, No, YES_MISSING, PARTIAL_MISSING +from version import is_older + +def analyze(url, repo, arches): + newest = dict() + arch_newest = {arch: dict() for arch in arches} + + for arch in arches: + print(f"Loading {arch}...", file=sys.stderr) + + for pkg in Index(url=f"{url}/{repo}/{arch}/APKINDEX.tar.gz").packages: + if pkg.name != pkg.origin: + continue + new = pkg.version + + for mydict in (newest, arch_newest[arch]): + curr = mydict.get(pkg.name, None) + if curr is None: + mydict[pkg.name] = new + elif is_older(curr, new): + mydict[pkg.name] = new + + return newest, arch_newest + +def order_arch(arches, newest, arch_newest, ign): + yield ["arch", "package", "version for arch", "newest version"] + + for arch in arches: + old = list() + + for pkg in newest.keys(): + ver = newest[pkg] + archver = arch_newest[arch].get(pkg, None) + + if archver is None and pkg not in ign: + yield [arch, pkg, PARTIAL_MISSING, ver] + + elif archver is not None and is_older(archver, ver): + yield [arch, pkg, archver, ver] + +def order_pkg(arches, newest, arch_newest, ign): + yield ["package", *arches] + + for pkg in sorted(newest.keys()): + for i in arches: + archver = arch_newest[i].get(pkg, None) + if archver is None: + break + if archver is not None and is_older(archver, newest[pkg]): + break + else: + continue + + row = [pkg] + for i in arches: + archver = arch_newest[i].get(pkg, None) + if archver is None and pkg in ign: + row.append(YES_MISSING) + elif archver is None: + row.append(PARTIAL_MISSING) + elif is_older(archver, newest[pkg]): + row.append(No(archver)) + else: + row.append(Yes(archver)) + + yield row + +ORDERS = { + "pkg": order_pkg, + "arch": order_arch, +} + +if __name__ == "__main__": + opts = argparse.ArgumentParser( + description="""Scan the REPO/ARCH repositories under URL and + look for outdated or missing packages when comparing across + architectures. This script only examines main packages, not + subpackages. + + At least two architectures must be given in order to make a + comparison.""" + ) + opts.add_argument( + "-f", "--format", choices=FORMATTERS.keys(), + default="pretty" if os.isatty(sys.stdout.fileno()) else "tab", + help="display format", + ) + opts.add_argument( + "-o", "--order", choices=ORDERS.keys(), + default="pkg", + help="display order", + ) + opts.add_argument( + "url", metavar="URL", + help="base URL (no repository or arch)", + ) + opts.add_argument( + "repo", metavar="REPO", + help="repository", + ) + opts.add_argument( + "arches", metavar="ARCHES", + help="architectures (comma separated, at least 2)", + ) + opts = opts.parse_args() + opts.arches = opts.arches.split(",") + + if len(opts.arches) < 2: + print("At least two arches are required", file=sys.stderr) + sys.exit(1) + + if Path(opts.repo + "-specific").is_file(): + with open(opts.repo + '-specific', 'r') as ignore_file: + ign = set(pkg[:-1] for pkg in ignore_file.readlines()) + else: + ign = set() + + newest, arch_newest = analyze(opts.url, opts.repo, opts.arches) + # FIXME: support multiple repos + FORMATTERS[opts.format]( + opts, + ORDERS[opts.order](opts.arches, newest, arch_newest, ign), + ) -- cgit v1.2.3-70-g09d2