From 923aef3d2ed08514fef20af2a2e6e2db640bf83e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Hertzog?= Date: Tue, 25 Oct 2016 10:35:08 +0000 Subject: Add a new tool to help review dsa-needed.txt/dla-needed.txt It makes it easy to find out old entries where nothing happened recently and where the person who claimed the entry failed to do his job in a timely manner. git-svn-id: svn+ssh://svn.debian.org/svn/secure-testing@45578 e39458fd-73e7-0310-bf30-c45bca0a0e42 --- bin/review-update-needed | 122 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100755 bin/review-update-needed (limited to 'bin/review-update-needed') diff --git a/bin/review-update-needed b/bin/review-update-needed new file mode 100755 index 0000000000..16bf2e6e0e --- /dev/null +++ b/bin/review-update-needed @@ -0,0 +1,122 @@ +#!/usr/bin/python3 + +import argparse +from datetime import datetime +import os +import re +import subprocess +import sys + +def format_date(timestamp): + date_to_format = datetime.utcfromtimestamp(timestamp) + delta = datetime.utcnow() - date_to_format + + output = date_to_format.strftime('%Y-%m-%d %H:%M') + if delta.days > 1: + output += ' ({} days ago)'.format(delta.days) + elif delta.days == 1: + output += ' (yesterday)' + + return output + +parser = argparse.ArgumentParser(description="Review DSA/DLA needed queues") +parser.add_argument('--lts', action='store_true', + help='Review dla-needed.txt instead of dsa-needed.txt') +parser.add_argument('-v', '--verbose', action='store_true', + help='Review dla-needed.txt instead of dsa-needed.txt') +parser.add_argument('--sort-by', default='last-update', + help='Sort by last-update (default) or by claimed-date') +parser.add_argument('--skip-unclaimed', action='store_true', + help='Skip unclaimed packages in the review') +args = parser.parse_args() + +if args.lts: + dsa_dla_needed = 'data/dla-needed.txt' +else: + dsa_dla_needed = 'data/dsa-needed.txt' + +if args.sort_by not in ('last-update', 'claimed-date'): + sys.stderr.write('ERROR: usage: --sort-by={last-update,claimed-date}\n') + sys.exit(1) + +if not os.path.exists(dsa_dla_needed): + sys.stderr.write("ERROR: {} not found\n".format(dsa_dla_needed)) + sys.exit(1) + +if not os.path.exists(".git"): + sys.stderr.write("ERROR: works only in a git-svn checkout\n") + sys.exit(1) + +process = subprocess.Popen(["git", "blame", "-p", "--", dsa_dla_needed], + stdout=subprocess.PIPE) +context = {} +in_preamble = True +all_entries = [] +entry = None +for line in process.stdout: + line = line.decode('utf-8') + res = re.search(r'^([0-9a-f]{40}) \d+', line) + if res: + context['commit'] = res.group(1) + if line.startswith('author '): + context['author'] = line.strip().split()[1] + elif line.startswith('author-time '): + context['author-time'] = int(line.strip().split()[1]) + elif line.startswith('summary '): + context['summary'] = line.strip().split(maxsplit=1)[1] + elif line.startswith("\t"): + line = line[1:] + if line.startswith("--"): + in_preamble = False + entry = None + elif in_preamble: + continue + elif line[0] == ' ' or line[0] == "\t": + entry['note'] += line + if context['author-time'] > entry['last-update']: + entry['last-update'] = context['author-time'] + entry['last-update-author'] = context['author'] + entry['last-update-summary'] = context['summary'] + entry['last-update-commit'] = context['commit'] + else: + res = re.match(r'^(\S+)(?:\s+\((.*)\)\s*)?$', line) + entry = { + 'pkg': res.group(1), + 'claimed-by': res.group(2), + 'claimed-date': context['author-time'], + 'last-update': context['author-time'], + 'last-update-author': context['author'], + 'last-update-summary': context['summary'], + 'last-update-commit': context['commit'], + 'author': context['author'], + 'note': '', + } + all_entries.append(entry) + +retcode = process.wait() +if retcode != 0: + sys.stderr.write("WARNING: git blame returned error code {}\n".format(retcode)) + +all_entries.sort(key=lambda x: x[args.sort_by]) + +for entry in all_entries: + if args.skip_unclaimed and not entry['claimed-by']: + continue + print("Package: {}".format(entry['pkg'])) + if entry['claimed-by']: + print("Claimed-By: {}".format(entry['claimed-by'])) + print("Claimed-Date: {}".format(format_date(entry['claimed-date']))) + else: + print("Unclaimed-Since: {}".format(format_date(entry['claimed-date']))) + if entry['last-update'] > entry['claimed-date']: + print("Last-Update: {}".format(format_date(entry['last-update']))) + if not args.verbose: + print("") + continue + print("Last-Update-Author: {}".format(entry['last-update-author'])) + print("Last-Update-Summary: {}".format(entry['last-update-summary'])) + print("Last-Update-Commit: {}".format(entry['last-update-commit'])) + if entry['note']: + print("Notes:\n{}".format(entry['note'])) + else: + print("") -- cgit v1.2.3