1
#!/usr/bin/env python2.6
2
# -*- coding: utf-8 -*-
6
import bzrlib.workingtree
9
from datetime import datetime
12
GPL_TAIL = """# This program is free software under the terms of GPLv2. For more
13
# information, see the file named COPYING distributed with this project.
15
IGNORE_DIRS = ['.bzr', 'build', 'dist']
16
NO_GPL_FILES = ['convenience_scripts/backup.py']
17
BRANCH_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
21
workingtree = bzrlib.workingtree.WorkingTree.open(BRANCH_PATH)
22
workingtree.lock_read()
24
paths = [t[0] for t in workingtree.inventory.entries()]
28
if path.endswith(".py"):
29
treat_file(os.path.join(BRANCH_PATH, path))
31
def uses_bzrlib(function):
32
@functools.wraps(function)
33
def new_function(*args, **kwargs):
34
with bzrlib.initialize():
35
return function(*args, **kwargs)
38
def canonical_author_name(authorname):
39
if authorname in ['David Lowe <david@david-laptop>', 'David D Lowe <daviddlowe@noemail.com>']:
40
return 'David D Lowe <daviddlowe.flimm@gmail.com>'
45
def authors_dict_for_file(filename):
46
filename = os.path.relpath(filename, BRANCH_PATH)
48
workingtree = bzrlib.workingtree.WorkingTree.open(BRANCH_PATH)
49
file_id = workingtree.path2id(filename)
50
branch = bzrlib.branch.Branch.open(BRANCH_PATH)
57
repo = branch.repository
58
revno_map = branch.get_revision_id_to_revno_map()
62
for rev_id, depth, revno, end_of_merge in branch.iter_merge_sorted_revisions(direction='forward'):
63
revision = repo.get_revision(rev_id)
64
revtree = repo.revision_tree(rev_id)
67
if lastrevtree is None:
68
modified_file = revtree.has_filename(filename)
70
changes = revtree.changes_from(lastrevtree)
71
modified_file = changes.touches_file_id(file_id)
75
for author in revision.get_apparent_authors():
76
tup = authors.get(canonical_author_name(author), (0, set()))
77
tup[1].add(datetime.fromtimestamp(revision.timestamp).year)
78
tup = (tup[0] + 1, tup[1])
79
authors[canonical_author_name(author)] = tup
88
def generate_copyright_header(filename):
89
authors = authors_dict_for_file(filename)
90
tuples = [(value[0], key, value[1]) for key, value in authors.items()]
91
# each tuple is (count, authorname, set_of_years)
92
tuples.sort(reverse=True)
95
output.append(u"# Copyright © %s %s" % (extract_name(t[1]), convert_years_to_string(t[2])))
96
if os.path.relpath(filename, BRANCH_PATH) in NO_GPL_FILES:
97
return "\n".join(output) + "\n"
99
return "\n".join(output) + "\n" + GPL_TAIL + "\n"
101
def extract_name(committer):
102
return re.sub(r"<.+?>", "", committer).strip()
104
def convert_years_to_string(set_of_years):
105
years = sorted(list(set_of_years))
107
storedyear = None # when swallowed by -
111
output.append(str(year))
112
elif (storedyear is not None and year == storedyear + 1) or year == previousyear + 1:
115
if storedyear is not None:
116
output.extend(["-", str(storedyear)])
118
output.append(", " + str(year))
121
output.append("-" + str(storedyear))
122
return "".join(output)
125
def treat_file(filename):
126
contents = [line.decode("utf-8") for line in open(filename, 'r').readlines()]
130
if cursor < len(contents) and contents[cursor].startswith("#!"):
131
output.append(contents[cursor])
133
if cursor < len(contents) and contents[cursor].strip() == "# -*- coding: utf-8 -*-":
134
output.append(contents[cursor])
137
output.append("# -*- coding: utf-8 -*-\n")
138
gen = generate_copyright_header(filename)
141
while cursor < len(contents) and (contents[cursor].startswith(u"# Copyright © ") or \
142
contents[cursor][:-1] in GPL_TAIL.split("\n")):
145
output.extend(contents[cursor:])
147
open(filename, 'w').write(u"".join(output).encode("utf-8"))
149
if __name__ == "__main__":