Skip to content

Instantly share code, notes, and snippets.

@upsuper
Last active August 29, 2015 14:07
Show Gist options
  • Save upsuper/6d22e1f8b5beb6d62764 to your computer and use it in GitHub Desktop.
Save upsuper/6d22e1f8b5beb6d62764 to your computer and use it in GitHub Desktop.
Check difference between local patches and submitted ones
#!/usr/bin/env python3
# - * - coding: UTF-8 - * -
import sys
import json
import concurrent.futures as futures
from pathlib import Path
from difflib import Differ
from urllib.request import urlopen
try:
import colorama
colorama.init()
except ImportError:
pass
SIGNS = ['=', '~', '*', '!']
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
SIGN_COLORS = [GREEN, BLUE, YELLOW, RED]
def usage():
app_name = Path(sys.argv[0]).name
print('usage: {} bug_id'.format(app_name))
def fetch_data(fileinfo):
local_file = Path('.hg/patches', fileinfo['file_name'])
if not local_file.exists():
return None
local_data = [line.decode('UTF-8') for line in local_file.open('rb')]
url = 'https://bugzilla.mozilla.org/' + \
'attachment.cgi?id={0}'.format(fileinfo['id'])
remote_data = [line.decode('UTF-8') for line in urlopen(url)]
return local_data, remote_data
def compare_patches(local_data, remote_data):
start = False
diff = 0
for line in Differ().compare(local_data, remote_data):
if not start:
if line[2:6] == 'diff':
start = True
continue
if line[0] == ' ' or line[0] == '?':
continue
if line[2] == '@':
diff = max(diff, 1)
elif line[2] == ' ':
diff = max(diff, 2)
else:
diff = max(diff, 3)
break
return diff
def print_result_line(filename, diff):
if sys.stdout.isatty():
print('\x1b[1;{0}m{1}\x1b[0m {2}'.format(
SIGN_COLORS[diff] + 30, SIGNS[diff], filename))
else:
print('{0} {1}'.format(SIGNS[diff], filename))
def main():
if len(sys.argv) < 2:
usage()
exit(2)
if not Path('.hg/patches').exists():
print(".hg/patches not exists")
exit(1)
bug_id = int(sys.argv[1])
url = 'https://api-dev.bugzilla.mozilla.org' + \
'/latest/bug/{0}/attachment'.format(bug_id) + \
'?include_fields=id,is_patch,is_obsolete,file_name'
data = urlopen(url).read().decode('UTF-8')
attachments = json.loads(data)['attachments']
attachments = [file for file in attachments
if file['is_patch'] and not file['is_obsolete']]
with futures.ThreadPoolExecutor(max_workers=5) as executor:
fetcher = executor.map(fetch_data, attachments)
for file, data in zip(attachments, fetcher):
if not data:
continue
local_data, remote_data = data
diff = compare_patches(local_data, remote_data)
print_result_line(file['file_name'], diff)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment