|
| 1 | +# |
| 2 | +# |
| 3 | + |
| 4 | + |
| 5 | +import os |
| 6 | +import sys |
| 7 | +from collections import defaultdict |
| 8 | +from datetime import datetime |
| 9 | +from subprocess import Popen, PIPE |
| 10 | + |
| 11 | +root = os.path.dirname(sys.argv[0]) |
| 12 | + |
| 13 | + |
| 14 | +def read_authors(fn): |
| 15 | + return {email.strip('<>'): name for name, email in |
| 16 | + [line.rsplit(maxsplit=1) for line in open(fn, 'r')]} |
| 17 | + |
| 18 | + |
| 19 | +def parse_git_log(log, authors): |
| 20 | + committers = defaultdict(set) |
| 21 | + author = None |
| 22 | + date = None |
| 23 | + for line in log.decode('utf-8').split('\n'): |
| 24 | + if line.startswith('commit'): |
| 25 | + if date is not None and author is not None: |
| 26 | + committers[author].add(date.year) |
| 27 | + elif line.startswith('Author:'): |
| 28 | + email = line.rsplit('<', maxsplit=1)[1][:-1] |
| 29 | + elif line.startswith('Date:'): |
| 30 | + date = datetime.strptime(line[5:].rsplit(maxsplit=1)[0].strip(), |
| 31 | + '%a %b %d %H:%M:%S %Y') |
| 32 | + try: |
| 33 | + author = authors[email] |
| 34 | + except KeyError: |
| 35 | + author = email |
| 36 | + elif 'copyright' in line.lower() or 'license' in line.lower(): |
| 37 | + date = None |
| 38 | + if date is not None: |
| 39 | + committers[author].add(date.year) |
| 40 | + return committers |
| 41 | + |
| 42 | + |
| 43 | +def pretty_years(years): |
| 44 | + years = sorted(years) |
| 45 | + prev_year = prev_out = years[0] |
| 46 | + s = '{}'.format(prev_year) |
| 47 | + for year in years[1:]: |
| 48 | + if year - prev_year > 1: |
| 49 | + if year - prev_out > 1: |
| 50 | + if prev_year == prev_out: |
| 51 | + s = '{}, {}'.format(s, year) |
| 52 | + else: |
| 53 | + s = '{}-{}, {}'.format(s, prev_year, year) |
| 54 | + else: |
| 55 | + s = '{}, {}'.format(s, prev_year) |
| 56 | + prev_out = year |
| 57 | + prev_year = year |
| 58 | + if prev_year - prev_out == 1: |
| 59 | + s = '{}-{}'.format(s, prev_year) |
| 60 | + elif prev_year - prev_out > 1: |
| 61 | + s = '{}, {}'.format(s, prev_year) |
| 62 | + return s |
| 63 | + |
| 64 | + |
| 65 | +authors = read_authors('{}/../AUTHORS'.format(root)) |
| 66 | + |
| 67 | +process = Popen(['git', 'log', '--follow', sys.argv[1]], stdout=PIPE, |
| 68 | + stderr=PIPE) |
| 69 | +stdout, stderr = process.communicate() |
| 70 | +committers = parse_git_log(stdout, authors) |
| 71 | + |
| 72 | +prefix = 'Copyright' |
| 73 | +for name, years in committers.items(): |
| 74 | + print('{} {} {}'.format(prefix, pretty_years(years), name)) |
| 75 | + prefix = ' ' * len(prefix) |
| 76 | +print() |
0 commit comments