##// END OF EJS Templates
make-release: import version and copyright updates from default branch (dba4e770d4b6)...
Thomas De Schampheleire -
r7136:d06c0566 stable
parent child Browse files
Show More
@@ -1,63 +1,71 b''
1 #!/bin/bash
1 #!/bin/bash
2 set -e
2 set -e
3 set -x
3 set -x
4
4
5 echo "Checking tools needed for uploading stuff"
5 echo "Install/verify tools needed for building and uploading stuff"
6 pip freeze | grep '^Sphinx==' || pip install Sphinx
6 pip install --upgrade -e .
7 pip freeze | grep '^Sphinx-PyPI-upload==' || pip install Sphinx-PyPI-upload
7 pip install --upgrade Sphinx Sphinx-PyPI-upload
8
9 echo "Cleanup and update copyrights ... and clean checkout"
10 scripts/whitespacecleanup.sh
11 scripts/update-copyrights.py
12 hg up -cr .
8
13
9 echo "Verifying everything can build"
14 echo "Make release build from clean checkout in build/"
10 hg purge --all dist
15 rm -rf build dist
11 python2 setup.py build_sphinx
16 hg archive build
12 python2 setup.py compile_catalog # TODO: check for errors
17 cd build
18
19 echo "Check MANIFEST.in"
20 sed -e 's/[^ ]*[ ]*\([^ ]*\).*/\1/g' MANIFEST.in | grep -v '^node_modules/bootstrap\|^kallithea/public/css/style.css' | xargs ls -lad
21
22 echo "Build dist"
23 python2 setup.py compile_catalog
13 python2 setup.py sdist
24 python2 setup.py sdist
14
25
15 echo "Verifying VERSION from kallithea/__init__.py"
26 echo "Verify VERSION from kallithea/__init__.py"
16 namerel=$(cd dist && echo Kallithea-*.tar.gz)
27 namerel=$(cd dist && echo Kallithea-*.tar.gz)
17 namerel=${namerel%.tar.gz}
28 namerel=${namerel%.tar.gz}
18 version=${namerel#Kallithea-}
29 version=${namerel#Kallithea-}
30 ls -l $(pwd)/dist/$namerel.tar.gz
19 echo "Releasing Kallithea $version in directory $namerel"
31 echo "Releasing Kallithea $version in directory $namerel"
20 echo "Verifying current revision is tagged for $version"
21 hg log -r "'$version'&." | grep .
22
32
23 echo "Cleaning before making release build"
33 echo "Verify dist file content"
24 hg up -c .
34 ! tar tf dist/Kallithea-$version.tar.gz | grep "$namerel/node_modules/bootstrap/\$"
25 hg revert -a -r null
35
26 hg up -C "'$version'&."
36 echo "Verify docs build"
27 hg purge --all
37 python2 setup.py build_sphinx # not used yet ... but we want to make sure it builds
38
39 cat - << EOT
28
40
29 echo "Building dist file"
41 Now, make sure
30 python2 setup.py compile_catalog
42 * the copyright and contributor lists have been updated
31 python2 setup.py sdist
43 * all tests are passing
44 * release note is ready
45 * announcement is ready
46 * source has been pushed to https://kallithea-scm.org/repos/kallithea
32
47
33 echo "Verifying dist file content"
48 EOT
34 tar tf dist/Kallithea-*.tar.gz | sed "s|^$namerel/||" | LANG=C sort > scripts/manifest
35 hg diff
36 hg up -c . # fail if manifest changed
37
49
38 echo "Now, make sure"
50 echo "Verify current revision is tagged for $version"
39 echo "* the copyright and contributor lists have been updated"
51 hg log -r "'$version'&." | grep .
40 echo "* all tests are passing"
41 echo "* release note is ready"
42 echo "* announcement is ready"
43 echo "* source has been pushed to https://kallithea-scm.org/repos/kallithea"
44 echo
45
52
46 echo -n "Enter \"pypi\" to upload Kallithea $version to pypi: "
53 echo -n "Enter \"pypi\" to upload Kallithea $version to pypi: "
47 read answer
54 read answer
48 [ "$answer" = "pypi" ]
55 [ "$answer" = "pypi" ]
49 extraargs=${EMAIL:+--identity=$EMAIL}
50 python2 setup.py sdist upload --sign $extraargs
51 xdg-open https://pypi.python.org/pypi/Kallithea
52
56
53 echo "Uploading docs to pypi"
57 echo "Upload docs to pypi"
54 # See https://wiki.python.org/moin/PyPiDocumentationHosting
58 # See https://wiki.python.org/moin/PyPiDocumentationHosting
55 python2 setup.py build_sphinx upload_sphinx
59 python2 setup.py build_sphinx upload_sphinx
56 xdg-open https://pythonhosted.org/Kallithea/
60 xdg-open https://pythonhosted.org/Kallithea/
57 xdg-open http://packages.python.org/Kallithea/installation.html
61 xdg-open http://packages.python.org/Kallithea/installation.html
58
62
59 echo "Rebuilding readthedocs for docs.kallithea-scm.org"
63 echo "Rebuild readthedocs for docs.kallithea-scm.org"
60 xdg-open https://readthedocs.org/projects/kallithea/
64 xdg-open https://readthedocs.org/projects/kallithea/
61 curl -X POST http://readthedocs.org/build/kallithea
65 curl -X POST http://readthedocs.org/build/kallithea
62 xdg-open https://readthedocs.org/builds/kallithea/
66 xdg-open https://readthedocs.org/builds/kallithea/
63 xdg-open http://docs.kallithea-scm.org/en/latest/ # or whatever the branch is
67 xdg-open http://docs.kallithea-scm.org/en/latest/ # or whatever the branch is
68
69 extraargs=${EMAIL:+--identity=$EMAIL}
70 python2 setup.py sdist upload --sign $extraargs
71 xdg-open https://pypi.python.org/pypi/Kallithea
@@ -1,253 +1,253 b''
1 #!/usr/bin/env python2
1 #!/usr/bin/env python2
2 # -*- coding: utf-8 -*-
2 # -*- coding: utf-8 -*-
3
3
4 """
4 """
5 Kallithea script for maintaining contributor lists from version control
5 Kallithea script for maintaining contributor lists from version control
6 history.
6 history.
7
7
8 This script and the data in it is a best effort attempt at reverse engineering
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
9 previous attributions and correlate that with version control history while
10 preserving all existing copyright statements and attribution. This script is
10 preserving all existing copyright statements and attribution. This script is
11 processing and summarizing information found elsewhere - it is not by itself
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
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
13 possible explanations - they are not showing any intent or confirming it is
14 correct.
14 correct.
15
15
16 Three files are generated / modified by this script:
16 Three files are generated / modified by this script:
17
17
18 kallithea/templates/about.html claims to show copyright holders, and the GPL
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
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.
20 keep it updated with copyright holders, but do not claim it is a correct list.
21
21
22 CONTRIBUTORS has the purpose of giving credit where credit is due and list all
22 CONTRIBUTORS has the purpose of giving credit where credit is due and list all
23 the contributor names in the source.
23 the contributor names in the source.
24
24
25 kallithea/templates/base/base.html contains the copyright years in the page
25 kallithea/templates/base/base.html contains the copyright years in the page
26 footer.
26 footer.
27
27
28 Both make a best effort of listing all copyright holders, but revision control
28 Both make a best effort of listing all copyright holders, but revision control
29 history might be a better and more definitive source.
29 history might be a better and more definitive source.
30
30
31 Contributors are sorted "fairly" by copyright year and amount of
31 Contributors are sorted "fairly" by copyright year and amount of
32 contribution.
32 contribution.
33
33
34 New contributors are listed, without considering if the contribution contains
34 New contributors are listed, without considering if the contribution contains
35 copyrightable work.
35 copyrightable work.
36
36
37 When the copyright might belong to a different legal entity than the
37 When the copyright might belong to a different legal entity than the
38 contributor, the legal entity is given credit too.
38 contributor, the legal entity is given credit too.
39 """
39 """
40
40
41
41
42 # Some committers are so wrong that it doesn't point at any contributor:
42 # Some committers are so wrong that it doesn't point at any contributor:
43 total_ignore = set()
43 total_ignore = set()
44 total_ignore.add('*** failed to import extension hggit: No module named hggit')
44 total_ignore.add('*** failed to import extension hggit: No module named hggit')
45 total_ignore.add('<>')
45 total_ignore.add('<>')
46
46
47 # Normalize some committer names where people have contributed under different
47 # Normalize some committer names where people have contributed under different
48 # names or email addresses:
48 # names or email addresses:
49 name_fixes = {}
49 name_fixes = {}
50 name_fixes['Andrew Shadura'] = "Andrew Shadura <andrew@shadura.me>"
50 name_fixes['Andrew Shadura'] = "Andrew Shadura <andrew@shadura.me>"
51 name_fixes['aparkar'] = "Aparkar <aparkar@icloud.com>"
51 name_fixes['aparkar'] = "Aparkar <aparkar@icloud.com>"
52 name_fixes['Aras Pranckevicius'] = "Aras Pranckevičius <aras@unity3d.com>"
52 name_fixes['Aras Pranckevicius'] = "Aras Pranckevičius <aras@unity3d.com>"
53 name_fixes['Augosto Hermann'] = "Augusto Herrmann <augusto.herrmann@planejamento.gov.br>"
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>"
54 name_fixes['"Bradley M. Kuhn" <bkuhn@ebb.org>'] = "Bradley M. Kuhn <bkuhn@sfconservancy.org>"
55 name_fixes['dmitri.kuznetsov'] = "Dmitri Kuznetsov"
55 name_fixes['dmitri.kuznetsov'] = "Dmitri Kuznetsov"
56 name_fixes['Dmitri Kuznetsov'] = "Dmitri Kuznetsov"
56 name_fixes['Dmitri Kuznetsov'] = "Dmitri Kuznetsov"
57 name_fixes['domruf'] = "Dominik Ruf <dominikruf@gmail.com>"
57 name_fixes['domruf'] = "Dominik Ruf <dominikruf@gmail.com>"
58 name_fixes['Ingo von borstel'] = "Ingo von Borstel <kallithea@planetmaker.de>"
58 name_fixes['Ingo von borstel'] = "Ingo von Borstel <kallithea@planetmaker.de>"
59 name_fixes['Jan Heylen'] = "Jan Heylen <heyleke@gmail.com>"
59 name_fixes['Jan Heylen'] = "Jan Heylen <heyleke@gmail.com>"
60 name_fixes['Jason F. Harris'] = "Jason Harris <jason@jasonfharris.com>"
60 name_fixes['Jason F. Harris'] = "Jason Harris <jason@jasonfharris.com>"
61 name_fixes['Jelmer Vernooij'] = "Jelmer VernooΔ³ <jelmer@samba.org>"
61 name_fixes['Jelmer Vernooij'] = "Jelmer VernooΔ³ <jelmer@samba.org>"
62 name_fixes['jfh <jason@jasonfharris.com>'] = "Jason Harris <jason@jasonfharris.com>"
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>"
63 name_fixes['Leonardo Carneiro<leonardo@unity3d.com>'] = "Leonardo Carneiro <leonardo@unity3d.com>"
64 name_fixes['leonardo'] = "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>"
65 name_fixes['Leonardo <leo@unity3d.com>'] = "Leonardo Carneiro <leonardo@unity3d.com>"
66 name_fixes['Les Peabody'] = "Les Peabody <lpeabody@gmail.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>"
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>"
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>"
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>"
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>"
71 name_fixes['Marcin Kuzminski'] = "Marcin KuΕΊmiΕ„ski <marcin@python-works.com>"
72 name_fixes['nansenat16@null.tw'] = "nansenat16 <nansenat16@null.tw>"
72 name_fixes['nansenat16@null.tw'] = "nansenat16 <nansenat16@null.tw>"
73 name_fixes['Peter Vitt'] = "Peter Vitt <petervitt@web.de>"
73 name_fixes['Peter Vitt'] = "Peter Vitt <petervitt@web.de>"
74 name_fixes['philip.j@hostdime.com'] = "Philip Jameson <philip.j@hostdime.com>"
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>"
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>"
76 name_fixes['Thomas De Schampheleire'] = "Thomas De Schampheleire <thomas.de_schampheleire@nokia.com>"
77 name_fixes['Weblate'] = "<>"
77 name_fixes['Weblate'] = "<>"
78 name_fixes['xpol'] = "xpol <xpolife@gmail.com>"
78 name_fixes['xpol'] = "xpol <xpolife@gmail.com>"
79
79
80
80
81 # Some committer email address domains that indicate that another entity might
81 # Some committer email address domains that indicate that another entity might
82 # hold some copyright too:
82 # hold some copyright too:
83 domain_extra = {}
83 domain_extra = {}
84 domain_extra['unity3d.com'] = "Unity Technologies"
84 domain_extra['unity3d.com'] = "Unity Technologies"
85 domain_extra['rhodecode.com'] = "RhodeCode GmbH"
85 domain_extra['rhodecode.com'] = "RhodeCode GmbH"
86
86
87 # Repository history show some old contributions that traditionally hasn't been
87 # Repository history show some old contributions that traditionally hasn't been
88 # listed in about.html - preserve that:
88 # listed in about.html - preserve that:
89 no_about = set(total_ignore)
89 no_about = set(total_ignore)
90 # The following contributors were traditionally not listed in about.html and it
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.
91 # seems unclear if the copyright is personal or belongs to a company.
92 no_about.add(('Thayne Harbaugh <thayne@fusionio.com>', '2011'))
92 no_about.add(('Thayne Harbaugh <thayne@fusionio.com>', '2011'))
93 no_about.add(('Dies Koper <diesk@fast.au.fujitsu.com>', '2012'))
93 no_about.add(('Dies Koper <diesk@fast.au.fujitsu.com>', '2012'))
94 no_about.add(('Erwin Kroon <e.kroon@smartmetersolutions.nl>', '2012'))
94 no_about.add(('Erwin Kroon <e.kroon@smartmetersolutions.nl>', '2012'))
95 no_about.add(('Vincent Caron <vcaron@bearstech.com>', '2012'))
95 no_about.add(('Vincent Caron <vcaron@bearstech.com>', '2012'))
96 # These contributors' contributions might be too small to be copyrightable:
96 # These contributors' contributions might be too small to be copyrightable:
97 no_about.add(('philip.j@hostdime.com', '2012'))
97 no_about.add(('philip.j@hostdime.com', '2012'))
98 no_about.add(('Stefan Engel <mail@engel-stefan.de>', '2012'))
98 no_about.add(('Stefan Engel <mail@engel-stefan.de>', '2012'))
99 no_about.add(('Ton Plomp <tcplomp@gmail.com>', '2013'))
99 no_about.add(('Ton Plomp <tcplomp@gmail.com>', '2013'))
100 # Was reworked and contributed later and shadowed by other contributions:
100 # Was reworked and contributed later and shadowed by other contributions:
101 no_about.add(('Sean Farley <sean.michael.farley@gmail.com>', '2013'))
101 no_about.add(('Sean Farley <sean.michael.farley@gmail.com>', '2013'))
102
102
103 # Preserve contributors listed in about.html but not appearing in repository
103 # Preserve contributors listed in about.html but not appearing in repository
104 # history:
104 # history:
105 other_about = [
105 other_about = [
106 ("2011", "Aparkar <aparkar@icloud.com>"),
106 ("2011", "Aparkar <aparkar@icloud.com>"),
107 ("2010", "RhodeCode GmbH"),
107 ("2010", "RhodeCode GmbH"),
108 ("2011", "RhodeCode GmbH"),
108 ("2011", "RhodeCode GmbH"),
109 ("2012", "RhodeCode GmbH"),
109 ("2012", "RhodeCode GmbH"),
110 ("2013", "RhodeCode GmbH"),
110 ("2013", "RhodeCode GmbH"),
111 ]
111 ]
112
112
113 # Preserve contributors listed in CONTRIBUTORS but not appearing in repository
113 # Preserve contributors listed in CONTRIBUTORS but not appearing in repository
114 # history:
114 # history:
115 other_contributors = [
115 other_contributors = [
116 ("", "Andrew Kesterson <andrew@aklabs.net>"),
116 ("", "Andrew Kesterson <andrew@aklabs.net>"),
117 ("", "cejones"),
117 ("", "cejones"),
118 ("", "David A. SjΓΈen <david.sjoen@westcon.no>"),
118 ("", "David A. SjΓΈen <david.sjoen@westcon.no>"),
119 ("", "James Rhodes <jrhodes@redpointsoftware.com.au>"),
119 ("", "James Rhodes <jrhodes@redpointsoftware.com.au>"),
120 ("", "Jonas Oberschweiber <jonas.oberschweiber@d-velop.de>"),
120 ("", "Jonas Oberschweiber <jonas.oberschweiber@d-velop.de>"),
121 ("", "larikale"),
121 ("", "larikale"),
122 ("", "RhodeCode GmbH"),
122 ("", "RhodeCode GmbH"),
123 ("", "Sebastian Kreutzberger <sebastian@rhodecode.com>"),
123 ("", "Sebastian Kreutzberger <sebastian@rhodecode.com>"),
124 ("", "Steve Romanow <slestak989@gmail.com>"),
124 ("", "Steve Romanow <slestak989@gmail.com>"),
125 ("", "SteveCohen"),
125 ("", "SteveCohen"),
126 ("", "Thomas <thomas@rhodecode.com>"),
126 ("", "Thomas <thomas@rhodecode.com>"),
127 ("", "Thomas Waldmann <tw-public@gmx.de>"),
127 ("", "Thomas Waldmann <tw-public@gmx.de>"),
128 ]
128 ]
129
129
130
130
131 import os
131 import os
132 import re
132 import re
133 from collections import defaultdict
133 from collections import defaultdict
134
134
135
135
136 def sortkey(x):
136 def sortkey(x):
137 """Return key for sorting contributors "fairly":
137 """Return key for sorting contributors "fairly":
138 * latest contribution
138 * latest contribution
139 * first contribution
139 * first contribution
140 * number of contribution years
140 * number of contribution years
141 * name (with some unicode normalization)
141 * name (with some unicode normalization)
142 The entries must be 2-tuples of a list of string years and the unicode name"""
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]),
143 return (x[0] and -int(x[0][-1]),
144 x[0] and int(x[0][0]),
144 x[0] and int(x[0][0]),
145 -len(x[0]),
145 -len(x[0]),
146 x[1].decode('utf8').lower().replace(u'\xe9', u'e').replace(u'\u0142', u'l')
146 x[1].decode('utf8').lower().replace(u'\xe9', u'e').replace(u'\u0142', u'l')
147 )
147 )
148
148
149
149
150 def nice_years(l, dash='-', join=' '):
150 def nice_years(l, dash='-', join=' '):
151 """Convert a list of years into brief range like '1900-1901, 1921'."""
151 """Convert a list of years into brief range like '1900-1901, 1921'."""
152 if not l:
152 if not l:
153 return ''
153 return ''
154 start = end = int(l[0])
154 start = end = int(l[0])
155 ranges = []
155 ranges = []
156 for year in l[1:] + [0]:
156 for year in l[1:] + [0]:
157 year = int(year)
157 year = int(year)
158 if year == end + 1:
158 if year == end + 1:
159 end = year
159 end = year
160 continue
160 continue
161 if start == end:
161 if start == end:
162 ranges.append('%s' % start)
162 ranges.append('%s' % start)
163 else:
163 else:
164 ranges.append('%s%s%s' % (start, dash, end))
164 ranges.append('%s%s%s' % (start, dash, end))
165 start = end = year
165 start = end = year
166 assert start == 0 and end == 0, (start, end)
166 assert start == 0 and end == 0, (start, end)
167 return join.join(ranges)
167 return join.join(ranges)
168
168
169
169
170 def insert_entries(
170 def insert_entries(
171 filename,
171 filename,
172 all_entries,
172 all_entries,
173 no_entries,
173 no_entries,
174 domain_extra,
174 domain_extra,
175 split_re,
175 split_re,
176 normalize_name,
176 normalize_name,
177 format_f):
177 format_f):
178 """Update file with contributor information.
178 """Update file with contributor information.
179 all_entries: list of tuples with year and name
179 all_entries: list of tuples with year and name
180 no_entries: set of names or name and year tuples to ignore
180 no_entries: set of names or name and year tuples to ignore
181 domain_extra: map domain name to extra credit name
181 domain_extra: map domain name to extra credit name
182 split_re: regexp matching the part of file to rewrite
182 split_re: regexp matching the part of file to rewrite
183 normalize_name: function to normalize names for grouping and display
183 normalize_name: function to normalize names for grouping and display
184 format_f: function formatting year list and name to a string
184 format_f: function formatting year list and name to a string
185 """
185 """
186 name_years = defaultdict(set)
186 name_years = defaultdict(set)
187
187
188 for year, name in all_entries:
188 for year, name in all_entries:
189 if name in no_entries or (name, year) in no_entries:
189 if name in no_entries or (name, year) in no_entries:
190 continue
190 continue
191 domain = name.split('@', 1)[-1].rstrip('>')
191 domain = name.split('@', 1)[-1].rstrip('>')
192 if domain in domain_extra:
192 if domain in domain_extra:
193 name_years[domain_extra[domain]].add(year)
193 name_years[domain_extra[domain]].add(year)
194 name_years[normalize_name(name)].add(year)
194 name_years[normalize_name(name)].add(year)
195
195
196 l = [(list(sorted(year for year in years if year)), name)
196 l = [(list(sorted(year for year in years if year)), name)
197 for name, years in name_years.items()]
197 for name, years in name_years.items()]
198 l.sort(key=sortkey)
198 l.sort(key=sortkey)
199
199
200 with file(filename) as f:
200 with file(filename) as f:
201 pre, post = re.split(split_re, f.read())
201 pre, post = re.split(split_re, f.read())
202
202
203 with file(filename, 'w') as f:
203 with file(filename, 'w') as f:
204 f.write(pre +
204 f.write(pre +
205 ''.join(format_f(years, name) for years, name in l) +
205 ''.join(format_f(years, name) for years, name in l) +
206 post)
206 post)
207
207
208
208
209 def main():
209 def main():
210 repo_entries = [
210 repo_entries = [
211 (year, name_fixes.get(name) or name_fixes.get(name.rsplit('<', 1)[0].strip()) or name)
211 (year, name_fixes.get(name) or name_fixes.get(name.rsplit('<', 1)[0].strip()) or name)
212 for year, name in
212 for year, name in
213 (line.strip().split(' ', 1)
213 (line.strip().split(' ', 1)
214 for line in os.popen("""hg log -r '::.' -T '{date(date,"%Y")} {author}\n'""").readlines())
214 for line in os.popen("""hg log -r '::.' -T '{date(date,"%Y")} {author}\n'""").readlines())
215 ]
215 ]
216
216
217 insert_entries(
217 insert_entries(
218 filename='kallithea/templates/about.html',
218 filename='kallithea/templates/about.html',
219 all_entries=repo_entries + other_about,
219 all_entries=repo_entries + other_about,
220 no_entries=no_about,
220 no_entries=no_about,
221 domain_extra=domain_extra,
221 domain_extra=domain_extra,
222 split_re=r'(?: <li>Copyright &copy; [^\n]*</li>\n)*',
222 split_re=r'(?: <li>Copyright &copy; [^\n]*</li>\n)*',
223 normalize_name=lambda name: name.split('<', 1)[0].strip(),
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),
224 format_f=lambda years, name: ' <li>Copyright &copy; %s, %s</li>\n' % (nice_years(years, '&ndash;', ', '), name),
225 )
225 )
226
226
227 insert_entries(
227 insert_entries(
228 filename='CONTRIBUTORS',
228 filename='CONTRIBUTORS',
229 all_entries=repo_entries + other_contributors,
229 all_entries=repo_entries + other_contributors,
230 no_entries=total_ignore,
230 no_entries=total_ignore,
231 domain_extra=domain_extra,
231 domain_extra=domain_extra,
232 split_re=r'(?: [^\n]*\n)*',
232 split_re=r'(?: [^\n]*\n)*',
233 normalize_name=lambda name: name,
233 normalize_name=lambda name: name,
234 format_f=lambda years, name: (' %s%s%s\n' % (name, ' ' if years else '', nice_years(years))),
234 format_f=lambda years, name: (' %s%s%s\n' % (name, ' ' if years else '', nice_years(years))),
235 )
235 )
236
236
237 insert_entries(
237 insert_entries(
238 filename='kallithea/templates/base/base.html',
238 filename='kallithea/templates/base/base.html',
239 all_entries=repo_entries,
239 all_entries=repo_entries,
240 no_entries=total_ignore,
240 no_entries=total_ignore,
241 domain_extra={},
241 domain_extra={},
242 split_re=r'(?<=&copy;) .* (?=by various authors)',
242 split_re=r'(?<=&copy;) .* (?=by various authors)',
243 normalize_name=lambda name: '',
243 normalize_name=lambda name: '',
244 format_f=lambda years, name: ' ' + nice_years(years, '&ndash;', ', ') + ' ',
244 format_f=lambda years, name: ' ' + nice_years(years, '&ndash;', ', ') + ' ',
245 )
245 )
246
246
247
247
248 if __name__ == '__main__':
248 if __name__ == '__main__':
249 main()
249 main()
250
250
251
251
252 # To list new contributors since last tagging:
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
253 # { hg log -r '::tagged()' -T ' {author}\n {author}\n'; hg log -r '::.' -T ' {author}\n' | sort | uniq; } | sort | uniq -u
General Comments 0
You need to be logged in to leave comments. Login now