Created
September 12, 2017 15:06
-
-
Save fritschy/82befa8a499d7d00b6cca88eae5f3faf to your computer and use it in GitHub Desktop.
Create a useless AF spreadsheet from git history
This file contains hidden or 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/env python3 | |
| import xlsxwriter, os, re, sys | |
| from os.path import join as pjoin, isdir | |
| from datetime import timezone, datetime, timedelta | |
| from pygit2 import Repository as GR, Tree, Blob, Diff, GIT_SORT_REVERSE, GIT_SORT_TIME | |
| from functools import reduce | |
| CONTEXT_LINES = 100 | |
| OUTFILE = 'winman-patches.xlsx' | |
| REPLACE_CHARS = set([i for i in '<>;:,.()[]{}$%§"\'?`/´\\=*+~^°#|!& ']) | |
| MUTLIPLE_DASHES = re.compile(r'--+') | |
| def get_patch_name(x, m): | |
| n = ['-' if i in REPLACE_CHARS else i for i in m] # normalize | |
| n = re.sub(MUTLIPLE_DASHES, '-', ''.join(n)) # replace consecutive - with single - | |
| return '%04d-%s.patch' % (x, n.lower()) | |
| def get_repo_path(): | |
| for rn in ('.', '..'): # executing this from build-dirs | |
| if isdir(pjoin(rn, '.git')): | |
| return pjoin(rn, '.git') | |
| print('Could not find ".git"') | |
| sys.exit(1) | |
| def main(): | |
| with xlsxwriter.Workbook(OUTFILE) as wb: | |
| ws = wb.add_worksheet() | |
| header_format, std_format = wb.add_format({'bold': True}), wb.add_format({}) | |
| r = GR(get_repo_path()) | |
| n = 0 # tracking row for append(), first row | |
| def append(*args, **kwargs): | |
| nonlocal n | |
| for i, a in enumerate(args): | |
| ws.write(n, i, a, kwargs.get('fmt', std_format)) | |
| n += 1 | |
| append('Index', 'Date', 'Author', 'Short Description', 'Size', 'Insertions', 'Deletions', 'Files Changed', 'Patch File', fmt=header_format) | |
| for i, c in enumerate(r.walk(r.head.target, GIT_SORT_TIME | GIT_SORT_REVERSE)): | |
| firstline = c.message.split('\n', 1)[0] | |
| st = {'insertions': 0, 'deletions': 0, 'files_changed': 0} | |
| if len(c.parents) > 0: | |
| s = r.diff(c.parents[0], c).stats | |
| st['insertions'] = s.insertions | |
| st['deletions'] = s.deletions | |
| st['files_changed'] = s.files_changed | |
| else: | |
| def s(l): | |
| return reduce(lambda x, y: (x[0] + y[0], x[1] + y[1]), (b(r[x.id]) for x in l), (0, 0)) | |
| def b(bl): | |
| if isinstance(bl, Blob): | |
| d = bl.diff(old_as_path='/dev/null') | |
| return (sum(d.line_stats), 1) # there are only insertions | |
| elif isinstance(bl, Tree): | |
| return s(bl) | |
| return (0, 0) | |
| ins, fs = s(c.tree) | |
| st['insertions'] = ins | |
| st['files_changed'] = fs | |
| p = get_patch_name(i, firstline) | |
| os.system('git show -U%d %s > %s' % (CONTEXT_LINES, c.oid, p)) # so, sue me! | |
| ps = os.stat(p).st_size | |
| committer = '%s <%s>' % (c.author.name, c.author.email) | |
| tzi = timezone(timedelta(minutes=c.author.offset)) | |
| t = datetime.fromtimestamp(float(c.author.time), tzi) | |
| append(str(i+1), t.strftime('%Y-%m-%dT%H:%M:%S%z'), committer, firstline, ps, st['insertions'], st['deletions'], st['files_changed'], p) | |
| __name__ == '__main__' and main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment