##// END OF EJS Templates
Merge stable
Mads Kiilerich -
r6709:a48802bf merge default
parent child Browse files
Show More
@@ -0,0 +1,253 b''
1 #!/usr/bin/env python2
2 # -*- coding: utf-8 -*-
3
4 """
5 Kallithea script for maintaining contributor lists from version control
6 history.
7
8 This script and the data in it is a best effort attempt at reverse engineering
9 previous attributions and correlate that with version control history while
10 preserving all existing copyright statements and attribution. This script is
11 processing and summarizing information found elsewhere - it is not by itself
12 making any claims. Comments in the script are an attempt at reverse engineering
13 possible explanations - they are not showing any intent or confirming it is
14 correct.
15
16 Three files are generated / modified by this script:
17
18 kallithea/templates/about.html claims to show copyright holders, and the GPL
19 license requires such existing "legal notices" to be preserved. We also try to
20 keep it updated with copyright holders, but do not claim it is a correct list.
21
22 CONTRIBUTORS has the purpose of giving credit where credit is due and list all
23 the contributor names in the source.
24
25 kallithea/templates/base/base.html contains the copyright years in the page
26 footer.
27
28 Both make a best effort of listing all copyright holders, but revision control
29 history might be a better and more definitive source.
30
31 Contributors are sorted "fairly" by copyright year and amount of
32 contribution.
33
34 New contributors are listed, without considering if the contribution contains
35 copyrightable work.
36
37 When the copyright might belong to a different legal entity than the
38 contributor, the legal entity is given credit too.
39 """
40
41
42 # Some committers are so wrong that it doesn't point at any contributor:
43 total_ignore = set()
44 total_ignore.add('*** failed to import extension hggit: No module named hggit')
45 total_ignore.add('<>')
46
47 # Normalize some committer names where people have contributed under different
48 # names or email addresses:
49 name_fixes = {}
50 name_fixes['Andrew Shadura'] = "Andrew Shadura <andrew@shadura.me>"
51 name_fixes['aparkar'] = "Aparkar <aparkar@icloud.com>"
52 name_fixes['Aras Pranckevicius'] = "Aras Pranckevičius <aras@unity3d.com>"
53 name_fixes['Augosto Hermann'] = "Augusto Herrmann <augusto.herrmann@planejamento.gov.br>"
54 name_fixes['"Bradley M. Kuhn" <bkuhn@ebb.org>'] = "Bradley M. Kuhn <bkuhn@sfconservancy.org>"
55 name_fixes['dmitri.kuznetsov'] = "Dmitri Kuznetsov"
56 name_fixes['Dmitri Kuznetsov'] = "Dmitri Kuznetsov"
57 name_fixes['domruf'] = "Dominik Ruf <dominikruf@gmail.com>"
58 name_fixes['Ingo von borstel'] = "Ingo von Borstel <kallithea@planetmaker.de>"
59 name_fixes['Jan Heylen'] = "Jan Heylen <heyleke@gmail.com>"
60 name_fixes['Jason F. Harris'] = "Jason Harris <jason@jasonfharris.com>"
61 name_fixes['Jelmer Vernooij'] = "Jelmer Vernooij <jelmer@samba.org>"
62 name_fixes['jfh <jason@jasonfharris.com>'] = "Jason Harris <jason@jasonfharris.com>"
63 name_fixes['Leonardo Carneiro<leonardo@unity3d.com>'] = "Leonardo Carneiro <leonardo@unity3d.com>"
64 name_fixes['leonardo'] = "Leonardo Carneiro <leonardo@unity3d.com>"
65 name_fixes['Leonardo <leo@unity3d.com>'] = "Leonardo Carneiro <leonardo@unity3d.com>"
66 name_fixes['Les Peabody'] = "Les Peabody <lpeabody@gmail.com>"
67 name_fixes['"Lorenzo M. Catucci" <lorenzo@sancho.ccd.uniroma2.it>'] = "Lorenzo M. Catucci <lorenzo@sancho.ccd.uniroma2.it>"
68 name_fixes['Lukasz Balcerzak'] = "Łukasz Balcerzak <lukaszbalcerzak@gmail.com>"
69 name_fixes['mao <mao@lins.fju.edu.tw>'] = "Ching-Chen Mao <mao@lins.fju.edu.tw>"
70 name_fixes['marcink'] = "Marcin Kuźmiński <marcin@python-works.com>"
71 name_fixes['Marcin Kuzminski'] = "Marcin Kuźmiński <marcin@python-works.com>"
72 name_fixes['nansenat16@null.tw'] = "nansenat16 <nansenat16@null.tw>"
73 name_fixes['Peter Vitt'] = "Peter Vitt <petervitt@web.de>"
74 name_fixes['philip.j@hostdime.com'] = "Philip Jameson <philip.j@hostdime.com>"
75 name_fixes['Søren Løvborg'] = "Søren Løvborg <sorenl@unity3d.com>"
76 name_fixes['Thomas De Schampheleire'] = "Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>"
77 name_fixes['Weblate'] = "<>"
78 name_fixes['xpol'] = "xpol <xpolife@gmail.com>"
79
80
81 # Some committer email address domains that indicate that another entity might
82 # hold some copyright too:
83 domain_extra = {}
84 domain_extra['unity3d.com'] = "Unity Technologies"
85 domain_extra['rhodecode.com'] = "RhodeCode GmbH"
86
87 # Repository history show some old contributions that traditionally hasn't been
88 # listed in about.html - preserve that:
89 no_about = set(total_ignore)
90 # The following contributors were traditionally not listed in about.html and it
91 # seems unclear if the copyright is personal or belongs to a company.
92 no_about.add(('Thayne Harbaugh <thayne@fusionio.com>', '2011'))
93 no_about.add(('Dies Koper <diesk@fast.au.fujitsu.com>', '2012'))
94 no_about.add(('Erwin Kroon <e.kroon@smartmetersolutions.nl>', '2012'))
95 no_about.add(('Vincent Caron <vcaron@bearstech.com>', '2012'))
96 # These contributors' contributions might be too small to be copyrightable:
97 no_about.add(('philip.j@hostdime.com', '2012'))
98 no_about.add(('Stefan Engel <mail@engel-stefan.de>', '2012'))
99 no_about.add(('Ton Plomp <tcplomp@gmail.com>', '2013'))
100 # Was reworked and contributed later and shadowed by other contributions:
101 no_about.add(('Sean Farley <sean.michael.farley@gmail.com>', '2013'))
102
103 # Preserve contributors listed in about.html but not appearing in repository
104 # history:
105 other_about = [
106 ("2011", "Aparkar <aparkar@icloud.com>"),
107 ("2010", "RhodeCode GmbH"),
108 ("2011", "RhodeCode GmbH"),
109 ("2012", "RhodeCode GmbH"),
110 ("2013", "RhodeCode GmbH"),
111 ]
112
113 # Preserve contributors listed in CONTRIBUTORS but not appearing in repository
114 # history:
115 other_contributors = [
116 ("", "Andrew Kesterson <andrew@aklabs.net>"),
117 ("", "cejones"),
118 ("", "David A. Sjøen <david.sjoen@westcon.no>"),
119 ("", "James Rhodes <jrhodes@redpointsoftware.com.au>"),
120 ("", "Jonas Oberschweiber <jonas.oberschweiber@d-velop.de>"),
121 ("", "larikale"),
122 ("", "RhodeCode GmbH"),
123 ("", "Sebastian Kreutzberger <sebastian@rhodecode.com>"),
124 ("", "Steve Romanow <slestak989@gmail.com>"),
125 ("", "SteveCohen"),
126 ("", "Thomas <thomas@rhodecode.com>"),
127 ("", "Thomas Waldmann <tw-public@gmx.de>"),
128 ]
129
130
131 import os
132 import re
133 from collections import defaultdict
134
135
136 def sortkey(x):
137 """Return key for sorting contributors "fairly":
138 * latest contribution
139 * first contribution
140 * number of contribution years
141 * name (with some unicode normalization)
142 The entries must be 2-tuples of a list of string years and the unicode name"""
143 return (x[0] and -int(x[0][-1]),
144 x[0] and int(x[0][0]),
145 -len(x[0]),
146 x[1].decode('utf8').lower().replace(u'\xe9', u'e').replace(u'\u0142', u'l')
147 )
148
149
150 def nice_years(l, dash='-', join=' '):
151 """Convert a list of years into brief range like '1900-1901, 1921'."""
152 if not l:
153 return ''
154 start = end = int(l[0])
155 ranges = []
156 for year in l[1:] + [0]:
157 year = int(year)
158 if year == end + 1:
159 end = year
160 continue
161 if start == end:
162 ranges.append('%s' % start)
163 else:
164 ranges.append('%s%s%s' % (start, dash, end))
165 start = end = year
166 assert start == 0 and end == 0, (start, end)
167 return join.join(ranges)
168
169
170 def insert_entries(
171 filename,
172 all_entries,
173 no_entries,
174 domain_extra,
175 split_re,
176 normalize_name,
177 format_f):
178 """Update file with contributor information.
179 all_entries: list of tuples with year and name
180 no_entries: set of names or name and year tuples to ignore
181 domain_extra: map domain name to extra credit name
182 split_re: regexp matching the part of file to rewrite
183 normalize_name: function to normalize names for grouping and display
184 format_f: function formatting year list and name to a string
185 """
186 name_years = defaultdict(set)
187
188 for year, name in all_entries:
189 if name in no_entries or (name, year) in no_entries:
190 continue
191 domain = name.split('@', 1)[-1].rstrip('>')
192 if domain in domain_extra:
193 name_years[domain_extra[domain]].add(year)
194 name_years[normalize_name(name)].add(year)
195
196 l = [(list(sorted(year for year in years if year)), name)
197 for name, years in name_years.items()]
198 l.sort(key=sortkey)
199
200 with file(filename) as f:
201 pre, post = re.split(split_re, f.read())
202
203 with file(filename, 'w') as f:
204 f.write(pre +
205 ''.join(format_f(years, name) for years, name in l) +
206 post)
207
208
209 def main():
210 repo_entries = [
211 (year, name_fixes.get(name) or name_fixes.get(name.rsplit('<', 1)[0].strip()) or name)
212 for year, name in
213 (line.strip().split(' ', 1)
214 for line in os.popen("""hg log -r '::.' -T '{date(date,"%Y")} {author}\n'""").readlines())
215 ]
216
217 insert_entries(
218 filename='kallithea/templates/about.html',
219 all_entries=repo_entries + other_about,
220 no_entries=no_about,
221 domain_extra=domain_extra,
222 split_re=r'(?: <li>Copyright &copy; [^\n]*</li>\n)*',
223 normalize_name=lambda name: name.split('<', 1)[0].strip(),
224 format_f=lambda years, name: ' <li>Copyright &copy; %s, %s</li>\n' % (nice_years(years, '&ndash;', ', '), name),
225 )
226
227 insert_entries(
228 filename='CONTRIBUTORS',
229 all_entries=repo_entries + other_contributors,
230 no_entries=total_ignore,
231 domain_extra=domain_extra,
232 split_re=r'(?: [^\n]*\n)*',
233 normalize_name=lambda name: name,
234 format_f=lambda years, name: (' %s%s%s\n' % (name, ' ' if years else '', nice_years(years))),
235 )
236
237 insert_entries(
238 filename='kallithea/templates/base/base.html',
239 all_entries=repo_entries,
240 no_entries=total_ignore,
241 domain_extra={},
242 split_re=r'(?<=&copy;) .* (?=by various authors)',
243 normalize_name=lambda name: '',
244 format_f=lambda years, name: ' ' + nice_years(years, '&ndash;', ', ') + ' ',
245 )
246
247
248 if __name__ == '__main__':
249 main()
250
251
252 # To list new contributors since last tagging:
253 # { hg log -r '::tagged()' -T ' {author}\n {author}\n'; hg log -r '::.' -T ' {author}\n' | sort | uniq; } | sort | uniq -u
@@ -1,3 +1,4 b''
1 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
@@ -64,3 +64,4 b' 14f488a5dc4ca6647bc6acf12534fd137e968aa8'
64 9b3e9e242f5c97cc0c7657e5ac93dce7de61ca16 0.3
64 9b3e9e242f5c97cc0c7657e5ac93dce7de61ca16 0.3
65 9bf8eb837e785b6856ccfac264e977ce3ebe1535 0.3.1
65 9bf8eb837e785b6856ccfac264e977ce3ebe1535 0.3.1
66 a84d40e9481fcea4dafadee86b03f0dd401527d6 0.3.2
66 a84d40e9481fcea4dafadee86b03f0dd401527d6 0.3.2
67 64ea7ea0923618a0c117acebb816a6f0d162bfdb 0.3.3
@@ -1,18 +1,30 b''
1 List of contributors to Kallithea project:
1 List of contributors to Kallithea project:
2
2
3 Mads Kiilerich <madski@unity3d.com> 2012-2016
3 Mads Kiilerich <madski@unity3d.com> 2012-2017
4 Unity Technologies 2012-2017
5 Andrew Shadura <andrew@shadura.me> 2012 2014-2017
6 Dominik Ruf <dominikruf@gmail.com> 2012 2014-2017
7 Thomas De Schampheleire <thomas.de.schampheleire@gmail.com> 2014-2017
8 Søren Løvborg <sorenl@unity3d.com> 2015-2017
9 Sam Jaques <sam.jaques@me.com> 2015 2017
10 Asterios Dimitriou <steve@pci.gr> 2016-2017
11 Mads Kiilerich <mads@kiilerich.com> 2016-2017
12 Alessandro Molina <alessandro.molina@axant.it> 2017
13 Anton Schur <tonich.sh@gmail.com> 2017
14 Ching-Chen Mao <mao@lins.fju.edu.tw> 2017
15 Eivind Tagseth <eivindt@gmail.com> 2017
16 FUJIWARA Katsunori <foozy@lares.dti.ne.jp> 2017
17 Karl Goetz <karl@kgoetz.id.au> 2017
18 Marko Semet <markosemet@googlemail.com> 2017
19 Viktar Vauchkevich <victorenator@gmail.com> 2017
4 Takumi IINO <trot.thunder@gmail.com> 2012-2016
20 Takumi IINO <trot.thunder@gmail.com> 2012-2016
5 Unity Technologies 2012-2016
6 Andrew Shadura <andrew@shadura.me> 2012 2014-2016
7 Dominik Ruf <dominikruf@gmail.com> 2012 2014-2016
8 Thomas De Schampheleire <thomas.de.schampheleire@gmail.com> 2014-2016
9 Étienne Gilli <etienne.gilli@gmail.com> 2015-2016
21 Étienne Gilli <etienne.gilli@gmail.com> 2015-2016
10 Jan Heylen <heyleke@gmail.com> 2015-2016
22 Jan Heylen <heyleke@gmail.com> 2015-2016
11 Robert Martinez <ntttq@inboxen.org> 2015-2016
23 Robert Martinez <ntttq@inboxen.org> 2015-2016
12 Robert Rauch <mail@robertrauch.de> 2015-2016
24 Robert Rauch <mail@robertrauch.de> 2015-2016
13 Søren Løvborg <sorenl@unity3d.com> 2015-2016
14 Angel Ezquerra <angel.ezquerra@gmail.com> 2016
25 Angel Ezquerra <angel.ezquerra@gmail.com> 2016
15 Asterios Dimitriou <steve@pci.gr> 2016
26 Anton Shestakov <av6@dwimlabs.net> 2016
27 Brandon Jones <bjones14@gmail.com> 2016
16 Kateryna Musina <kateryna@unity3d.com> 2016
28 Kateryna Musina <kateryna@unity3d.com> 2016
17 Konstantin Veretennicov <kveretennicov@gmail.com> 2016
29 Konstantin Veretennicov <kveretennicov@gmail.com> 2016
18 Oscar Curero <oscar@naiandei.net> 2016
30 Oscar Curero <oscar@naiandei.net> 2016
@@ -49,7 +61,6 b' List of contributors to Kallithea projec'
49 Niemand Jedermann <predatorix@web.de> 2015
61 Niemand Jedermann <predatorix@web.de> 2015
50 Peter Vitt <petervitt@web.de> 2015
62 Peter Vitt <petervitt@web.de> 2015
51 Ronny Pfannschmidt <opensource@ronnypfannschmidt.de> 2015
63 Ronny Pfannschmidt <opensource@ronnypfannschmidt.de> 2015
52 Sam Jaques <sam.jaques@me.com> 2015
53 Tuux <tuxa@galaxie.eu.org> 2015
64 Tuux <tuxa@galaxie.eu.org> 2015
54 Viktar Palstsiuk <vipals@gmail.com> 2015
65 Viktar Palstsiuk <vipals@gmail.com> 2015
55 Ante Ilic <ante@unity3d.com> 2014
66 Ante Ilic <ante@unity3d.com> 2014
@@ -27,19 +27,30 b''
27 necessarily limited to the following:</p>
27 necessarily limited to the following:</p>
28 <ul>
28 <ul>
29
29
30 <li>Copyright &copy; 2012&ndash;2016, Mads Kiilerich</li>
30 <li>Copyright &copy; 2012&ndash;2017, Mads Kiilerich</li>
31 <li>Copyright &copy; 2012&ndash;2017, Unity Technologies</li>
32 <li>Copyright &copy; 2012, 2014&ndash;2017, Andrew Shadura</li>
33 <li>Copyright &copy; 2012, 2014&ndash;2017, Dominik Ruf</li>
34 <li>Copyright &copy; 2014&ndash;2017, Thomas De Schampheleire</li>
35 <li>Copyright &copy; 2015&ndash;2017, Søren Løvborg</li>
36 <li>Copyright &copy; 2015, 2017, Sam Jaques</li>
37 <li>Copyright &copy; 2016&ndash;2017, Asterios Dimitriou</li>
38 <li>Copyright &copy; 2017, Alessandro Molina</li>
39 <li>Copyright &copy; 2017, Anton Schur</li>
40 <li>Copyright &copy; 2017, Ching-Chen Mao</li>
41 <li>Copyright &copy; 2017, Eivind Tagseth</li>
42 <li>Copyright &copy; 2017, FUJIWARA Katsunori</li>
43 <li>Copyright &copy; 2017, Karl Goetz</li>
44 <li>Copyright &copy; 2017, Marko Semet</li>
45 <li>Copyright &copy; 2017, Viktar Vauchkevich</li>
31 <li>Copyright &copy; 2012&ndash;2016, Takumi IINO</li>
46 <li>Copyright &copy; 2012&ndash;2016, Takumi IINO</li>
32 <li>Copyright &copy; 2012&ndash;2016, Unity Technologies</li>
33 <li>Copyright &copy; 2012, 2014&ndash;2016, Andrew Shadura</li>
34 <li>Copyright &copy; 2012, 2014&ndash;2016, Dominik Ruf</li>
35 <li>Copyright &copy; 2014&ndash;2016, Thomas De Schampheleire</li>
36 <li>Copyright &copy; 2015&ndash;2016, Étienne Gilli</li>
47 <li>Copyright &copy; 2015&ndash;2016, Étienne Gilli</li>
37 <li>Copyright &copy; 2015&ndash;2016, Jan Heylen</li>
48 <li>Copyright &copy; 2015&ndash;2016, Jan Heylen</li>
38 <li>Copyright &copy; 2015&ndash;2016, Robert Martinez</li>
49 <li>Copyright &copy; 2015&ndash;2016, Robert Martinez</li>
39 <li>Copyright &copy; 2015&ndash;2016, Robert Rauch</li>
50 <li>Copyright &copy; 2015&ndash;2016, Robert Rauch</li>
40 <li>Copyright &copy; 2015&ndash;2016, Søren Løvborg</li>
41 <li>Copyright &copy; 2016, Angel Ezquerra</li>
51 <li>Copyright &copy; 2016, Angel Ezquerra</li>
42 <li>Copyright &copy; 2016, Asterios Dimitriou</li>
52 <li>Copyright &copy; 2016, Anton Shestakov</li>
53 <li>Copyright &copy; 2016, Brandon Jones</li>
43 <li>Copyright &copy; 2016, Kateryna Musina</li>
54 <li>Copyright &copy; 2016, Kateryna Musina</li>
44 <li>Copyright &copy; 2016, Konstantin Veretennicov</li>
55 <li>Copyright &copy; 2016, Konstantin Veretennicov</li>
45 <li>Copyright &copy; 2016, Oscar Curero</li>
56 <li>Copyright &copy; 2016, Oscar Curero</li>
@@ -76,7 +87,6 b''
76 <li>Copyright &copy; 2015, Niemand Jedermann</li>
87 <li>Copyright &copy; 2015, Niemand Jedermann</li>
77 <li>Copyright &copy; 2015, Peter Vitt</li>
88 <li>Copyright &copy; 2015, Peter Vitt</li>
78 <li>Copyright &copy; 2015, Ronny Pfannschmidt</li>
89 <li>Copyright &copy; 2015, Ronny Pfannschmidt</li>
79 <li>Copyright &copy; 2015, Sam Jaques</li>
80 <li>Copyright &copy; 2015, Tuux</li>
90 <li>Copyright &copy; 2015, Tuux</li>
81 <li>Copyright &copy; 2015, Viktar Palstsiuk</li>
91 <li>Copyright &copy; 2015, Viktar Palstsiuk</li>
82 <li>Copyright &copy; 2014, Ante Ilic</li>
92 <li>Copyright &copy; 2014, Ante Ilic</li>
General Comments 0
You need to be logged in to leave comments. Login now