outdated.py (2310B)
1 import collections 2 import json 3 import os 4 import subprocess 5 import sys 6 import urllib.request 7 8 9 def check_sub_tree(path): 10 names = { 11 "awk": "nawk", 12 "lpeg": "lua:lpeg", 13 "samurai": "samurai-build-tool", 14 "sshfs": "fusefs:sshfs", 15 "st": "st-term", 16 "terminus-font": "fonts:terminus", 17 "the_silver_searcher": "the-silver-searcher", 18 "tz": "tzdata", 19 "vis": "vis-editor", 20 "wpa_supplicant": "wpa-supplicant", 21 } 22 skip = set( 23 [ 24 "adobe-source-fonts", 25 "b3sum", 26 "cproc", 27 "fspec-sync", 28 "libutp", 29 "linux-headers", 30 "mc", 31 "openbsd", 32 "qbe", 33 "sbase", 34 "sdhcp", 35 "skeleton", 36 "spm", 37 "st", 38 "swc", 39 "ubase", 40 "velox", 41 "wld", 42 ] 43 ) 44 p = subprocess.Popen(["git", "-C", path, "ls-tree", "HEAD"], stdout=subprocess.PIPE) 45 for line in p.stdout: 46 fields = line.decode().split() 47 if fields[1] != "tree" or fields[3] in skip: 48 continue 49 name = fields[3] 50 try: 51 with open("{}/{}/ver".format(path, name), "r") as f: 52 oldver = f.read().rsplit(maxsplit=1)[0] 53 except FileNotFoundError: 54 continue 55 proj = names.get(name, name) 56 with urllib.request.urlopen( 57 "https://repology.org/api/v1/project/{}".format(proj) 58 ) as response: 59 pkgs = json.loads(response.read()) 60 newest = collections.Counter() 61 for pkg in pkgs: 62 if pkg["status"] in ("newest", "unique"): 63 newest[pkg["version"]] += 1 64 if not newest: 65 print("could not find newest version of {}".format(proj), file=sys.stderr) 66 continue 67 newver = newest.most_common(1)[0][0] 68 if oldver != newver: 69 print("{:20} {:16} => {:16}".format(name, oldver, newver)) 70 if p.wait(): 71 raise CalledProcessError(p.retcode, p.args) 72 73 74 paths = [] 75 for dpath, dnames, _ in os.walk("pkg"): 76 paths += [dpath] 77 depth = dpath.count(os.path.sep) 78 if depth >= 1: 79 del dnames[:] 80 81 # strip "pkg" 82 paths = paths[1:] 83 for path in paths: 84 check_sub_tree(path)