Merge lp:~dobey/tarmac/merge-specific into lp:tarmac

Proposed by dobey
Status: Merged
Approved by: dobey
Approved revision: 432
Merged at revision: 430
Proposed branch: lp:~dobey/tarmac/merge-specific
Merge into: lp:tarmac
Diff against target: 167 lines (+73/-8)
3 files modified
tarmac/bin/commands.py (+19/-3)
tarmac/bin/options.py (+4/-0)
tarmac/tests/test_commands.py (+50/-5)
To merge this branch: bzr merge lp:~dobey/tarmac/merge-specific
Reviewer Review Type Date Requested Status
Francis Ginther Approve
Review via email: mp+208037@code.launchpad.net

Commit message

Add an option to merge a single specific proposal to a branch.

Description of the change

This adds the --proposal option to the tarmac merge command, so that a specific proposal can be merged. The argument is the web link to the MP to be merged. Passing this argument to the merge command will result in tarmac attempting to merge only that MP, and no others, not even branches for other targets which are set up in tarmac.conf.

To post a comment you must log in.
lp:~dobey/tarmac/merge-specific updated
430. By dobey

Add a couple more tests.
Fix a typo.
Revert the changes to addProposal.
Clean up the branch created by addProposal.

431. By dobey

Always use the branch_url from the MP when --proposal is used.

432. By dobey

Revert one more line.

Revision history for this message
Francis Ginther (fginther) wrote :

