from urllib3 import PoolManager import json import sys import re def get_patches(bugzillaID): http = PoolManager() # first find when the bug was fixed history = 'https://bugzilla.mozilla.org/rest/bug/{}/history'.format( bugzillaID) request = http.request('GET', history, retries=10) j = json.loads(request.data) times = [change['when'] for change in j['bugs'][0]['history'] if "FIXED" in [c["added"] for c in change["changes"]]] # then look through all the fix comments for patch URLs comments = 'https://bugzilla.mozilla.org/rest/bug/{}/comment'.format( bugzillaID) request = http.request('GET', comments, retries=10) j = json.loads(request.data) urlregex = r'https?://hg\.mozilla\.org/(?:mozilla-central|releases/[^/]+)'\ '/rev/[0-9a-f]+' fix_comments = [comment for comment in j['bugs'][bugzillaID]['comments'] if comment['creation_time'] in times] for comment in fix_comments: for urlmatch in re.findall(urlregex, comment['text']): patch_url = urlmatch.replace('/rev/', '/raw-rev/') yield http.request('GET', patch_url, retries=10).data.decode( errors='ignore') def get_title_lines(bugzillaID): for patch in get_patches(bugzillaID): for line in patch.split('\n'): line = line.strip() if len(line) != 0 and line[0] != '#': yield line break def get_affected_files(bugzillaID): for patch in get_patches(bugzillaID): for line in patch.split('\n'): if len(line) > 5 and ( line[:5] == '--- a' or line[:5] == '+++ b'): yield line[6:] def get_deleted_files(bugzillaID): fetch_next = False for patch in get_patches(bugzillaID): for line in patch.split('\n'): if len(line) >= 17 and \ line[:17] == "deleted file mode" and \ not fetch_next: fetch_next = True elif fetch_next: assert(line[:5] == '--- a') yield line[6:] fetch_next = False if __name__ == '__main__': command = sys.argv[1] bugzillaID = sys.argv[2] if command == 'titles': line_generator = get_title_lines(bugzillaID) elif command == 'files': line_generator = get_affected_files(bugzillaID) elif command == 'deleted': line_generator = get_deleted_files(bugzillaID) else: print("Bad command: " + command) sys.exit(1) for item in line_generator: print(item)