Brian Silverman | 7c33ab2 | 2018-08-04 17:14:51 -0700 | [diff] [blame^] | 1 | #!/usr/bin/env python |
| 2 | from subprocess import check_output as run |
| 3 | from datetime import datetime |
| 4 | from itertools import groupby |
| 5 | from operator import itemgetter |
| 6 | import re |
| 7 | import magic |
| 8 | |
| 9 | def authors(filename): |
| 10 | log = run(['git', 'log', '--follow', |
| 11 | '--date=short','--format=%aN%x09%ad', filename], |
| 12 | universal_newlines=True) |
| 13 | for line in log.splitlines(): |
| 14 | author, date = line.split('\t') |
| 15 | if author != 'fix-copyright.py': |
| 16 | yield author, datetime.strptime(date, '%Y-%m-%d') |
| 17 | |
| 18 | def new_copyright(filename, previous): |
| 19 | def f(): |
| 20 | au = list(authors(filename)) |
| 21 | alldates = map(itemgetter(1), au) |
| 22 | aup = sorted(au + map(lambda a: (a, None), previous), key=itemgetter(0)) |
| 23 | for author, records in groupby(aup, itemgetter(0)): |
| 24 | dates = filter(None, map(itemgetter(1), records)) |
| 25 | if not dates: dates = alldates |
| 26 | start = min(dates) |
| 27 | end = max(dates) |
| 28 | fmt = '{0}' if start.year == end.year else '{0}-{1}' |
| 29 | line = 'Copyright ' + fmt.format(start.year, end.year) + ' ' + author |
| 30 | key = (start, author) |
| 31 | yield key, line |
| 32 | return map(itemgetter(1), sorted(f())) |
| 33 | |
| 34 | def fix_copyright(filename): |
| 35 | # Find copyright block in original file |
| 36 | prefix = set() |
| 37 | names = [] |
| 38 | lines = [] |
| 39 | with open(filename, 'r') as f: |
| 40 | content = list(f) |
| 41 | for i, line in enumerate(content[:15]): |
| 42 | m = re.match(r'^(?P<prefix>\W*)(\(c\))?\s*?copyright\s*(\(c\))?\s+\d{4}(\s*-\s*\d{4})?\s+(?P<name>.+?)\s*$', line, re.IGNORECASE) |
| 43 | if m: |
| 44 | d = m.groupdict() |
| 45 | prefix.add(d['prefix']) |
| 46 | lines.append(i) |
| 47 | names.append(d['name'].strip()) |
| 48 | if len(prefix) != 1: |
| 49 | print 'Not found:', filename |
| 50 | return |
| 51 | prefix = list(prefix)[0] |
| 52 | |
| 53 | print filename |
| 54 | new = iter(new_copyright(filename, names)) |
| 55 | with open(filename, 'w') as f: |
| 56 | for i, line in enumerate(content): |
| 57 | if i in lines: |
| 58 | for repl in new: |
| 59 | print >>f, prefix + repl |
| 60 | else: |
| 61 | print >>f, line, |
| 62 | pass |
| 63 | |
| 64 | def all_files(): |
| 65 | ls = run(['git', 'ls-files'], universal_newlines=True) |
| 66 | for filename in ls.splitlines(): |
| 67 | if magic.from_file(filename, mime=True).split('/')[0] == 'text': |
| 68 | yield filename |
| 69 | |
| 70 | for f in all_files(): |
| 71 | fix_copyright(f) |