Merge lp:~albaguirre/jenkins-launchpad-plugin/support-voting-on-git-mps into lp:jenkins-launchpad-plugin

Proposed by Alberto Aguirre
Status: Merged
Merged at revision: 132
Proposed branch: lp:~albaguirre/jenkins-launchpad-plugin/support-voting-on-git-mps
Merge into: lp:jenkins-launchpad-plugin
Prerequisite: lp:~albaguirre/jenkins-launchpad-plugin/support-query-git-mps
Diff against target: 285 lines (+153/-28)
3 files modified
jlp/commands/getMergeProposals.py (+2/-2)
jlp/launchpadutils.py (+37/-12)
tests/test_launchpadutils.py (+114/-14)
To merge this branch: bzr merge lp:~albaguirre/jenkins-launchpad-plugin/support-voting-on-git-mps
Reviewer Review Type Date Requested Status
Alexandros Frantzis (community) Approve
Review via email: mp+302451@code.launchpad.net

Commit message

Support voting on git based MPs

Description of the change

To post a comment you must log in.
133. By Alberto Aguirre

merge lp:~albaguirre/jenkins-launchpad-plugin/support-query-git-mps, fix conflict

134. By Alberto Aguirre

Slight cleanup, more tests

135. By Alberto Aguirre

Require bazaar instead of bzr for repo_type.

136. By Alberto Aguirre

Fix TestGetBranchHandle tests

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'jlp/commands/getMergeProposals.py'
2--- jlp/commands/getMergeProposals.py 2016-08-12 16:51:26 +0000
3+++ jlp/commands/getMergeProposals.py 2016-08-12 16:51:26 +0000
4@@ -35,8 +35,8 @@
5 "proposals.")
6 parser.add_argument("-t", "--merge_type", default="Approved",
7 help="Count only this type of merge proposals.")
8- parser.add_argument("-r", "--repo_type", default="bzr",
9- help="Repository type [bzr or git]")
10+ parser.add_argument("-r", "--repo_type", default="bazaar",
11+ help="Repository type [bazaar or git]")
12 parser.add_argument("branch", nargs="+",
13 help="Branch to check merge count.")
14 args = vars(parser.parse_args())
15
16=== modified file 'jlp/launchpadutils.py'
17--- jlp/launchpadutils.py 2016-08-12 16:51:26 +0000
18+++ jlp/launchpadutils.py 2016-08-12 16:51:26 +0000
19@@ -20,10 +20,19 @@
20 This returns what seems to be the launchpad way of doing subjects.
21 :param mp: launchpad merge proposal handle
22 """
23+ if '+git' in mp.web_link:
24+ source = mp.source_git_repository.display_name.replace('lp:', '') + \
25+ ':' + \
26+ mp.source_git_path.replace('refs/heads/', '')
27+ target = mp.target_git_repository.display_name.replace('lp:', '') + \
28+ ':' + \
29+ mp.target_git_path.replace('refs/heads/', '')
30
31- return 'Re: [Merge] {} into {}'.format(
32- mp.source_branch.display_name,
33- mp.target_branch.display_name)
34+ return 'Re: [Merge] {} into {}'.format(source, target)
35+ else:
36+ return 'Re: [Merge] {} into {}'.format(
37+ mp.source_branch.display_name,
38+ mp.target_branch.display_name)
39
40
41 def get_branch_from_mp(merge_proposal):
42@@ -306,7 +315,7 @@
43 def approve_mp(mp, revision, build_url):
44 """Approve a given merge proposal a revision.
45
46- :params mp: launchapd handle to the respective merge proposal
47+ :params mp: launchpad handle to the respective merge proposal
48 :params revision: revision that should be approved
49 :params build_url: jenkins build url with the details. This job is used to
50 generate the message with all the links to test runs as
51@@ -324,7 +333,7 @@
52 def disapprove_mp(mp, revision, build_url, reason=None):
53 """Disapprove a given merge proposal a revision (vote Needs Fixing).
54
55- :params mp: launchapd handle to the respective merge proposal
56+ :params mp: launchpad handle to the respective merge proposal
57 :params revision: revision that should be fixed
58 :params build_url: jenkins build url with the details. This job is used to
59 generate the message with all the links to test runs as
60@@ -401,7 +410,7 @@
61 :param repo_type: Type of repository [bzr or git]
62 """
63
64- if 'bzr' == repo_type:
65+ if 'bazaar' == repo_type:
66 return lp_handle.branches.getByUrl(url=name)
67 elif 'git' == repo_type:
68 name = name.replace('lp:', '');
69@@ -414,7 +423,7 @@
70 logger.debug('Repo type "' + repo_type + '" is not valid')
71 return None
72
73-def get_merge_proposals(lp_handle, name, state, repo_type='bzr'):
74+def get_merge_proposals(lp_handle, name, state, repo_type='bazaar'):
75 """ Return all merge proposals for a given branch.
76
77 Returns a list of launchpad handles for merge proposals.
78@@ -436,6 +445,26 @@
79 mps.append(mp)
80 return mps
81
82+def get_branch_handle_from_url(lp_handle, url):
83+ """ Return a branch/repo handle for the given url.
84+
85+ Returns a launchpad branch or git repository handle for the given url.
86+ :param lp_handle: launchpad API handle/instance
87+ :param url: url of the branch or git repository
88+ """
89+ if '+git' in url:
90+ name = url.replace('https://code.launchpad.net/', '')
91+ logger.debug('fetching repo: ' + name)
92+ try:
93+ return lp_handle.git_repositories.getByPath(path=name)
94+ except AttributeError:
95+ logger.debug('git_repositories.getByPath was not found. You may need to set lp_version=devel in the config')
96+ return None
97+ else:
98+ name = url.replace('https://code.launchpad.net/', 'lp:')
99+ name = name.replace('https://code.staging.launchpad.net/', 'lp://staging/')
100+ logger.debug('fetching branch: ' + name)
101+ return lp_handle.branches.getByUrl(url=name)
102
103 def get_mp_handle_from_url(lp_handle, merge_proposal_link):
104 """ Get launchpad handle for merge proposal given a merge proposal URL.
105@@ -448,11 +477,7 @@
106 logger.error('Unable to get branch link from merge proposal link.')
107 return None
108
109- branch_link = branch_link.replace('https://code.launchpad.net/', 'lp:')
110- branch_link = branch_link.replace('https://code.staging.launchpad.net/',
111- 'lp://staging/')
112- logger.debug('fetching branch: ' + branch_link)
113- branch = lp_handle.branches.getByUrl(url=branch_link)
114+ branch = get_branch_handle_from_url(lp_handle, branch_link)
115 if not branch:
116 logger.debug('Branch {} does not exist'.format(branch_link))
117 return None
118
119=== modified file 'tests/test_launchpadutils.py'
120--- tests/test_launchpadutils.py 2016-08-12 16:51:26 +0000
121+++ tests/test_launchpadutils.py 2016-08-12 16:51:26 +0000
122@@ -459,10 +459,29 @@
123 mp.source_branch.display_name = 'lp:~ps-jenkins/unity/fix'
124 return mp
125
126+ def _get_git_mp(self):
127+ mp = MagicMock()
128+ mp.web_link = 'https://code.launchpad.net/~dummy/agitproject/+git/gitproject/+merge/778899'
129+ mp.target_git_repository.display_name = 'lp:agitproject'
130+ mp.source_git_repository.display_name = 'lp:~auser/gitrepo'
131+ mp.source_git_path = 'refs/heads/abranch'
132+ mp.target_git_path = 'refs/heads/master'
133+ return mp
134+
135 def _get_subject(self, mp):
136 return 'Re: [Merge] {} into {}'.format(
137 mp.source_branch.display_name, mp.target_branch.display_name)
138
139+ def _expected_git_mp_subject(self, mp):
140+ source = mp.source_git_repository.display_name.replace('lp:', '') + \
141+ ':' + \
142+ mp.source_git_path.replace('refs/heads/', '')
143+ target = mp.target_git_repository.display_name.replace('lp:', '') + \
144+ ':' + \
145+ mp.target_git_path.replace('refs/heads/', '')
146+
147+ return 'Re: [Merge] {} into {}'.format(source, target)
148+
149 def setUp(self):
150 user = MagicMock()
151 user.name = self.jenkinsUserName
152@@ -531,6 +550,40 @@
153 subject=subject,
154 content=content)
155
156+ def test_approve_git_mp(self):
157+ mp = self._get_git_mp()
158+ subject = self._expected_git_mp_subject(mp)
159+ launchpadutils.approve_mp(mp, '1', 'http://url')
160+ content = dedent('''\
161+ PASSED: Continuous integration, rev:1
162+ http://url
163+
164+ Click here to trigger a rebuild:
165+ http://url/rebuild
166+ ''')
167+ mp.createComment.assert_called_once_with(
168+ review_type=get_config_option('launchpad_review_type'),
169+ vote=launchpadutils.LaunchpadVote.APPROVE,
170+ subject=subject,
171+ content=content)
172+
173+ def test_dissaprove_git_mp(self):
174+ mp = self._get_git_mp()
175+ subject = self._expected_git_mp_subject(mp)
176+ launchpadutils.disapprove_mp(mp, '1', 'http://url')
177+ content = dedent('''\
178+ FAILED: Continuous integration, rev:1
179+ http://url
180+
181+ Click here to trigger a rebuild:
182+ http://url/rebuild
183+ ''')
184+ mp.createComment.assert_called_once_with(
185+ review_type=get_config_option('launchpad_review_type'),
186+ vote=launchpadutils.LaunchpadVote.NEEDS_FIXING,
187+ subject=subject,
188+ content=content)
189+
190
191 class TestGetMergeProposalsWithInvalidBranch(unittest.TestCase):
192 branch_with_mps = None
193@@ -646,29 +699,76 @@
194 ret = launchpadutils.get_mp_handle_from_url(launchpad, mp_url)
195 self.assertEquals(ret, mp)
196
197+ def test_call_git_api_for_git_url(self):
198+ """If there is a merge proposal for the given merge proposal URL then
199+ get_mp_handle_from_url must return the respective merge proposal
200+ handle"""
201+
202+ mp_url = 'https://code.launchpad.net/~dummy/agitproject/+git/gitproject/+merge/778899'
203+ launchpad = MagicMock()
204+ git_repo = MagicMock
205+ mp = MagicMock()
206+ mp.web_link = mp_url
207+ git_repo.landing_targets = [mp]
208+ launchpad.git_repositories.getByPath = lambda path: git_repo
209+ ret = launchpadutils.get_mp_handle_from_url(launchpad, mp_url)
210+ self.assertEquals(ret, mp)
211+
212 class TestGetBranchHandle(unittest.TestCase):
213+ def create_mock_which_returns(self, return_value):
214+ a_mock = MagicMock()
215+ a_mock.return_value = return_value
216+ return a_mock
217+
218+ def create_mock_launchpad_for_git(self, handle_to_return):
219+ launchpad = MagicMock()
220+ launchpad.git_repositories.getByPath = self.create_mock_which_returns(handle_to_return)
221+ return launchpad
222+
223+ def create_mock_launchpad_for_bzr(self, handle_to_return):
224+ launchpad = MagicMock()
225+ launchpad.branches.getByUrl = self.create_mock_which_returns(handle_to_return)
226+ return launchpad
227+
228 def test_uses_bzr_api_for_bzr_type(self):
229- launchpad = MagicMock()
230+ expected_handle = MagicMock()
231+ launchpad = self.create_mock_launchpad_for_bzr(expected_handle)
232 name = 'lp:dummy'
233- getByUrlMock = MagicMock()
234- dummyHandle = MagicMock()
235- getByUrlMock.return_value = dummyHandle
236- launchpad.branches.getByUrl = getByUrlMock
237
238- result = launchpadutils.get_branch_handle_for(launchpad, name, 'bzr');
239+ result = launchpadutils.get_branch_handle_for(launchpad, name, 'bazaar');
240
241 launchpad.branches.getByUrl.assert_called_once_with(url=name)
242- self.assertEqual(result, dummyHandle)
243+ self.assertEqual(result, expected_handle)
244
245 def test_uses_git_api_for_git_type(self):
246- launchpad = MagicMock()
247- name = 'lp:dummy'
248- getByPathMock = MagicMock()
249- dummyHandle = MagicMock()
250- getByPathMock.return_value = dummyHandle
251- launchpad.git_repositories.getByPath = getByPathMock
252+ expected_handle = MagicMock()
253+ launchpad = self.create_mock_launchpad_for_git(expected_handle)
254+ name = "lp:dummy"
255
256 result = launchpadutils.get_branch_handle_for(launchpad, name, 'git');
257
258 launchpad.git_repositories.getByPath.assert_called_once_with(path='dummy')
259- self.assertEqual(result, dummyHandle)
260\ No newline at end of file
261+ self.assertEqual(result, expected_handle)
262+
263+ def test_uses_bzr_api_for_bzr_url(self):
264+ expected_handle = MagicMock()
265+ launchpad = self.create_mock_launchpad_for_bzr(expected_handle)
266+ expected_path = '~auser/plainoldbzrproject/abranch'
267+ url = 'https://code.launchpad.net/' + expected_path
268+ expected_url = "lp:" + expected_path
269+
270+ result = launchpadutils.get_branch_handle_from_url(launchpad, url)
271+
272+ launchpad.branches.getByUrl.assert_called_once_with(url=expected_url)
273+ self.assertEqual(result, expected_handle)
274+
275+ def test_uses_git_api_for_git_url(self):
276+ expected_handle = MagicMock()
277+ launchpad = self.create_mock_launchpad_for_git(expected_handle)
278+ expected_path='~auser/agitproject/+git/agitproject'
279+ url = 'https://code.launchpad.net/' + expected_path
280+
281+ result = launchpadutils.get_branch_handle_from_url(launchpad, url)
282+
283+ launchpad.git_repositories.getByPath.assert_called_once_with(path=expected_path)
284+ self.assertEqual(result, expected_handle)
285\ No newline at end of file

Subscribers

People subscribed via source and target branches