167 lines
5.3 KiB
Plaintext
167 lines
5.3 KiB
Plaintext
|
#!/usr/bin/env python3
|
||
|
|
||
|
import sys
|
||
|
|
||
|
import codecs
|
||
|
import urllib.request
|
||
|
import json
|
||
|
|
||
|
import textwrap
|
||
|
|
||
|
sys.stdin = codecs.getreader("utf-8")(sys.stdin.detach())
|
||
|
sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())
|
||
|
|
||
|
entries = []
|
||
|
|
||
|
|
||
|
def add_entry(entry):
|
||
|
if entry and 'ignore' not in entry:
|
||
|
combo = []
|
||
|
for bug in set(entry.get('bugs', [])):
|
||
|
combo.append(bug)
|
||
|
for cve in set(entry.get('cves', [])):
|
||
|
combo.append(cve)
|
||
|
combo = sorted(combo)
|
||
|
|
||
|
if len(combo) == 0:
|
||
|
if entry.get('subject', "").startswith('UBUNTU'):
|
||
|
combo = '__packaging__'
|
||
|
else:
|
||
|
combo = '__mainline__'
|
||
|
else:
|
||
|
if entry.get('subject', "") == 'UBUNTU: link-to-tracker: update tracking bug':
|
||
|
# Construct a key with '__trackingbug__' on the first position
|
||
|
# and the tracking bug number afterwards
|
||
|
combo.insert(0, '__trackingbug__')
|
||
|
# Tracking bug goes at the top
|
||
|
keys.insert(0, combo)
|
||
|
else:
|
||
|
if combo not in keys:
|
||
|
keys.append(combo)
|
||
|
|
||
|
entry['key'] = combo
|
||
|
entries.append(entry)
|
||
|
|
||
|
|
||
|
# Suck up the git log output and extract the information we need.
|
||
|
keys = []
|
||
|
entry = None
|
||
|
subject_wait = False
|
||
|
for line in sys.stdin:
|
||
|
if line.startswith('commit '):
|
||
|
add_entry(entry)
|
||
|
entry = {}
|
||
|
subject_wait = True
|
||
|
|
||
|
elif line.startswith('Author: '):
|
||
|
bits = line.strip().split(maxsplit=1)
|
||
|
entry['author'] = bits[1]
|
||
|
|
||
|
elif subject_wait and line.startswith(' '):
|
||
|
subject_wait = False
|
||
|
entry['subject'] = line.strip()
|
||
|
|
||
|
elif line.startswith(' BugLink: '):
|
||
|
bits = line.strip().split(maxsplit=2)
|
||
|
if len(bits) > 2:
|
||
|
# There is text after the URL, so use that (after stripping the
|
||
|
# enclosing characters)
|
||
|
entry.setdefault('bugs', []).append(bits[2][1:-1])
|
||
|
elif 'launchpad.net' in bits[1]:
|
||
|
# Extract the bug number from the launchpad URL
|
||
|
bits = bits[1].split('/')
|
||
|
entry.setdefault('bugs', []).append(bits[-1])
|
||
|
|
||
|
elif line.startswith(' CVE-'):
|
||
|
entry.setdefault('cves', []).append(line.strip())
|
||
|
|
||
|
elif line.startswith(' Ignore:'):
|
||
|
entry['ignore'] = True
|
||
|
|
||
|
elif line.startswith(' Properties:'):
|
||
|
for prop in line.strip().split()[1:]:
|
||
|
if prop in ('ignore', 'no-changelog'):
|
||
|
entry['ignore'] = True
|
||
|
|
||
|
add_entry(entry)
|
||
|
|
||
|
entries.reverse()
|
||
|
|
||
|
# Go through the entries and clear out authors for upstream commits.
|
||
|
for entry in entries:
|
||
|
if entry['subject'].startswith('UBUNTU:'):
|
||
|
entry['subject'] = entry['subject'][7:].strip()
|
||
|
else:
|
||
|
del entry['author']
|
||
|
|
||
|
# Lump everything without a bug at the bottom.
|
||
|
keys.append('__packaging__')
|
||
|
keys.append('__mainline__')
|
||
|
|
||
|
emit_nl = False
|
||
|
for key in keys:
|
||
|
if key == '__packaging__':
|
||
|
title_set = ['Miscellaneous Ubuntu changes']
|
||
|
elif key == '__mainline__':
|
||
|
title_set = ['Miscellaneous upstream changes']
|
||
|
else:
|
||
|
title_set = []
|
||
|
for bug in key:
|
||
|
if bug.startswith('CVE-'):
|
||
|
title_set.append(bug)
|
||
|
elif bug == '__trackingbug__':
|
||
|
# Look for the tracking bug number on the second
|
||
|
# position of the key
|
||
|
continue
|
||
|
elif bug.isdigit():
|
||
|
# Assume that it is an LP bug number if 'bug' contains only digits
|
||
|
bug_info = None
|
||
|
|
||
|
try:
|
||
|
# urllib.request.urlcleanup()
|
||
|
request = urllib.request.Request('https://api.launchpad.net/devel/bugs/' + bug)
|
||
|
request.add_header('Cache-Control', 'no-cache')
|
||
|
with urllib.request.urlopen(request) as response:
|
||
|
data = response.read()
|
||
|
bug_info = json.loads(data.decode('utf-8'))
|
||
|
|
||
|
title = bug_info['title']
|
||
|
if 'description' in bug_info:
|
||
|
for line in bug_info['description'].split('\n'):
|
||
|
if line.startswith('Kernel-Description:'):
|
||
|
title = line.split(' ', 1)[1]
|
||
|
|
||
|
except urllib.error.HTTPError:
|
||
|
title = 'INVALID or PRIVATE BUG'
|
||
|
|
||
|
title += ' (LP###' + bug + ')'
|
||
|
title_set.append(title)
|
||
|
else:
|
||
|
# Finally treat 'bug' itself as the title
|
||
|
title_set.append(bug)
|
||
|
|
||
|
emit_title = True
|
||
|
for entry in entries:
|
||
|
if entry['key'] != key:
|
||
|
continue
|
||
|
|
||
|
if emit_title:
|
||
|
if emit_nl:
|
||
|
print('')
|
||
|
emit_nl = True
|
||
|
|
||
|
title_lines = textwrap.wrap('#// '.join(title_set), 76)
|
||
|
print(' * ' + title_lines[0].replace('LP###', 'LP: #').replace('#//', ' //'))
|
||
|
for line in title_lines[1:]:
|
||
|
line = line.replace('LP###', 'LP: #').replace('#//', ' //')
|
||
|
print(' ' + line)
|
||
|
|
||
|
emit_title = False
|
||
|
|
||
|
if key[0] != '__trackingbug__':
|
||
|
title_lines = textwrap.wrap(entry['subject'], 76)
|
||
|
print(' - ' + title_lines[0])
|
||
|
for line in title_lines[1:]:
|
||
|
line = line.replace('LP###', 'LP: #')
|
||
|
print(' ' + line)
|