Merge lp:~abentley/bzr/find-proposal-branch into lp:bzr

Proposed by Aaron Bentley
Status: Rejected
Rejected by: Aaron Bentley
Proposed branch: lp:~abentley/bzr/find-proposal-branch
Merge into: lp:bzr
Diff against target: 192 lines (+119/-10)
3 files modified
bzrlib/plugins/launchpad/__init__.py (+1/-0)
bzrlib/plugins/launchpad/cmds.py (+28/-10)
bzrlib/plugins/launchpad/test_cmds.py (+90/-0)
To merge this branch: bzr merge lp:~abentley/bzr/find-proposal-branch
Reviewer Review Type Date Requested Status
Jelmer Vernooij (community) code Approve
Review via email: mp+110615@code.launchpad.net

Commit message

Add BRANCH option to the lp-find-proposal command.

Description of the change

This branch adds an optional BRANCH argument to the lp-find-proposal command.

lp-find-proposal must search the branch that any proposals were targetted against; LP does not provide a mechanism that uses solely the revision-id. This means that often, the current branch is not a suitable place to look up proposals, so it makes sense to permit an override.

At the same time, this branch introduces testing for launchpad plugin commands, starting with lp-find-proposal. Until now, these commands have gone untested, because they use Launchpad. This meant that they didn't have a way to set up test objects, and they incurred network traffic. This approach uses a fake, in-memory version of the Launchpadlib API. Only necessary functionality is implemented.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

Thanks, nice to have some extra testing.

There's an extra dot in """Specified branch is used.."""

Revision history for this message
Jelmer Vernooij (jelmer) :
review: Approve (code)
6528. By Aaron Bentley

Merged dev into find-proposal-branch.

6529. By Aaron Bentley

Update from review.

6530. By Aaron Bentley

Merged dev into find-proposal-branch.

Revision history for this message
Martin Packman (gz) wrote :

sent to pqm by email

Revision history for this message
Aaron Bentley (abentley) wrote :

This branch can't land because it requires launchpadlib on the build slave. But it doesn't need to land, because as of r6541 the branch is no longer considered when looking up merge proposals.

Martin Packman <email address hidden> wrote:

>The proposal to merge lp:~abentley/bzr/find-proposal-branch into lp:bzr has been updated.
>
> Status: Needs review => Approved
>
>For more details, see:
>https://code.launchpad.net/~abentley/bzr/find-proposal-branch/+merge/110615
>--
>https://code.launchpad.net/~abentley/bzr/find-proposal-branch/+merge/110615
>You are the owner of lp:~abentley/bzr/find-proposal-branch.
>

Revision history for this message
Martin Packman (gz) wrote :

Thanks Aaron, wondered why there was an approved branch from you sitting around unmerged.

Unmerged revisions

6530. By Aaron Bentley

Merged dev into find-proposal-branch.

6529. By Aaron Bentley

Update from review.

6528. By Aaron Bentley

Merged dev into find-proposal-branch.

6527. By Aaron Bentley

Cleanup.

6526. By Aaron Bentley

Support specifying branch for lp-find-proposal.

6525. By Aaron Bentley

