Rev 5549: Add lp-find-proposal command. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Tue Nov 23 16:54:51 GMT 2010
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 5549 [merge]
revision-id: pqm at pqm.ubuntu.com-20101123165450-bmll7p8fjng1d8xy
parent: pqm at pqm.ubuntu.com-20101122222758-wr1j89eb778ypclt
parent: aaron at aaronbentley.com-20101123145433-i231qdd7v9t6yf5t
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2010-11-23 16:54:50 +0000
message:
Add lp-find-proposal command.
modified:
bzrlib/plugins/launchpad/__init__.py __init__.py-20060315182712-2d5feebd2a1032dc
bzrlib/plugins/launchpad/lp_api.py lp_api.py-20090704082908-79il6zl4gugwl3wz-1
bzrlib/plugins/launchpad/lp_propose.py lp_submit.py-20100120065117-penrmqruf596pui6-1
=== modified file 'bzrlib/plugins/launchpad/__init__.py'
--- a/bzrlib/plugins/launchpad/__init__.py 2010-10-11 14:10:29 +0000
+++ b/bzrlib/plugins/launchpad/__init__.py 2010-11-23 14:54:33 +0000
@@ -47,6 +47,8 @@
lazy_import(globals(), """
from bzrlib import (
branch as _mod_branch,
+ errors,
+ ui,
trace,
)
""")
@@ -367,6 +369,84 @@
register_command(cmd_lp_propose_merge)
+class cmd_lp_find_proposal(Command):
+
+ __doc__ = """Find the proposal to merge this revision.
+
+ Finds the merge proposal(s) that discussed landing the specified revision.
+ This works only if the selected branch was the merge proposal target, and
+ if the merged_revno is recorded for the merge proposal. The proposal(s)
+ are opened in a web browser.
+
+ Any revision involved in the merge may be specified-- the revision in
+ which the merge was performed, or one of the revisions that was merged.
+
+ So, to find the merge proposal that reviewed line 1 of README::
+
+ bzr lp-find-proposal -r annotate:README:1
+ """
+
+ takes_options = ['revision']
+
+ def run(self, revision=None):
+ from bzrlib.plugins.launchpad import lp_api
+ import webbrowser
+ b = _mod_branch.Branch.open_containing('.')[0]
+ pb = ui.ui_factory.nested_progress_bar()
+ b.lock_read()
+ try:
+ revno = self._find_merged_revno(revision, b, pb)
+ merged = self._find_proposals(revno, b, pb)
+ if len(merged) == 0:
+ raise BzrCommandError('No review found.')
+ trace.note('%d proposals(s) found.' % len(merged))
+ for mp in merged:
+ webbrowser.open(lp_api.canonical_url(mp))
+ finally:
+ b.unlock()
+ pb.finished()
+
+ def _find_merged_revno(self, revision, b, pb):
+ if revision is None:
+ return b.revno()
+ pb.update('Finding revision-id')
+ revision_id = revision[0].as_revision_id(b)
+ # a revno spec is necessarily on the mainline.
+ if self._is_revno_spec(revision[0]):
+ merging_revision = revision_id
+ else:
+ graph = b.repository.get_graph()
+ pb.update('Finding merge')
+ merging_revision = graph.find_lefthand_merger(
+ revision_id, b.last_revision())
+ if merging_revision is None:
+ raise errors.InvalidRevisionSpec(revision[0].user_spec, b)
+ pb.update('Finding revno')
+ return b.revision_id_to_revno(merging_revision)
+
+ def _find_proposals(self, revno, b, pb):
+ launchpad = lp_api.login(lp_registration.LaunchpadService())
+ pb.update('Finding Launchpad branch')
+ lpb = lp_api.LaunchpadBranch.from_bzr(launchpad, b,
+ create_missing=False)
+ pb.update('Finding proposals')
+ return list(lpb.lp.getMergeProposals(status=['Merged'],
+ merged_revnos=[revno]))
+
+
+ @staticmethod
+ def _is_revno_spec(spec):
+ try:
+ int(spec.user_spec)
+ except ValueError:
+ return False
+ else:
+ return True
+
+
+register_command(cmd_lp_find_proposal)
+
+
def _register_directory():
directories.register_lazy('lp:', 'bzrlib.plugins.launchpad.lp_directory',
'LaunchpadDirectory',
=== modified file 'bzrlib/plugins/launchpad/lp_api.py'
--- a/bzrlib/plugins/launchpad/lp_api.py 2010-03-05 08:55:12 +0000
+++ b/bzrlib/plugins/launchpad/lp_api.py 2010-11-23 14:54:33 +0000
@@ -23,6 +23,7 @@
import os
import re
+import urlparse
from bzrlib import (
branch,
@@ -47,6 +48,10 @@
STAGING_SERVICE_ROOT,
Launchpad,
)
+try:
+ from launchpadlib.uris import LPNET_SERVICE_ROOT
+except ImportError:
+ LPNET_SERVICE_ROOT = 'https://api.launchpad.net/beta/'
# Declare the minimum version of launchpadlib that we need in order to work.
@@ -75,7 +80,7 @@
LAUNCHPAD_API_URLS = {
- 'production': 'https://api.launchpad.net/beta/',
+ 'production': LPNET_SERVICE_ROOT,
'edge': EDGE_SERVICE_ROOT,
'staging': STAGING_SERVICE_ROOT,
'dev': 'https://api.launchpad.dev/beta/',
@@ -101,6 +106,13 @@
raise InvalidLaunchpadInstance(lp_instance)
+class NoLaunchpadBranch(errors.BzrError):
+ _fmt = 'No launchpad branch could be found for branch "%(url)s".'
+
+ def __init__(self, branch):
+ errors.BzrError.__init__(self, branch=branch, url=branch.base)
+
+
def login(service, timeout=None, proxy_info=None):
"""Log in to the Launchpad API.
@@ -187,7 +199,7 @@
'bazaar.staging.launchpad.net')
@classmethod
- def from_bzr(cls, launchpad, bzr_branch):
+ def from_bzr(cls, launchpad, bzr_branch, create_missing=True):
"""Find a Launchpad branch from a bzr branch."""
check_update = True
for url in cls.candidate_urls(bzr_branch):
@@ -198,6 +210,8 @@
if lp_branch is not None:
break
else:
+ if not create_missing:
+ raise NoLaunchpadBranch(bzr_branch)
lp_branch = cls.create_now(launchpad, bzr_branch)
check_update = False
return cls(lp_branch, bzr_branch.base, bzr_branch, check_update)
@@ -280,3 +294,13 @@
if lp_branch:
return lp_branch
raise NotLaunchpadBranch(url)
+
+
+def canonical_url(object):
+ """Return the canonical URL for a branch."""
+ scheme, netloc, path, params, query, fragment = urlparse.urlparse(
+ str(object.self_link))
+ path = '/'.join(path.split('/')[2:])
+ netloc = netloc.replace('api.', 'code.')
+ return urlparse.urlunparse((scheme, netloc, path, params, query,
+ fragment))
=== modified file 'bzrlib/plugins/launchpad/lp_propose.py'
--- a/bzrlib/plugins/launchpad/lp_propose.py 2010-08-25 10:20:41 +0000
+++ b/bzrlib/plugins/launchpad/lp_propose.py 2010-11-23 14:54:33 +0000
@@ -15,7 +15,6 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-import urlparse
import webbrowser
from bzrlib import (
@@ -27,6 +26,7 @@
lp_api,
lp_registration,
)
+from bzrlib.plugins.launchpad.lp_api import canonical_url
from lazr.restfulclient import errors as restful_errors
@@ -217,13 +217,3 @@
old_tree):
if c and k == 'file':
yield str(path)
-
-
-def canonical_url(object):
- """Return the canonical URL for a branch."""
- scheme, netloc, path, params, query, fragment = urlparse.urlparse(
- str(object.self_link))
- path = '/'.join(path.split('/')[2:])
- netloc = netloc.replace('api.', 'code.')
- return urlparse.urlunparse((scheme, netloc, path, params, query,
- fragment))
More information about the bazaar-commits
mailing list