summaryrefslogtreecommitdiffstats
path: root/bin/review-update-needed
diff options
context:
space:
mode:
authorRaphaël Hertzog <hertzog@debian.org>2016-10-25 10:35:08 +0000
committerRaphaël Hertzog <hertzog@debian.org>2016-10-25 10:35:08 +0000
commit923aef3d2ed08514fef20af2a2e6e2db640bf83e (patch)
tree610be3ed16990a9b52529b0ef455e244f368ace9 /bin/review-update-needed
parent0ce97b8ed304a1e2fc07a4ad7597353b31e4f63b (diff)
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
Diffstat (limited to 'bin/review-update-needed')
-rwxr-xr-xbin/review-update-needed122
1 files changed, 122 insertions, 0 deletions
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("")

© 2014-2024 Faster IT GmbH | imprint | privacy policy