Add tests of default behaviour.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/plugins/launchpad/__init__.py'
2--- bzrlib/plugins/launchpad/__init__.py 2012-03-10 19:11:06 +0000
3+++ bzrlib/plugins/launchpad/__init__.py 2012-06-26 15:04:27 +0000
4@@ -141,6 +141,7 @@
5 def load_tests(basic_tests, module, loader):
6 testmod_names = [
7 'test_account',
8+ 'test_cmds',
9 'test_register',
10 'test_lp_api',
11 'test_lp_api_lite',
12
13=== modified file 'bzrlib/plugins/launchpad/cmds.py'
14--- bzrlib/plugins/launchpad/cmds.py 2012-03-12 14:35:26 +0000
15+++ bzrlib/plugins/launchpad/cmds.py 2012-06-26 15:04:27 +0000
16@@ -22,6 +22,7 @@
17 branch as _mod_branch,
18 controldir,
19 trace,
20+ ui,
21 )
22 from bzrlib.commands import (
23 Command,
24@@ -40,6 +41,11 @@
25 )
26
27
28+def launchpad_factory():
29+ from bzrlib.plugins.launchpad import (lp_api, lp_registration)
30+ return lp_api.login(lp_registration.LaunchpadService())
31+
32+
33 class cmd_register_branch(Command):
34 __doc__ = """Register a branch with launchpad.net.
35
36@@ -345,15 +351,30 @@
37 So, to find the merge proposal that reviewed line 1 of README::
38
39 bzr lp-find-proposal -r annotate:README:1
40+
41+ If BRANCH is specified, it indicates the branch to use when looking up the
42+ proposal. :submit may be a useful value, especially for aliases.
43 """
44
45 takes_options = ['revision']
46
47- def run(self, revision=None):
48- from bzrlib import ui
49+ takes_args = ['branch?']
50+
51+ def __init__(self, launchpad_factory=launchpad_factory,
52+ open_web_page=None):
53+ super(cmd_lp_find_proposal, self).__init__()
54+ self.launchpad_factory = launchpad_factory
55+ if open_web_page is None:
56+ import webbrowser
57+ open_web_page = webbrowser.open
58+ self.open_web_page = open_web_page
59+
60+ def run(self, branch=None, revision=None):
61 from bzrlib.plugins.launchpad import lp_api
62- import webbrowser
63- b = _mod_branch.Branch.open_containing('.')[0]
64+ if branch is not None:
65+ b = _mod_branch.Branch.open(branch)
66+ else:
67+ b = _mod_branch.Branch.open_containing('.')[0]
68 pb = ui.ui_factory.nested_progress_bar()
69 b.lock_read()
70 try:
71@@ -363,7 +384,7 @@
72 raise BzrCommandError(gettext('No review found.'))
73 trace.note(gettext('%d proposals(s) found.') % len(merged))
74 for mp in merged:
75- webbrowser.open(lp_api.canonical_url(mp))
76+ self.open_web_page(lp_api.canonical_url(mp))
77 finally:
78 b.unlock()
79 pb.finished()
80@@ -387,8 +408,8 @@
81 return b.revision_id_to_revno(merging_revision)
82
83 def _find_proposals(self, revno, b, pb):
84- from bzrlib.plugins.launchpad import (lp_api, lp_registration)
85- launchpad = lp_api.login(lp_registration.LaunchpadService())
86+ from bzrlib.plugins.launchpad import lp_api
87+ launchpad = self.launchpad_factory()
88 pb.update(gettext('Finding Launchpad branch'))
89 lpb = lp_api.LaunchpadBranch.from_bzr(launchpad, b,
90 create_missing=False)
91@@ -405,6 +426,3 @@
92 return False
93 else:
94 return True
95-
96-
97-
98
99=== added file 'bzrlib/plugins/launchpad/test_cmds.py'
100--- bzrlib/plugins/launchpad/test_cmds.py 1970-01-01 00:00:00 +0000
101+++ bzrlib/plugins/launchpad/test_cmds.py 2012-06-26 15:04:27 +0000
102@@ -0,0 +1,90 @@
103+# Copyright (C) 2012 Canonical Ltd
104+#
105+# This program is free software; you can redistribute it and/or modify
106+# it under the terms of the GNU General Public License as published by
107+# the Free Software Foundation; either version 2 of the License, or
108+# (at your option) any later version.
109+#
110+# This program is distributed in the hope that it will be useful,
111+# but WITHOUT ANY WARRANTY; without even the implied warranty of
112+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
113+# GNU General Public License for more details.
114+#
115+# You should have received a copy of the GNU General Public License
116+# along with this program; if not, write to the Free Software
117+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
118+
119+
120+from bzrlib.tests import TestCaseWithTransport
121+from bzrlib.plugins.launchpad.cmds import cmd_lp_find_proposal
122+
123+
124+class FakeBranchMergeProposal(object):
125+
126+ def __init__(self, status):
127+ self.status = 'Merged'
128+ self.self_link = 'http://api.example.org/1/2/3/4'
129+
130+
131+class FakeBranch(object):
132+
133+ def __init__(self):
134+ self._bmp = {}
135+
136+ def getMergeProposals(self, status, merged_revnos):
137+ return [self._bmp[revno] for revno in merged_revnos if
138+ self._bmp[revno].status in status]
139+
140+
141+class FakeBranchCollection(object):
142+
143+ def __init__(self):
144+ self._by_url = {}
145+
146+ def getByUrl(self, url):
147+ return self._by_url[url]
148+
149+
150+class FakeLaunchpad(object):
151+
152+ def __init__(self):
153+ self._root_uri = None
154+ self.branches = FakeBranchCollection()
155+
156+
157+class TestLPFindProposal(TestCaseWithTransport):
158+
159+ def make_branch_and_lp(self, location, lp_location):
160+ """Make a branch and FakeLaunchpad to work together."""
161+ tree = self.make_branch_and_tree(location)
162+ tree.commit('r1')
163+ tree.branch.set_push_location(lp_location)
164+
165+ fake_launchpad = FakeLaunchpad()
166+ fake_branch = FakeBranch()
167+ fake_launchpad.branches._by_url[lp_location] = fake_branch
168+ fake_bmp = FakeBranchMergeProposal('Merged')
169+ fake_branch._bmp[1] = fake_bmp
170+ return fake_launchpad
171+
172+ def get_lp_find_proposal(self, location):
173+ """"Return a specially-configured cmd_lp_find_proposal.
174+
175+ web_urls is the list of urls that would be opened.
176+ """
177+ fake_launchpad = self.make_branch_and_lp(location, 'lp:asdf')
178+ web_urls = []
179+ cmd = cmd_lp_find_proposal(lambda: fake_launchpad, web_urls.append)
180+ return cmd, web_urls
181+
182+ def test_run_default_branch(self):
183+ """Current directory is used for branch if unspecified."""
184+ cmd, web_urls = self.get_lp_find_proposal('.')
185+ cmd.run_argv_aliases(['-r', '1'])
186+ self.assertEqual(['http://code.example.org/2/3/4'], web_urls)
187+
188+ def test_run_specified_branch(self):
189+ """Specified branch is used."""
190+ cmd, web_urls = self.get_lp_find_proposal('specific-branch')
191+ cmd.run_argv_aliases(['-r', '1', 'specific-branch'])
192+ self.assertEqual(['http://code.example.org/2/3/4'], web_urls)