/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/plugins/launchpad/__init__.py

  • Committer: John Arbash Meinel
  • Date: 2011-04-20 09:46:28 UTC
  • mfrom: (5609.33.4 2.3)
  • mto: (5609.33.5 2.3)
  • mto: This revision was merged to the branch mainline in revision 5811.
  • Revision ID: john@arbash-meinel.com-20110420094628-l0bafq1lwb6ib1v2
Merge lp:bzr/2.3 @ 5640 so we can update the release notes (aka NEWS)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
"""Launchpad.net integration plugin for Bazaar."""
 
17
"""Launchpad.net integration plugin for Bazaar.
 
18
 
 
19
This plugin provides facilities for working with Bazaar branches that are
 
20
hosted on Launchpad (http://launchpad.net).  It provides a directory service 
 
21
for referring to Launchpad branches using the "lp:" prefix.  For example,
 
22
lp:bzr refers to the Bazaar's main development branch and
 
23
lp:~username/project/branch-name can be used to refer to a specific branch.
 
24
 
 
25
This plugin provides a bug tracker so that "bzr commit --fixes lp:1234" will
 
26
record that revision as fixing Launchpad's bug 1234.
 
27
 
 
28
The plugin also provides the following commands:
 
29
 
 
30
    launchpad-login: Show or set the Launchpad user ID
 
31
    launchpad-open: Open a Launchpad branch page in your web browser
 
32
    lp-propose-merge: Propose merging a branch on Launchpad
 
33
    register-branch: Register a branch with launchpad.net
 
34
    launchpad-mirror: Ask Launchpad to mirror a branch now
 
35
 
 
36
"""
18
37
 
19
38
# The XMLRPC server address can be overridden by setting the environment
20
39
# variable $BZR_LP_XMLRPC_URL
21
40
 
22
 
# see http://bazaar-vcs.org/Specs/BranchRegistrationTool
 
41
# see http://wiki.bazaar.canonical.com/Specs/BranchRegistrationTool
23
42
 
24
43
# Since we are a built-in plugin we share the bzrlib version
25
44
from bzrlib import version_info
28
47
lazy_import(globals(), """
29
48
from bzrlib import (
30
49
    branch as _mod_branch,
 
50
    errors,
 
51
    ui,
31
52
    trace,
32
53
    )
33
54
""")
34
55
 
35
 
from bzrlib.commands import Command, Option, register_command
 
56
from bzrlib import bzrdir
 
57
from bzrlib.commands import (
 
58
        Command,
 
59
        register_command,
 
60
)
36
61
from bzrlib.directory_service import directories
37
62
from bzrlib.errors import (
38
63
    BzrCommandError,
42
67
    NotBranchError,
43
68
    )
44
69
from bzrlib.help_topics import topic_registry
 
70
from bzrlib.option import (
 
71
        Option,
 
72
        ListOption,
 
73
)
45
74
 
46
75
 
47
76
class cmd_register_branch(Command):
48
 
    """Register a branch with launchpad.net.
 
77
    __doc__ = """Register a branch with launchpad.net.
49
78
 
50
79
    This command lists a bzr branch in the directory of branches on
51
80
    launchpad.net.  Registration allows the branch to be associated with
153
182
 
154
183
 
155
184
class cmd_launchpad_open(Command):
156
 
    """Open a Launchpad branch page in your web browser."""
 
185
    __doc__ = """Open a Launchpad branch page in your web browser."""
157
186
 
158
187
    aliases = ['lp-open']
159
188
    takes_options = [
203
232
 
204
233
 
205
234
class cmd_launchpad_login(Command):
206
 
    """Show or set the Launchpad user ID.
 
235
    __doc__ = """Show or set the Launchpad user ID.
207
236
 
208
237
    When communicating with Launchpad, some commands need to know your
209
238
    Launchpad user ID.  This command can be used to set or show the
259
288
 
260
289
# XXX: cmd_launchpad_mirror is untested
261
290
class cmd_launchpad_mirror(Command):
262
 
    """Ask Launchpad to mirror a branch now."""
 
291
    __doc__ = """Ask Launchpad to mirror a branch now."""
263
292
 
264
293
    aliases = ['lp-mirror']
265
294
    takes_args = ['location?']
277
306
register_command(cmd_launchpad_mirror)
278
307
 
279
308
 
 
309
class cmd_lp_propose_merge(Command):
 
310
    __doc__ = """Propose merging a branch on Launchpad.
 
311
 
 
312
    This will open your usual editor to provide the initial comment.  When it
 
313
    has created the proposal, it will open it in your default web browser.
 
314
 
 
315
    The branch will be proposed to merge into SUBMIT_BRANCH.  If SUBMIT_BRANCH
 
316
    is not supplied, the remembered submit branch will be used.  If no submit
 
317
    branch is remembered, the development focus will be used.
 
318
 
 
319
    By default, the SUBMIT_BRANCH's review team will be requested to review
 
320
    the merge proposal.  This can be overriden by specifying --review (-R).
 
321
    The parameter the launchpad account name of the desired reviewer.  This
 
322
    may optionally be followed by '=' and the review type.  For example:
 
323
 
 
324
      bzr lp-propose-merge --review jrandom --review review-team=qa
 
325
 
 
326
    This will propose a merge,  request "jrandom" to perform a review of
 
327
    unspecified type, and request "review-team" to perform a "qa" review.
 
328
    """
 
329
 
 
330
    takes_options = [Option('staging',
 
331
                            help='Propose the merge on staging.'),
 
332
                     Option('message', short_name='m', type=unicode,
 
333
                            help='Commit message.'),
 
334
                     Option('approve',
 
335
                            help='Mark the proposal as approved immediately.'),
 
336
                     ListOption('review', short_name='R', type=unicode,
 
337
                            help='Requested reviewer and optional type.')]
 
338
 
 
339
    takes_args = ['submit_branch?']
 
340
 
 
341
    aliases = ['lp-submit', 'lp-propose']
 
342
 
 
343
    def run(self, submit_branch=None, review=None, staging=False,
 
344
            message=None, approve=False):
 
345
        from bzrlib.plugins.launchpad import lp_propose
 
346
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
 
347
            '.')
 
348
        if review is None:
 
349
            reviews = None
 
350
        else:
 
351
            reviews = []
 
352
            for review in review:
 
353
                if '=' in review:
 
354
                    reviews.append(review.split('=', 2))
 
355
                else:
 
356
                    reviews.append((review, ''))
 
357
            if submit_branch is None:
 
358
                submit_branch = branch.get_submit_branch()
 
359
        if submit_branch is None:
 
360
            target = None
 
361
        else:
 
362
            target = _mod_branch.Branch.open(submit_branch)
 
363
        proposer = lp_propose.Proposer(tree, branch, target, message,
 
364
                                       reviews, staging, approve=approve)
 
365
        proposer.check_proposal()
 
366
        proposer.create_proposal()
 
367
 
 
368
 
 
369
register_command(cmd_lp_propose_merge)
 
370
 
 
371
 
 
372
class cmd_lp_find_proposal(Command):
 
373
 
 
374
    __doc__ = """Find the proposal to merge this revision.
 
375
 
 
376
    Finds the merge proposal(s) that discussed landing the specified revision.
 
377
    This works only if the selected branch was the merge proposal target, and
 
378
    if the merged_revno is recorded for the merge proposal.  The proposal(s)
 
379
    are opened in a web browser.
 
380
 
 
381
    Any revision involved in the merge may be specified-- the revision in
 
382
    which the merge was performed, or one of the revisions that was merged.
 
383
 
 
384
    So, to find the merge proposal that reviewed line 1 of README::
 
385
 
 
386
      bzr lp-find-proposal -r annotate:README:1
 
387
    """
 
388
 
 
389
    takes_options = ['revision']
 
390
 
 
391
    def run(self, revision=None):
 
392
        from bzrlib.plugins.launchpad import lp_api
 
393
        import webbrowser
 
394
        b = _mod_branch.Branch.open_containing('.')[0]
 
395
        pb = ui.ui_factory.nested_progress_bar()
 
396
        b.lock_read()
 
397
        try:
 
398
            revno = self._find_merged_revno(revision, b, pb)
 
399
            merged = self._find_proposals(revno, b, pb)
 
400
            if len(merged) == 0:
 
401
                raise BzrCommandError('No review found.')
 
402
            trace.note('%d proposals(s) found.' % len(merged))
 
403
            for mp in merged:
 
404
                webbrowser.open(lp_api.canonical_url(mp))
 
405
        finally:
 
406
            b.unlock()
 
407
            pb.finished()
 
408
 
 
409
    def _find_merged_revno(self, revision, b, pb):
 
410
        if revision is None:
 
411
            return b.revno()
 
412
        pb.update('Finding revision-id')
 
413
        revision_id = revision[0].as_revision_id(b)
 
414
        # a revno spec is necessarily on the mainline.
 
415
        if self._is_revno_spec(revision[0]):
 
416
            merging_revision = revision_id
 
417
        else:
 
418
            graph = b.repository.get_graph()
 
419
            pb.update('Finding merge')
 
420
            merging_revision = graph.find_lefthand_merger(
 
421
                revision_id, b.last_revision())
 
422
            if merging_revision is None:
 
423
                raise errors.InvalidRevisionSpec(revision[0].user_spec, b)
 
424
        pb.update('Finding revno')
 
425
        return b.revision_id_to_revno(merging_revision)
 
426
 
 
427
    def _find_proposals(self, revno, b, pb):
 
428
        launchpad = lp_api.login(lp_registration.LaunchpadService())
 
429
        pb.update('Finding Launchpad branch')
 
430
        lpb = lp_api.LaunchpadBranch.from_bzr(launchpad, b,
 
431
                                              create_missing=False)
 
432
        pb.update('Finding proposals')
 
433
        return list(lpb.lp.getMergeProposals(status=['Merged'],
 
434
                                             merged_revnos=[revno]))
 
435
 
 
436
 
 
437
    @staticmethod
 
438
    def _is_revno_spec(spec):
 
439
        try:
 
440
            int(spec.user_spec)
 
441
        except ValueError:
 
442
            return False
 
443
        else:
 
444
            return True
 
445
 
 
446
 
 
447
register_command(cmd_lp_find_proposal)
 
448
 
 
449
 
280
450
def _register_directory():
281
451
    directories.register_lazy('lp:', 'bzrlib.plugins.launchpad.lp_directory',
282
452
                              'LaunchpadDirectory',
283
453
                              'Launchpad-based directory service',)
 
454
    directories.register_lazy(
 
455
        'debianlp:', 'bzrlib.plugins.launchpad.lp_directory',
 
456
        'LaunchpadDirectory',
 
457
        'debianlp: shortcut')
 
458
    directories.register_lazy(
 
459
        'ubuntu:', 'bzrlib.plugins.launchpad.lp_directory',
 
460
        'LaunchpadDirectory',
 
461
        'ubuntu: shortcut')
 
462
 
284
463
_register_directory()
285
464
 
286
465