This implements the requested feature. Tests and code changes look good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tarmac/bin/commands.py'
2--- tarmac/bin/commands.py 2014-02-20 03:16:01 +0000
3+++ tarmac/bin/commands.py 2014-02-24 23:41:56 +0000
4@@ -174,6 +174,7 @@
5 options.imply_commit_message_option,
6 options.one_option,
7 options.list_approved_option,
8+ options.proposal_option,
9 ]
10
11 def _handle_merge_error(self, proposal, failure):
12@@ -201,14 +202,17 @@
13 proposal.setStatus(status=u'Needs review')
14 proposal.lp_save()
15
16- def _do_merges(self, branch_url):
17+ def _do_merges(self, branch_url, source_mp=None):
18 """Merge the approved proposals for %branch_url."""
19 lp_branch = self.launchpad.branches.getByUrl(url=branch_url)
20 if lp_branch is None:
21 self.logger.info('Not a valid branch: {0}'.format(branch_url))
22 return
23
24- proposals = self._get_mergable_proposals_for_branch(lp_branch)
25+ if source_mp is not None:
26+ proposals = [source_mp]
27+ else:
28+ proposals = self._get_mergable_proposals_for_branch(lp_branch)
29
30 if not proposals:
31 self.logger.info(
32@@ -409,6 +413,12 @@
33
34 return reviews
35
36+ def _get_proposal_from_mp_url(self, mp_url):
37+ """Return a branch_merge_proposal object from its web URL."""
38+ urlp = re.compile('http[s]?://code.launchpad\.net/')
39+ api_url = urlp.sub('https://api.launchpad.net/1.0/', mp_url)
40+ return self.launchpad.load(api_url)
41+
42 def run(self, branch_url=None, launchpad=None, **kwargs):
43 for key, value in kwargs.iteritems():
44 self.config.set('Tarmac', key, value)
45@@ -429,12 +439,18 @@
46 self.launchpad = self.get_launchpad_object()
47 self.logger.debug('launchpad object loaded')
48
49+ proposal = None
50+ if self.config.proposal:
51+ proposal = self._get_proposal_from_mp_url(self.config.proposal)
52+ # Always override branch_url with the correct one.
53+ branch_url = proposal.target_branch.bzr_identity
54+
55 if branch_url:
56 self.logger.debug('%(branch_url)s specified as branch_url' % {
57 'branch_url': branch_url})
58 if not branch_url.startswith('lp:'):
59 raise TarmacCommandError('Branch urls must start with lp:')
60- self._do_merges(branch_url)
61+ self._do_merges(branch_url, source_mp=proposal)
62
63 else:
64 for branch in self.config.branches:
65
66=== modified file 'tarmac/bin/options.py'
67--- tarmac/bin/options.py 2014-02-17 20:12:51 +0000
68+++ tarmac/bin/options.py 2014-02-24 23:41:56 +0000
69@@ -36,3 +36,7 @@
70 list_approved_option = Option(
71 'list-approved', short_name='l',
72 help='List Approved merge proposals for the target branch.')
73+proposal_option = Option(
74+ 'proposal', short_name='p',
75+ type=str, argname='url',
76+ help='Pass the URL for a specific proposal to merge to the target branch.')
77
78=== modified file 'tarmac/tests/test_commands.py'
79--- tarmac/tests/test_commands.py 2014-02-20 03:16:01 +0000
80+++ tarmac/tests/test_commands.py 2014-02-24 23:41:56 +0000
81@@ -19,7 +19,7 @@
82 import shutil
83 import sys
84
85-from mock import patch
86+from mock import patch, MagicMock
87 from tarmac.bin import commands
88 from tarmac.bin.registry import CommandRegistry
89 from tarmac.branch import Branch
90@@ -157,7 +157,7 @@
91 reviewer=Thing(display_name=u'Reviewer'))]),
92 Thing(
93 self_link=u'https://api.launchpad.net/1.0/proposal1',
94- web_link=u'https://codelaunchpad.net/proposal1',
95+ web_link=u'https://code.launchpad.net/proposal1',
96 queue_status=u'Approved',
97 commit_message=u'Commit this.',
98 source_branch=self.branches[0],
99@@ -201,8 +201,8 @@
100 branch3.lp_branch.unique_name = '~user/branch/' + name
101 branch3.lp_branch.landing_candidates = []
102 b3_proposal = Thing(
103- self_link=u'http://api.edge.launchpad.net/devel/proposal3',
104- web_link=u'http://edge.launchpad.net/proposal3',
105+ self_link=u'https://api.launchpad.net/1.0/proposal3',
106+ web_link=u'https://code.launchpad.net/proposal3',
107 queue_status=u'Approved',
108 commit_message=u'Commitable.',
109 source_branch=branch3.lp_branch,
110@@ -219,7 +219,7 @@
111 branch3.lp_branch.landing_targets = [b3_proposal]
112 self.proposals.append(b3_proposal)
113 self.branches.append(branch3.lp_branch)
114-
115+ self.addCleanup(shutil.rmtree, branch3_dir)
116
117 def lp_save(self, *args, **kwargs):
118 """Do nothing here."""
119@@ -491,3 +491,48 @@
120 self.addProposal("one_prerequisite", self.branches[0])
121 proposals = self.command._get_prerequisite_proposals(self.proposals[2])
122 self.assertEqual(len(proposals), 2)
123+
124+ @patch('tarmac.bin.commands.Launchpad.load')
125+ def test__get_proposal_from_mp_url(self, mocked):
126+ """Test that the URL is substituted correctly."""
127+ self.command.launchpad = MagicMock()
128+ self.command.launchpad.load = mocked
129+ self.command._get_proposal_from_mp_url(
130+ 'https://code.launchpad.net/~foo/bar/baz/+merge/10')
131+ mocked.assert_called_once_with(
132+ 'https://api.launchpad.net/1.0/~foo/bar/baz/+merge/10')
133+
134+ @patch('tarmac.bin.commands.Launchpad.load')
135+ def test__get_proposal_from_mp_url_with_api_url(self, mocked):
136+ """Test that the URL is ignored correctly."""
137+ self.command.launchpad = MagicMock()
138+ self.command.launchpad.load = mocked
139+ self.command._get_proposal_from_mp_url(
140+ 'https://api.launchpad.net/1.0/~foo/bar/baz/+merge/10')
141+ mocked.assert_called_once_with(
142+ 'https://api.launchpad.net/1.0/~foo/bar/baz/+merge/10')
143+
144+ def test_run_merge_with_specific_proposal_without_branch_url(self):
145+ """Test that a specific proposal is merged, with the others ignored."""
146+ self.proposals[1].reviewed_revid = \
147+ self.branch2.bzr_branch.last_revision()
148+ self.addProposal('specific_merge_without_branch_url')
149+ self.launchpad.load = MagicMock(return_value=self.proposals[1])
150+ self.command._get_reviews = MagicMock()
151+ self.config.proposal = self.proposals[1].web_link
152+ self.command.run(launchpad=self.launchpad)
153+ self.launchpad.load.assert_called_once_with(self.proposals[1].self_link)
154+ self.command._get_reviews.assert_called_once_with(self.proposals[1])
155+
156+ def test_run_merge_with_specific_proposal_with_branch_url(self):
157+ """Test that a specific proposal is merged, with the others ignored."""
158+ self.proposals[1].reviewed_revid = \
159+ self.branch2.bzr_branch.last_revision()
160+ self.addProposal('specific_merge_with_branch_url')
161+ self.launchpad.load = MagicMock(return_value=self.proposals[1])
162+ self.command._get_reviews = MagicMock()
163+ self.config.proposal = self.proposals[1].web_link
164+ self.command.run(launchpad=self.launchpad,
165+ branch_url=self.branches[1].bzr_identity)
166+ self.launchpad.load.assert_called_once_with(self.proposals[1].self_link)
167+ self.command._get_reviews.assert_called_once_with(self.proposals[1])

Subscribers

People subscribed via source and target branches