~launchpad-pqm/launchpad/devel

9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
#
4
# Copyright 2009 Canonical Ltd.  This software is licensed under the
5
# GNU Affero General Public License version 3 (see the file LICENSE).
6
9373.1.3 by Karl Fogel
* utilities/community-contributions.py: Update doc string to start
7
"""Show what Launchpad community contributors have done.
8
9
Trawl a Launchpad branch's history to detect contributions by non-Canonical
10
developers, then update https://dev.launchpad.net/Contributions accordingly.
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
11
10456.1.10 by William Grant
Take devel and db-devel paths as options instead of arguments, to make ordering more obvious.
12
Usage: community-contributions.py [options] --devel=PATH --db-devel=DB_PATH
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
13
14
Requirements:
10456.1.4 by William Grant
Fully support multiple branches -- they will now be linked properly, and their revisions will be labeled.
15
       You need both the 'devel' and 'db-devel' branches of Launchpad
16
       available locally (see https://dev.launchpad.net/Getting),
17
       your ~/.moin_ids file must be set up correctly, and you need
18
       editmoin.py (if you don't have it, the error message will tell
19
       you where to get it).
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
20
21
Options:
10456.1.10 by William Grant
Take devel and db-devel paths as options instead of arguments, to make ordering more obvious.
22
  -q               Print no non-essential messages.
23
  -h, --help       Print this help.
24
  --dry-run        Don't update the wiki, just print the new page to stdout.
25
  --draft-run      Update the wiki "/Draft" page instead of the real page.
26
  --devel=PATH     Specify the filesystem path to the 'devel' branch.
27
  --db-devel=PATH  Specify the filesystem path to the 'db-devel' branch.
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
28
"""
29
30
# General notes:
31
#
32
# The Right Way to do this would probably be to output some kind of
33
# XML format, and then have a separate converter script transform that
34
# to wiki syntax and update the wiki page.  But as the wiki is our
35
# only consumer right now, we just output wiki syntax and update the
36
# wiki page directly, premature generalization being the root of all
37
# evil.
38
#
39
# For understanding the code, you may find it helpful to see
40
# bzrlib/log.py and http://bazaar-vcs.org/Integrating_with_Bazaar.
41
9373.1.16 by Karl Fogel
* utilities/community-contributions.py: Sort imports, as per jml's review.
42
import getopt
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
43
import re
44
import sys
9373.1.16 by Karl Fogel
* utilities/community-contributions.py: Sort imports, as per jml's review.
45
46
from bzrlib import log
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
47
from bzrlib.branch import Branch
48
from bzrlib.osutils import format_date
49
50
try:
51
    from editmoin import editshortcut
52
except:
10281.1.2 by Jamal Fanaian
Fixed lint messages regardling line length
53
    sys.stderr.write("""ERROR: Unable to import from 'editmoin'. How to solve:
9521.1.1 by Karl Fogel
In utilities/community-contributions.py, update error message to give
54
Get editmoin.py from launchpadlib's "contrib/" directory:
55
56
  http://bazaar.launchpad.net/~lazr-developers/launchpadlib/trunk/annotate/head%3A/contrib/editmoin.py
57
58
(Put it in the same directory as this script and everything should work.)
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
59
""")
60
    sys.exit(1)
61
62
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
63
def wiki_encode(x):
64
    """Encode a Unicode string for display on the wiki."""
65
    return x.encode('utf-8', 'xmlcharrefreplace')
66
67
68
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
69
# The output contains two classes of contributors: people who don't
70
# work for Canonical at all, and people who do work for Canonical but
71
# not on the Launchpad team.
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
72
#
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
73
# People who used to work for Canonical on the Launchpad team are not
74
# shown in the output, since they don't help us from a "contributions
75
# from outside the team" perspective, so they are listed as known
76
# Canonical Launchpad developers even though they aren't actually on
77
# the team anymore.  There may be a few former Canonicalites who
78
# didn't work on the Launchpad team but who still contributed to
79
# Launchpad; most of them would have done so before Launchpad was open
80
# sourced in July 2009, though, and since this script is really about
81
# showing things that have happened since Launchpad was open sourced,
82
# they may be listed as Launchpad team members anyway just to ensure
83
# they don't appear in the output.
84
#
85
# (As time goes on, that assumption will be less and less correct, of
86
# course, and eventually we may wish to do something about it.  Also,
87
# there are some people, e.g. Jelmer Vernooij, who made contributions
88
# to Launchpad before working at Canonical, but who now work on the
89
# Launchpad team at Canonical.  Ideally, each potentially listable
90
# contributor could have a set of roles, and a date range associated
91
# with each role... but that would be overkill for this script.  That
92
# last 2% of correctness would cost way too much to achieve.)
93
#
10224.15.1 by Karl Fogel
* utilities/community-contributions.py
94
# XXX: Karl Fogel 2009-09-10 bug=513608: We should use launchpadlib
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
95
# to consult Launchpad itself to find out who's a Canonical developer,
96
# and within that who's a Launchpad developer.
97
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
98
99
# If a contributor's address contains this, then they are or were a
100
# Canonical developer -- maybe on the Launchpad team, maybe not.
101
CANONICAL_ADDR = wiki_encode(u" {_AT_} canonical.com")
102
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
103
# People on the Canonical Launchpad team.
104
known_canonical_lp_devs = \
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
105
    [wiki_encode(x) for x in (u'Aaron Bentley',
106
                              u'Abel Deuring',
107
                              u'Andrew Bennetts',
108
                              u'Barry Warsaw',
11728.1.1 by William Grant
Update community-contributions.py's list Launchpad and Canonical developers, and add some more email merges.
109
                              u'Benji York',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
110
                              u'Bjorn Tillenius',
111
                              u'Björn Tillenius',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
112
                              u'Brad Bollenbach',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
113
                              u'Brad Crittenden',
114
                              u'Brian Fromme',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
115
                              u'Canonical.com Patch Queue Manager',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
116
                              u'Carlos Perello Marin',
117
                              u'Carlos Perelló Marín',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
118
                              u'carlos.perello {_AT_} canonical.com',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
119
                              u'Celso Providelo',
120
                              u'Christian Reis',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
121
                              u'Christian Robottom Reis',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
122
                              u'kiko {_AT_} beetle',
123
                              u'Curtis Hovey',
124
                              u'Dafydd Harries',
125
                              u'Danilo Šegan',
11728.1.1 by William Grant
Update community-contributions.py's list Launchpad and Canonical developers, and add some more email merges.
126
                              u'Danilo Segan',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
127
                              u'david <david {_AT_} marvin>',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
128
                              u'Данило Шеган',
129
                              u'данило шеган',
130
                              u'Daniel Silverstone',
131
                              u'David Allouche',
132
                              u'Deryck Hodge',
133
                              u'Diogo Matsubara',
134
                              u'Edwin Grubbs',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
135
                              u'Elliot Murphy',
136
                              u'Firstname Lastname',
14503.1.1 by William Grant
Add frankban to the Canonical LP devs list.
137
                              u'Francesco Banconi',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
138
                              u'Francis Lacoste',
139
                              u'Francis J. Lacoste',
140
                              u'Gary Poster',
141
                              u'Gavin Panella',
142
                              u'Graham Binns',
143
                              u'Guilherme Salgado',
144
                              u'Henning Eggers',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
145
                              u'Herb McNew',
13531.1.2 by William Grant
Update community-contributions.py's name maps.
146
                              u'Huw Wilkins',
11728.1.1 by William Grant
Update community-contributions.py's list Launchpad and Canonical developers, and add some more email merges.
147
                              u'Ian Booth',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
148
                              u'James Henstridge',
11728.1.1 by William Grant
Update community-contributions.py's list Launchpad and Canonical developers, and add some more email merges.
149
                              u'j.c.sackett',
150
                              u'jc',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
151
                              u'Jelmer Vernooij',
152
                              u'Jeroen Vermeulen',
153
                              u'Jeroen T. Vermeulen',
154
                              u'Joey Stanford',
11728.1.1 by William Grant
Update community-contributions.py's list Launchpad and Canonical developers, and add some more email merges.
155
                              u'Jon Sackett',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
156
                              u'Jonathan Lange',
11702.2.2 by Brian Murray
j.c.sackett works on Launchpad
157
                              u'j.c.sackett',
158
                              u'jonathan.sackett {_AT_} canonical.com',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
159
                              u'jml {_AT_} canonical.com',
160
                              u'jml {_AT_} mumak.net',
161
                              u'Jonathan Knowles',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
162
                              u'jonathan.knowles {_AT_} canonical.com',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
163
                              u'Julian Edwards',
164
                              u'Karl Fogel',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
165
                              u'Launch Pad',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
166
                              u'Launchpad APA',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
167
                              u'Launchpad Developers',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
168
                              u'Launchpad Patch Queue Manager',
169
                              u'Launchpad PQM Bot',
170
                              u'Leonard Richardson',
171
                              u'Malcolm Cleaton',
172
                              u'Maris Fogels',
173
                              u'Mark Shuttleworth',
174
                              u'Martin Albisetti',
175
                              u'Matt Zimmerman',
176
                              u'Matthew Paul Thomas',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
177
                              u'Matthew Thomas',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
178
                              u'Matthew Revell',
179
                              u'matthew.revell {_AT_} canonical.com',
180
                              u'Michael Hudson',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
181
                              u'michael.hudson {_AT_} canonical.com',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
182
                              u'Michael Nelson',
183
                              u'Muharem Hrnjadovic',
184
                              u'muharem {_AT_} canonical.com',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
185
                              u'Patch Queue Manager',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
186
                              u'Paul Hummer',
13531.1.2 by William Grant
Update community-contributions.py's name maps.
187
                              u'Raphael Badin',
188
                              u'Raphaël Badin',
14358.1.1 by William Grant
Add rickh to the lp devs list.
189
                              u'Richard Harding',
190
                              u'Rick Harding',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
191
                              u'Robert Collins',
11728.1.1 by William Grant
Update community-contributions.py's list Launchpad and Canonical developers, and add some more email merges.
192
                              u'root <root {_AT_} ubuntu>',
13531.1.2 by William Grant
Update community-contributions.py's name maps.
193
                              u'rvb',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
194
                              u'Stuart Bishop',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
195
                              u'Steve Alexander',
11057.1.1 by Jonathan Lange
Correct some bugs with the Launchpad data
196
                              u'Steve Kowalik',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
197
                              u'Steve McInerney',
198
                              u'<steve {_AT_} stedee.id.au>',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
199
                              u'test {_AT_} canonical.com',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
200
                              u'Tom Haddon',
201
                              u'Tim Penhey',
202
                              u'Tom Berger',
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
203
                              u'ubuntu <ubuntu {_AT_} lp-dev>',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
204
                              u'Ursula Junque',
13531.1.2 by William Grant
Update community-contributions.py's name maps.
205
                              u'William Grant <william.grant {_AT_} canonical.com>',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
206
                              )]
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
207
208
# People known to work for Canonical but not on the Launchpad team.
209
# Anyone with "@canonical.com" in their email address is considered to
210
# work for Canonical, but some people occasionally submit changes from
211
# their personal email addresses; this list contains people known to
212
# do that, so we can treat them appropriately in the output.
213
known_canonical_non_lp_devs = \
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
214
    [wiki_encode(x) for x in (u'Adam Conrad',
215
                              u'Andrew Bennetts',
216
                              u'Anthony Lenton',
217
                              u'Cody Somerville',
218
                              u'Cody A.W. Somerville',
219
                              u'David Murphy',
11057.1.1 by Jonathan Lange
Correct some bugs with the Launchpad data
220
                              u'Didier Roche',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
221
                              u'Elliot Murphy',
222
                              u'Gabriel Neuman gneuman {_AT_} async.com',
223
                              u'Gustavo Niemeyer',
224
                              u'James Henstridge',
11057.1.1 by Jonathan Lange
Correct some bugs with the Launchpad data
225
                              u'James Westby',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
226
                              u'John Lenton',
227
                              u'Kees Cook',
228
                              u'LaMont Jones',
13531.1.2 by William Grant
Update community-contributions.py's name maps.
229
                              u'Loïc Minier',
11057.1.1 by Jonathan Lange
Correct some bugs with the Launchpad data
230
                              u'Martin Pitt',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
231
                              u'Martin Pool',
232
                              u'Matt Zimmerman',
13531.1.2 by William Grant
Update community-contributions.py's name maps.
233
                              u'mbp {_AT_} sourcefrog.net',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
234
                              u'Michael Casadevall',
235
                              u'Michael Vogt',
236
                              u'Sidnei da Silva',
10667.1.1 by Karl Fogel
* utilities/community-contributions.py
237
                              u'Dustin Kirkland',
11728.1.1 by William Grant
Update community-contributions.py's list Launchpad and Canonical developers, and add some more email merges.
238
                              u'John Arbash Meinel',
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
239
                              )]
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
240
11057.1.2 by Jonathan Lange
Flakes, space
241
# Some people have made commits using various names and/or email
10281.1.1 by Jamal Fanaian
Created name map for community-contributions to merge people using different names/email addresses.
242
# addresses, so this map will be used to merge them accordingly.
10301.1.8 by Karl Fogel
Clean up the way we do string encoding. No functional change.
243
# The map is initialized from this list of pairs, where each pair is
244
# of the form (CONTRIBUTOR_AS_SEEN, UNIFYING_IDENTITY_FOR_CONTRIBUTOR).
245
merge_names_pairs = (
246
    (u'Jamal Fanaian <jfanaian {_AT_} gmail.com>',
247
     u'Jamal Fanaian <jamal.fanaian {_AT_} gmail.com>'),
248
    (u'Jamal Fanaian <jamal {_AT_} jfvm1>',
249
     u'Jamal Fanaian <jamal.fanaian {_AT_} gmail.com>'),
250
    (u'LaMont Jones <lamont {_AT_} rover3>',
251
     u'LaMont Jones <lamont {_AT_} debian.org>'),
10456.1.12 by William Grant
Start at revision 1 of both branches, and update the name maps for the older revisions.
252
    (u'Sidnei <sidnei {_AT_} ubuntu>',
253
     u'Sidnei da Silva <sidnei.da.silva {_AT_} canonical.com>'),
254
    (u'Sidnei da Silva <sidnei.da.silva {_AT_} gmail.com>',
255
     u'Sidnei da Silva <sidnei.da.silva {_AT_} canonical.com>'),
256
    (u'Sidnei da Silva <sidnei {_AT_} canonical.com>',
257
     u'Sidnei da Silva <sidnei.da.silva {_AT_} canonical.com>'),
258
    (u'Adam Conrad <adconrad {_AT_} ziggup>',
259
     u'Adam Conrad <adconrad {_AT_} 0c3.net>'),
260
    (u'Elliot Murphy <elliot {_AT_} elliotmurphy.com>',
261
     u'Elliot Murphy <elliot {_AT_} canonical.com>'),
262
    (u'Elliot Murphy <elliot.murphy {_AT_} canonical.com>',
263
     u'Elliot Murphy <elliot {_AT_} canonical.com>'),
264
    (u'Cody Somerville <cody-somerville {_AT_} mercurial>',
265
     u'Cody A.W. Somerville <cody.somerville {_AT_} canonical.com>'),
266
    (u'Adam Conrad <adconrad {_AT_} chinstrap>',
267
     u'Adam Conrad <adconrad {_AT_} 0c3.net>'),
268
    (u'Adam Conrad <adconrad {_AT_} cthulhu>',
269
     u'Adam Conrad <adconrad {_AT_} 0c3.net>'),
11728.1.1 by William Grant
Update community-contributions.py's list Launchpad and Canonical developers, and add some more email merges.
270
    (u'James Westby <james.westby {_AT_} linaro.org>',
13531.1.2 by William Grant
Update community-contributions.py's name maps.
271
     u'James Westby <james.westby {_AT_} canonical.com>'),
11728.1.1 by William Grant
Update community-contributions.py's list Launchpad and Canonical developers, and add some more email merges.
272
    (u'Bryce Harrington <bryce {_AT_} canonical.com>',
273
     u'Bryce Harrington <bryce.harrington {_AT_} canonical.com>'),
274
    (u'Dustin Kirkland <kirkland {_AT_} x200>',
275
     u'Dustin Kirkland <kirkland {_AT_} canonical.com>'),
276
    (u'Anthony Lenton <antoniolenton {_AT_} gmail.com>',
277
     u'Anthony Lenton <anthony.lenton {_AT_} canonical.com>'),
278
    (u'Steve Kowalik <steven {_AT_} quelled>',
279
     u'Steve Kowalik <steve.kowalik {_AT_} canonical.com>'),
280
    (u'Steve Kowalik <stevenk {_AT_} ubuntu.com>',
281
     u'Steve Kowalik <steve.kowalik {_AT_} canonical.com>'),
282
    (u'jc <jc {_AT_} launchpad>',
283
     u'j.c.sackett <jonathan.sackett {_AT_} canonical.com>'),
284
    (u'Jon Sackett <jc {_AT_} jabberwocky>',
285
     u'j.c.sackett <jonathan.sackett {_AT_} canonical.com>'),
286
    (u'John Arbash Meinel <jameinel {_AT_} falco-lucid>',
287
     u'John Arbash Meinel <john {_AT_} arbash-meinel.com>'),
288
    (u'Martin Pool <mbp {_AT_} sourcefrog.net>',
289
     u'Martin Pool <mbp {_AT_} canonical.com>'),
13531.1.2 by William Grant
Update community-contributions.py's name maps.
290
    (u'mbp {_AT_} sourcefrog.net',
291
     u'Martin Pool <mbp {_AT_} canonical.com>'),
292
    (u'mbp {_AT_} canonical.com',
293
     u'Martin Pool <mbp {_AT_} canonical.com>'),
11728.1.2 by William Grant
Add another email mapping.
294
    (u'Andrea Corbellini <corbellini.andrea {_AT_} gmail.com>',
295
     u'Andrea Corbellini <andrea.corbellini {_AT_} beeseek.org>'),
13531.1.2 by William Grant
Update community-contributions.py's name maps.
296
    (u'Luke Faraone <luke {_AT_} faraone.cc',
297
     u'Luke Faraone <luke {_AT_} faraone.cc>'),
10301.1.8 by Karl Fogel
Clean up the way we do string encoding. No functional change.
298
    )
299
# Then put it in dictionary form with the correct encodings.
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
300
merge_names_map = dict((wiki_encode(a), wiki_encode(b))
301
                       for a, b in merge_names_pairs)
10301.1.8 by Karl Fogel
Clean up the way we do string encoding. No functional change.
302
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
303
304
class ContainerRevision():
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
305
    """A wrapper for a top-level LogRevision containing child LogRevisions."""
306
10456.1.4 by William Grant
Fully support multiple branches -- they will now be linked properly, and their revisions will be labeled.
307
    def __init__(self, top_lr, branch_info):
10456.1.7 by William Grant
Address review comments.
308
        """Create a new ContainerRevision.
309
310
        :param top_lr: The top-level LogRevision.
311
        :param branch_info: The BranchInfo for the containing branch.
312
        """
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
313
        self.top_rev = top_lr       # e.g. LogRevision for r9371.
9373.1.12 by Karl Fogel
* utilities/community-contributions.py: More formatting and
314
        self.contained_revs = []    # e.g. [ {9369.1.1}, {9206.4.4}, ... ],
315
                                    # where "{X}" means "LogRevision for X"
10456.1.4 by William Grant
Fully support multiple branches -- they will now be linked properly, and their revisions will be labeled.
316
        self.branch_info = branch_info
317
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
318
    def add_subrev(self, lr):
319
        """Add a descendant child of this container revision."""
320
        self.contained_revs.append(lr)
321
322
    def __str__(self):
9373.1.12 by Karl Fogel
* utilities/community-contributions.py: More formatting and
323
        timestamp = self.top_rev.rev.timestamp
324
        timezone = self.top_rev.rev.timezone
325
        message = self.top_rev.rev.message or "(NO LOG MESSAGE)"
326
        rev_id = self.top_rev.rev.revision_id or "(NO REVISION ID)"
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
327
        if timestamp:
328
            date_str = format_date(timestamp, timezone or 0, 'original')
329
        else:
330
            date_str = "(NO DATE)"
331
10456.1.4 by William Grant
Fully support multiple branches -- they will now be linked properly, and their revisions will be labeled.
332
        rev_url_base = "http://bazaar.launchpad.net/%s/revision/" % (
10456.1.7 by William Grant
Address review comments.
333
            self.branch_info.loggerhead_path)
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
334
335
        # In loggerhead, you can use either a revision number or a
336
        # revision ID.  In other words, these would reach the same page:
337
        #
338
        # http://bazaar.launchpad.net/~launchpad-pqm/launchpad/devel/\
339
        # revision/9202
340
        #
341
        #   -and-
342
        #
10281.1.2 by Jamal Fanaian
Fixed lint messages regardling line length
343
        # http://bazaar.launchpad.net/~launchpad-pqm/launchpad/devel/\
344
        # revision/launchpad@pqm.canonical.com-20090821221206-\
345
        # ritpv21q8w61gbpt
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
346
        #
347
        # In our links, even when the link text is a revnum, we still
348
        # use a rev-id for the target.  This is both so that the URL will
349
        # still work if you manually tweak it (say to "db-devel" from
350
        # "devel") and so that hovering over a revnum on the wiki page
351
        # will give you some information about it before you click
352
        # (because a rev id often identifies the committer).
353
        rev_id_url = rev_url_base + rev_id
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
354
355
        if len(self.contained_revs) <= 10:
356
            commits_block = "\n ".join(
357
                ["[[%s|%s]]" % (rev_url_base + lr.rev.revision_id, lr.revno)
358
                 for lr in self.contained_revs])
359
        else:
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
360
            commits_block = ("''see the [[%s|full revision]] for details "
361
                             "(it contains %d commits)''"
362
                             % (rev_id_url, len(self.contained_revs)))
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
363
10456.1.7 by William Grant
Address review comments.
364
        name = self.branch_info.name
365
9373.1.13 by Karl Fogel
* utilities/community-contributions.py:
366
        text = [
10456.1.4 by William Grant
Fully support multiple branches -- they will now be linked properly, and their revisions will be labeled.
367
            " * [[%s|r%s%s]] -- %s\n" % (
368
                rev_id_url, self.top_rev.revno,
13531.1.1 by William Grant
community-contributions.py no longer blows up on Unicode names or messages.
369
                ' (%s)' % name.encode('utf-8') if name else '',
10456.1.4 by William Grant
Fully support multiple branches -- they will now be linked properly, and their revisions will be labeled.
370
                date_str),
13531.1.1 by William Grant
community-contributions.py no longer blows up on Unicode names or messages.
371
            " {{{\n%s\n}}}\n" % message.encode('utf-8'),
9373.1.13 by Karl Fogel
* utilities/community-contributions.py:
372
            " '''Commits:'''\n ",
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
373
            commits_block,
9373.1.13 by Karl Fogel
* utilities/community-contributions.py:
374
            "\n",
375
            ]
376
        return ''.join(text)
11057.1.2 by Jonathan Lange
Flakes, space
377
378
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
379
# "ExternalContributor" is too much to type, so I guess we'll just use this.
380
class ExCon():
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
381
    """A contributor to Launchpad from outside Canonical's Launchpad team."""
9373.1.9 by Karl Fogel
* utilities/community-contributions.py: Blank line after class docstrings.
382
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
383
    def __init__(self, name, is_canonical=False):
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
384
        """Create a new external contributor named 'name'.
385
386
        If 'is_canonical' is True, then this is a contributor from
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
387
        within Canonical, but not on the Launchpad team at Canonical.
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
388
        'name' is something like "Veronica Random <vr {_AT_} example.com>".
389
        """
10301.1.3 by Karl Fogel
Disguise email addresses in the source code.
390
        self.name = name
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
391
        self.is_canonical = is_canonical
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
392
        # If name is "Veronica Random <veronica {_AT_} example.com>",
393
        # then name_as_anchor will be "veronica_random".
394
        self.name_as_anchor = \
395
            re.compile("\\s+").sub("_", name.split("<")[0].strip()).lower()
396
        # All the top-level revisions this contributor is associated with
397
        # (key == value == ContainerRevision).  We use a dictionary
398
        # instead of list to get set semantics; set() would be overkill.
9373.1.12 by Karl Fogel
* utilities/community-contributions.py: More formatting and
399
        self._landings = {}
10456.1.6 by William Grant
Comment on the purpose and usage of seen_revs.
400
        # A map of revision IDs authored by this contributor (probably
401
        # not top-level) to a (LogRevision, ContainerRevision) pair. The
402
        # pair contains details of the shallowest found instance of this
403
        # revision.
10456.1.3 by William Grant
Collect the shallowest authored revisions across all branches for each ExCon, only adding their top-level revs once we've seen everything. This gives sane results by ignoring merges from devel->db-devel and db-devel->devel. The main problem now is that db-devel links will point to devel instead.
404
        self.seen_revs = {}
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
405
406
    def num_landings(self):
407
        """Return the number of top-level landings that include revisions
408
        by this contributor."""
409
        return len(self._landings)
410
411
    def add_top_level_revision(self, cr):
9373.1.11 by Karl Fogel
* utilities/community-contributions.py: Stay within 80 columns.
412
        "Record ContainableRevision CR as associated with this contributor."
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
413
        self._landings[cr] = cr
414
415
    def show_contributions(self):
9373.1.11 by Karl Fogel
* utilities/community-contributions.py: Stay within 80 columns.
416
        "Return a wikified string showing this contributor's contributions."
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
417
        plural = "s"
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
418
        name = self.name
419
        if self.is_canonical:
420
            name = name + " (Canonical developer)"
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
421
        if self.num_landings() == 1:
422
            plural = ""
9373.1.13 by Karl Fogel
* utilities/community-contributions.py:
423
        text = [
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
424
            "=== %s ===\n\n" % name,
9373.1.13 by Karl Fogel
* utilities/community-contributions.py:
425
            "''%d top-level landing%s:''\n\n" % (self.num_landings(), plural),
426
            ''.join(map(str, sorted(self._landings,
10456.1.1 by William Grant
Order top-level revs by timestamp, not revno string (this broke when we reached r10000).
427
                                    key=lambda x: x.top_rev.rev.timestamp,
9373.1.13 by Karl Fogel
* utilities/community-contributions.py:
428
                                    reverse=True))),
429
            "\n",
430
            ]
431
        return ''.join(text)
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
432
433
434
def get_ex_cons(authors, all_ex_cons):
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
435
    """Return a list of ExCon objects corresponding to AUTHORS (a list
436
    of strings).  If there are no external contributors in authors,
437
    return an empty list.
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
438
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
439
    ALL_EX_CONS is a dictionary mapping author names (as received from
440
    the bzr logs, i.e., with email address undisguised) to ExCon objects.
441
    """
9373.1.12 by Karl Fogel
* utilities/community-contributions.py: More formatting and
442
    ex_cons_this_rev = []
10301.1.2 by Karl Fogel
* community-contributions.py
443
    for author in authors:
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
444
        known_canonical_lp_dev = False
445
        known_canonical_non_lp_dev = False
10301.1.3 by Karl Fogel
Disguise email addresses in the source code.
446
        # The authors we list in the source code have their addresses
447
        # disguised (since this source code is public).  We must
448
        # disguise the ones coming from the Bazaar logs in the same way,
449
        # so string matches will work.
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
450
        author = wiki_encode(author)
10301.1.3 by Karl Fogel
Disguise email addresses in the source code.
451
        author = author.replace("@", " {_AT_} ")
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
452
453
        # If someone works/worked for Canonical on the Launchpad team,
454
        # then skip them -- we don't want to show them in the output.
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
455
        for name_fragment in known_canonical_lp_devs:
456
            if name_fragment in author:
457
                known_canonical_lp_dev = True
9373.1.12 by Karl Fogel
* utilities/community-contributions.py: More formatting and
458
                break
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
459
        if known_canonical_lp_dev:
460
            continue
461
462
        # Use the merge names map to merge contributions from the same
463
        # person using alternate names and/or emails.
10301.1.5 by Karl Fogel
* community-contributions.py
464
        author = merge_names_map.get(author, author)
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
465
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
466
        if CANONICAL_ADDR in author:
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
467
            known_canonical_non_lp_dev = True
468
        else:
469
            for name_fragment in known_canonical_non_lp_devs:
470
                if name_fragment in author:
471
                    known_canonical_non_lp_dev = True
472
                    break
473
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
474
        # There's a variant of the Singleton pattern that could be
475
        # used for this, whereby instantiating an ExCon object would
476
        # just get back an existing object if such has already been
477
        # instantiated for this name.  But that would make this code
478
        # non-reentrant, and that's just not cool.
479
        ec = all_ex_cons.get(author, None)
480
        if ec is None:
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
481
            ec = ExCon(author, is_canonical=known_canonical_non_lp_dev)
482
            all_ex_cons[author] = ec
483
        ex_cons_this_rev.append(ec)
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
484
    return ex_cons_this_rev
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
485
486
487
# The LogFormatter abstract class should really be called LogReceiver
488
# or something -- subclasses don't have to be about display.
489
class LogExCons(log.LogFormatter):
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
490
    """Log all the external contributions, by Contributor."""
9373.1.9 by Karl Fogel
* utilities/community-contributions.py: Blank line after class docstrings.
491
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
492
    # See log.LogFormatter documentation.
493
    supports_merge_revisions = True
494
495
    def __init__(self):
496
        super(LogExCons, self).__init__(to_file=None)
497
        # Dictionary mapping author names (with undisguised email
498
        # addresses) to ExCon objects.
9373.1.12 by Karl Fogel
* utilities/community-contributions.py: More formatting and
499
        self.all_ex_cons = {}
9373.1.11 by Karl Fogel
* utilities/community-contributions.py: Stay within 80 columns.
500
        # ContainerRevision object representing most-recently-seen
501
        # top-level rev.
10456.1.4 by William Grant
Fully support multiple branches -- they will now be linked properly, and their revisions will be labeled.
502
        self.current_top_level_rev = None
503
        self.branch_info = None
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
504
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
505
    def _toc(self, contributors):
506
        toc_text = []
507
        for val in contributors:
508
            plural = "s"
509
            if val.num_landings() == 1:
510
                plural = ""
511
            toc_text.extend(" 1. [[#%s|%s]] ''(%d top-level landing%s)''\n"
512
                            % (val.name_as_anchor, val.name,
513
                               val.num_landings(), plural))
514
        return toc_text
10456.1.4 by William Grant
Fully support multiple branches -- they will now be linked properly, and their revisions will be labeled.
515
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
516
    def result(self):
9373.1.11 by Karl Fogel
* utilities/community-contributions.py: Stay within 80 columns.
517
        "Return a moin-wiki-syntax string with TOC followed by contributions."
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
518
10456.1.6 by William Grant
Comment on the purpose and usage of seen_revs.
519
        # Go through the shallowest authored revisions and add their
520
        # top level revisions.
10456.1.3 by William Grant
Collect the shallowest authored revisions across all branches for each ExCon, only adding their top-level revs once we've seen everything. This gives sane results by ignoring merges from devel->db-devel and db-devel->devel. The main problem now is that db-devel links will point to devel instead.
521
        for excon in self.all_ex_cons.values():
522
            for rev, top_level_rev in excon.seen_revs.values():
523
                excon.add_top_level_revision(top_level_rev)
524
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
525
        # Divide contributors into non-Canonical and Canonical.
526
        non_canonical_contributors = [x for x in self.all_ex_cons.values()
527
                                      if not x.is_canonical]
528
        canonical_contributors = [x for x in self.all_ex_cons.values()
529
                                      if x.is_canonical]
530
        # Sort them.
531
        non_canonical_contributors = sorted(non_canonical_contributors,
532
                                            key=lambda x: x.num_landings(),
533
                                            reverse=True)
534
        canonical_contributors = sorted(canonical_contributors,
535
                                        key=lambda x: x.num_landings(),
536
                                        reverse=True)
537
9373.1.13 by Karl Fogel
* utilities/community-contributions.py:
538
        text = [
539
            "-----\n\n",
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
540
            "= Who =\n\n"
541
            "== Contributors (from outside Canonical) ==\n\n",
9373.1.13 by Karl Fogel
* utilities/community-contributions.py:
542
            ]
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
543
        text.extend(self._toc(non_canonical_contributors))
544
        text.extend([
545
            "== Contributors (from Canonical, but outside "
546
            "the Launchpad team) ==\n\n",
547
            ])
548
        text.extend(self._toc(canonical_contributors))
9373.1.13 by Karl Fogel
* utilities/community-contributions.py:
549
        text.extend(["\n-----\n\n",
550
                     "= What =\n\n",
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
551
                     "== Contributions (from outside Canonical) ==\n\n",
552
                     ])
553
        for val in non_canonical_contributors:
554
            text.extend("<<Anchor(%s)>>\n" % val.name_as_anchor)
555
            text.extend(val.show_contributions())
556
        text.extend(["== Contributions (from Canonical, but outside "
557
                     "the Launchpad team) ==\n\n",
558
                     ])
559
        for val in canonical_contributors:
9373.1.13 by Karl Fogel
* utilities/community-contributions.py:
560
            text.extend("<<Anchor(%s)>>\n" % val.name_as_anchor)
561
            text.extend(val.show_contributions())
562
        return ''.join(text)
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
563
564
    def log_revision(self, lr):
565
        """Log a revision.
566
        :param  lr:   The LogRevision to be logged.
567
        """
568
        # We count on always seeing the containing rev before its subrevs.
569
        if lr.merge_depth == 0:
10456.1.4 by William Grant
Fully support multiple branches -- they will now be linked properly, and their revisions will be labeled.
570
            self.current_top_level_rev = ContainerRevision(
571
                lr, self.branch_info)
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
572
        else:
573
            self.current_top_level_rev.add_subrev(lr)
574
        ex_cons = get_ex_cons(lr.rev.get_apparent_authors(), self.all_ex_cons)
575
        for ec in ex_cons:
10456.1.6 by William Grant
Comment on the purpose and usage of seen_revs.
576
            # If this is the shallowest sighting of a revision, note it
10456.1.9 by William Grant
Comment on shallowness a little more.
577
            # in the ExCon. We may see the revision at different depths
578
            # in different branches, mostly when one of the trunks is
579
            # merged into the other. We only care about the initial
580
            # merge, which should be shallowest.
10456.1.3 by William Grant
Collect the shallowest authored revisions across all branches for each ExCon, only adding their top-level revs once we've seen everything. This gives sane results by ignoring merges from devel->db-devel and db-devel->devel. The main problem now is that db-devel links will point to devel instead.
581
            if (lr.rev.revision_id not in ec.seen_revs or
10456.1.11 by William Grant
Wrap two long lines.
582
                lr.merge_depth <
583
                    ec.seen_revs[lr.rev.revision_id][0].merge_depth):
584
                ec.seen_revs[lr.rev.revision_id] = (
585
                    lr, self.current_top_level_rev)
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
586
587
10456.1.7 by William Grant
Address review comments.
588
class BranchInfo:
589
    """A collection of information about a branch."""
590
10456.1.13 by William Grant
Remove start_revno support.
591
    def __init__(self, path, loggerhead_path, name=None):
10456.1.7 by William Grant
Address review comments.
592
        """Create a new BranchInfo.
593
594
        :param path: Filesystem path to the branch.
595
        :param loggerhead_path: The path to the branch on Launchpad's
596
            Loggerhead instance.
597
        :param name: Optional name to identify the branch's revisions in the
598
            produced document.
599
        """
600
        self.path = path
601
        self.name = name
602
        self.loggerhead_path = loggerhead_path
603
604
9373.1.15 by Karl Fogel
* utilities/community-contributions.py: Add name to "XXX" comments, as
605
# XXX: Karl Fogel 2009-09-10: is this really necessary?  See bzrlib/log.py.
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
606
log.log_formatter_registry.register('external_contributors', LogExCons,
607
                                    'Find non-Canonical contributors.')
608
609
610
def usage():
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
611
    print __doc__
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
612
613
10301.1.13 by Karl Fogel
Various tweaks, based on Jonathan Lange's review.
614
# Use backslashes to suppress newlines because this is wiki syntax,
615
# not HTML, so newlines would be rendered as line breaks.
9373.1.14 by Karl Fogel
* utilities/community-contributions.py (page_intro): Format source
616
page_intro = """This page shows contributions to Launchpad from \
10301.1.4 by Karl Fogel
Show Canonical contributors from outside the Launchpad team.
617
developers not on the Launchpad team at Canonical.
618
10456.1.5 by William Grant
Fix obsolete comments, and add a couple more.
619
It lists all changes that have landed in the Launchpad ''devel'' \
620
or ''db-devel'' trees (see the [[Trunk|trunk explanation]] for more).
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
621
13541.2.1 by William Grant
kfogel no longer runs community-contributions.py. I do.
622
~-''Note for maintainers: this page is updated every hour by a \
623
cron job running as wgrant on devpad (though if there are no new \
9373.1.14 by Karl Fogel
* utilities/community-contributions.py (page_intro): Format source
624
contributions, the page's timestamp won't change).  The code that \
625
generates this page is \
626
[[http://bazaar.launchpad.net/%7Elaunchpad-pqm/launchpad/devel/annotate/head%3A/utilities/community-contributions.py|utilities/community-contributions.py]] \
627
in the Launchpad tree.''-~
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
628
629
"""
630
631
def main():
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
632
    quiet = False
633
    dry_run = False
10456.1.10 by William Grant
Take devel and db-devel paths as options instead of arguments, to make ordering more obvious.
634
    devel_path = None
635
    db_devel_path = None
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
636
10301.1.1 by Karl Fogel
* community-contributions.py
637
    wiki_dest = "https://dev.launchpad.net/Contributions"
638
10456.1.4 by William Grant
Fully support multiple branches -- they will now be linked properly, and their revisions will be labeled.
639
    if len(sys.argv) < 3:
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
640
        usage()
641
        sys.exit(1)
642
643
    try:
644
        opts, args = getopt.getopt(sys.argv[1:], '?hq',
10456.1.10 by William Grant
Take devel and db-devel paths as options instead of arguments, to make ordering more obvious.
645
                                   ['help', 'usage', 'dry-run', 'draft-run',
646
                                    'devel=', 'db-devel='])
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
647
    except getopt.GetoptError, e:
648
        sys.stderr.write("ERROR: " + str(e) + '\n\n')
649
        usage()
650
        sys.exit(1)
651
652
    for opt, value in opts:
653
        if opt == '--help' or opt == '-h' or opt == '-?' or opt == 'usage':
654
            usage()
655
            sys.exit(0)
656
        elif opt == '-q' or opt == '--quiet':
657
            quiet = True
658
        elif opt == '--dry-run':
659
            dry_run = True
10301.1.1 by Karl Fogel
* community-contributions.py
660
        elif opt == '--draft-run':
661
            wiki_dest += "/Draft"
10456.1.10 by William Grant
Take devel and db-devel paths as options instead of arguments, to make ordering more obvious.
662
        elif opt == '--devel':
663
            devel_path = value
664
        elif opt == '--db-devel':
665
            db_devel_path = value
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
666
667
    # Ensure we have the arguments we need.
10456.1.10 by William Grant
Take devel and db-devel paths as options instead of arguments, to make ordering more obvious.
668
    if not devel_path or not db_devel_path:
10456.1.4 by William Grant
Fully support multiple branches -- they will now be linked properly, and their revisions will be labeled.
669
        sys.stderr.write("ERROR: paths to Launchpad devel and db-devel "
10456.1.10 by William Grant
Take devel and db-devel paths as options instead of arguments, to make ordering more obvious.
670
                         "branches required as options\n")
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
671
        usage()
672
        sys.exit(1)
673
10456.1.7 by William Grant
Address review comments.
674
    branches = (
675
        BranchInfo(
10456.1.13 by William Grant
Remove start_revno support.
676
            devel_path, '~launchpad-pqm/launchpad/devel'),
10456.1.7 by William Grant
Address review comments.
677
        BranchInfo(
10456.1.13 by William Grant
Remove start_revno support.
678
            db_devel_path, '~launchpad-pqm/launchpad/db-devel', 'db-devel'),
10456.1.7 by William Grant
Address review comments.
679
        )
10456.1.4 by William Grant
Fully support multiple branches -- they will now be linked properly, and their revisions will be labeled.
680
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
681
    lec = LogExCons()
10456.1.2 by William Grant
Take multiple branches, and only count each authored revision once.
682
10456.1.7 by William Grant
Address review comments.
683
    for branch_info in branches:
10456.1.2 by William Grant
Take multiple branches, and only count each authored revision once.
684
        # Do everything.
10456.1.7 by William Grant
Address review comments.
685
        b = Branch.open(branch_info.path)
10456.1.2 by William Grant
Take multiple branches, and only count each authored revision once.
686
10456.1.13 by William Grant
Remove start_revno support.
687
        logger = log.Logger(b, {'direction' : 'reverse',
10456.1.2 by William Grant
Take multiple branches, and only count each authored revision once.
688
                                'levels' : 0, })
689
        if not quiet:
690
            print "Calculating (this may take a while)..."
10456.1.5 by William Grant
Fix obsolete comments, and add a couple more.
691
692
        # Set information about the current branch for later formatting.
10456.1.4 by William Grant
Fully support multiple branches -- they will now be linked properly, and their revisions will be labeled.
693
        lec.branch_info = branch_info
10456.1.2 by William Grant
Take multiple branches, and only count each authored revision once.
694
        logger.show(lec)  # Won't "show" anything -- just gathers data.
695
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
696
    page_contents = page_intro + lec.result()
697
    def update_if_modified(moinfile):
698
        if moinfile._unescape(moinfile.body) == page_contents:
699
            return 0  # Nothing changed, so cancel the edit.
700
        else:
701
            moinfile.body = page_contents
702
            return 1
703
    if not dry_run:
704
        if not quiet:
705
            print "Updating wiki..."
706
        # Not sure how to get editmoin to obey our quiet flag.
10301.1.1 by Karl Fogel
* community-contributions.py
707
        editshortcut(wiki_dest, editfile_func=update_if_modified)
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
708
        if not quiet:
709
            print "Done updating wiki."
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
710
    else:
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
711
        print page_contents
9373.1.1 by Karl Fogel
Add utilities/community-contributions.py (descended from lpcc.py in
712
713
714
if __name__ == '__main__':
9373.1.4 by Karl Fogel
* utilities/community-contributions.py: Reindent with py-offset-level 4,
715
    main()