Last active
July 26, 2017 11:21
-
-
Save choffmeister/1543dbdc5d152e7e95fb981952ed56e8 to your computer and use it in GitHub Desktop.
python -c "$(curl -fsSL https://gist.githubusercontent.com/choffmeister/1543dbdc5d152e7e95fb981952ed56e8/raw/generate-changelog.py)"
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
#!/usr/bin/python | |
import subprocess | |
import os | |
import re | |
import sys | |
import itertools | |
semver_regex = '^(?:v)?(\d+)\.(\d+)\.(\d+)(\-(.*))?$' | |
def toint(strOrNone): | |
if strOrNone: | |
return int(strOrNone) | |
else: | |
return None | |
def run(cmd, cwd = None, stdout = subprocess.PIPE): | |
p = subprocess.Popen(cmd, cwd = cwd, env = os.environ, stdout = stdout, stderr = subprocess.PIPE) | |
stdout, err = p.communicate() | |
if p.wait() != 0: raise Exception(err) | |
return stdout | |
def git_tags(): | |
return run(['git', 'tag']).splitlines() | |
def git_commits(ref_old, ref_new): | |
commits_raw = run(['git', 'log', '%s..%s' % (ref_old, ref_new), '--no-merges', '--pretty=%H %B|<|>|']).split('|<|>|')[:-1] | |
commits = filter(lambda c: c != None, map(lambda c: parse_commit(c), commits_raw)) | |
return commits | |
def tags_filter(t): | |
global semver_regex | |
return re.search(semver_regex, t) | |
def tags_sort(a, b): | |
global semver_regex | |
semver_a = re.match(semver_regex, a) | |
semver_b = re.match(semver_regex, b) | |
va = [toint(semver_a.group(1)), toint(semver_a.group(2)), toint(semver_a.group(3))] | |
vb = [toint(semver_b.group(1)), toint(semver_b.group(2)), toint(semver_b.group(3))] | |
if cmp(va, vb) != 0: | |
return cmp(va, vb) | |
else: | |
return -cmp(semver_a.group(5), semver_b.group(5)) | |
def parse_commit(raw_body): | |
parsed = re.match('^([a-z0-9]{40})\s(?:(\+|!|=|%|~)([^\s]+)?\s+)?(.*)$', raw_body.strip().splitlines()[0].strip()) | |
if parsed: | |
return { | |
'raw_body': raw_body.strip(), | |
'hash': parsed.group(1), | |
'type': parsed.group(2).strip() if parsed.group(2) else '', | |
'scopes': map(lambda s: s.strip(), parsed.group(3).split(',')) if parsed.group(3) else [], | |
'subject': parsed.group(4).strip() if parsed.group(4) else '' | |
} | |
else: | |
return None | |
tags = ['HEAD'] + list(reversed(sorted(filter(tags_filter, git_tags()), cmp = tags_sort))) | |
print '# Changelog\n' | |
for ref_new, ref_old in zip(tags[:-1], tags[1:]): | |
print '## %s\n' % ref_new | |
commits = git_commits(ref_old, ref_new) | |
for commit in commits: | |
scopes_str = ' (' + ','.join(commit['scopes']) + ')' if len(commit['scopes']) > 0 else '' | |
subject_str = commit['subject'] | |
hash_str = commit['hash'][:7] | |
print '*%s %s [%s]' % (scopes_str, subject_str, hash_str) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment