Last active
December 9, 2019 14:46
-
-
Save stmobo/9b96d4908bb53060e9f080eba4e8fd1b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import subprocess as sp | |
import sys | |
import re | |
import dateutil.parser | |
from datetime import timezone | |
from pathlib import PurePath | |
git_log_format = [ | |
"commit %H", | |
"refs: %D", | |
"author: %aN", | |
"committer: %cn", | |
"date: %aI", | |
"", | |
"%s" | |
] | |
log_match_re = r"commit ([0-9a-f]{40})\n((?:(?:[a-zA-Z]+):(?:[^\n]*)\n)+)\n([^\n]+)\n\n((?:[^\n]+\n(?!commit))*[^\n]+\n?)" | |
merge_request_namespace = 'upstream/merge-requests/' | |
def format_character_name(name): | |
if name == "saki_zls": | |
return "Saki (ZLS)" | |
elif name == "misty_hgss": | |
return "Misty (HGSS)" | |
elif name == "rarity_eg": | |
return "Rarity (EG)" | |
elif name == 'hk416': | |
return "HK416" | |
else: | |
name = name.replace('_', ' ') | |
name = re.sub(r"\w+", lambda m: m.group(0).capitalize(), name) | |
return name | |
def main(): | |
if len(sys.argv) < 3: | |
sys.stderr.write("USAGE: {:s} [start commit] ['author'|'character']\n".format(sys.argv[0])) | |
sys.exit(1) | |
ret = sp.run(["git", "rev-parse", "--show-toplevel"], encoding="utf-8", capture_output=True) | |
if ret.returncode != 0: | |
sys.stderr.write("git fetch failed with error {:d}\n".format(ret.returncode)) | |
sys.stderr.write(ret.stderr+"\n") | |
sys.exit(1) | |
repo_dir = ret.stdout.strip() | |
fetch_cmd = sp.run(["git", "fetch", "upstream"], cwd=repo_dir, stdout=sp.PIPE, stderr=sp.STDOUT, encoding="utf-8") | |
if fetch_cmd.returncode != 0: | |
sys.stderr.write("git fetch failed with error {:d}\n".format(fetch_cmd.returncode)) | |
sys.stderr.write(fetch_cmd.stdout+"\n") | |
sys.exit(1) | |
log_data = sp.run( | |
[ | |
"git", "log", | |
"--no-merges", | |
"--name-only", | |
"--format="+"%n".join(git_log_format), | |
sys.argv[1]+"..upstream/master" | |
], | |
cwd=repo_dir, | |
capture_output=True, | |
encoding="utf-8" | |
) | |
commits = [] | |
for match in re.finditer(log_match_re, log_data.stdout): | |
commit_data = { | |
'sha': match[1], | |
'message': match[3].strip(), | |
'author': None, | |
'committer': (None, None), | |
'date': None, | |
'merge_requests': [], | |
'tags': [], | |
'topic': '', | |
'characters': [] | |
} | |
opps = set() | |
for file in match[4].split('\n'): | |
p = PurePath(file) | |
try: | |
if p.parts[0] == 'opponents' and len(p.parts) > 2: | |
opps.add(p.parts[1].casefold()) | |
except (IndexError, ValueError): | |
continue | |
commit_data['characters'] = list(opps) | |
for metadata in match[2].split('\n'): | |
kv = metadata.split(':', maxsplit=1) | |
key = kv[0].strip().lower() | |
try: | |
value = kv[1].strip() | |
except IndexError: | |
value = '' | |
if key == 'author': | |
commit_data['author'] = value | |
elif key == 'committer': | |
commit_data['committer'] = value | |
elif key == 'date': | |
commit_data['date'] = dateutil.parser.isoparse(value) | |
elif key == 'refs': | |
merge_requests = [] | |
tags = [] | |
for ref in value.split(','): | |
ref = ref.strip() | |
if ref.startswith(merge_request_namespace): | |
try: | |
mr_num = int(ref[len(merge_request_namespace):]) | |
merge_requests.append(mr_num) | |
except ValueError: | |
continue | |
elif ref.startswith('tag: '): | |
tags.append(ref[5:]) | |
commit_data['merge_requests'] = merge_requests | |
commit_data['tags'] = tags | |
if commit_data['committer'] == 'SPNATI Utilities Bot' and '#' in commit_data['author']: | |
# attempt to auto-detect discord usernames | |
author_name, author_tag = commit_data['author'].rsplit('#', maxsplit=1) | |
if len(author_tag) == 4 and author_tag.isdecimal(): | |
commit_data['author'] = author_name | |
if ':' in commit_data['message']: | |
commit_data['topic'] = commit_data['message'].split(':', maxsplit=1)[0].casefold() | |
elif len(opps) > 0: | |
commit_data['topic'] = ', '.join(opps) | |
commits.append(commit_data) | |
groups = {} | |
# filter out version update commits: | |
commits = list(filter(lambda c: c['author'] != 'SPNATI Utilities Bot' or len(c['tags']) == 0, commits)) | |
# organize commits: | |
for commit in commits: | |
commit_groups = [] | |
if sys.argv[2] == 'author': | |
commit_groups = (commit['author'],) | |
elif sys.argv[2] == 'character': | |
commit_groups = commit['characters'] | |
for group in commit_groups: | |
if group not in groups: | |
groups[group] = [] | |
groups[group].append(commit) | |
for group_key, commit_set in sorted(groups.items(), key=lambda kv: kv[0]): | |
commit_set = sorted(commit_set, key=lambda c: c['date'], reverse=True) | |
commit_set = sorted(commit_set, key=lambda c: c['topic']) | |
if sys.argv[2] == 'character': | |
group_key = format_character_name(group_key) | |
sys.stdout.write("{:s} ({:d}):\n".format(group_key, len(commit_set))) | |
for commit in commit_set: | |
utc_date = commit['date'].astimezone(timezone.utc) | |
sys.stdout.write(" ") | |
sys.stdout.write(utc_date.strftime("[%d %b %Y] ")) | |
sys.stdout.write(commit['message']) | |
if len(commit['merge_requests']) > 0: | |
sys.stdout.write(" ("+', '.join('!'+str(mr) for mr in commit['merge_requests'])+")") | |
sys.stdout.write("\n") | |
sys.stdout.write("\n") | |
if __name__ == "__main__": | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment