~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-11-23 16:54:50 UTC
  • mfrom: (5546.2.4 find-review)
  • Revision ID: pqm@pqm.ubuntu.com-20101123165450-bmll7p8fjng1d8xy
Add lp-find-proposal command.

Show diffs side-by-side

added added

removed removed

Lines of Context:
47
47
lazy_import(globals(), """
48
48
from bzrlib import (
49
49
    branch as _mod_branch,
 
50
    errors,
 
51
    ui,
50
52
    trace,
51
53
    )
52
54
""")
367
369
register_command(cmd_lp_propose_merge)
368
370
 
369
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
 
370
450
def _register_directory():
371
451
    directories.register_lazy('lp:', 'bzrlib.plugins.launchpad.lp_directory',
372
452
                              'LaunchpadDirectory',