/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/plugins/propose/launchpad.py

  • Committer: Jelmer Vernooij
  • Date: 2019-01-03 02:35:46 UTC
  • mfrom: (0.431.67 trunk)
  • mto: This revision was merged to the branch mainline in revision 7239.
  • Revision ID: jelmer@jelmer.uk-20190103023546-pryb5dotaw5ecbbt
Merge lp:brz-propose.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
    MergeProposal,
28
28
    MergeProposalBuilder,
29
29
    MergeProposalExists,
30
 
    NoMergeProposal,
31
30
    UnsupportedHoster,
32
31
    )
33
32
 
51
50
 
52
51
# TODO(jelmer): Make selection of launchpad staging a configuration option.
53
52
 
54
 
MERGE_PROPOSAL_STATUSES = [
55
 
    'Work in progress',
56
 
    'Needs review',
57
 
    'Approved',
58
 
    'Rejected',
59
 
    'Merged',
60
 
    'Code failed to merge',
61
 
    'Queued',
62
 
    'Superseded',
63
 
    ]
 
53
def status_to_lp_mp_statuses(status):
 
54
    statuses = []
 
55
    if status in ('open', 'all'):
 
56
        statuses.extend([
 
57
            'Work in progress',
 
58
            'Needs review',
 
59
            'Approved',
 
60
            'Code failed to merge',
 
61
            'Queued'])
 
62
    if status in ('closed', 'all'):
 
63
        statuses.extend(['Rejected', 'Superseded'])
 
64
    if status in ('merged', 'all'):
 
65
        statuses.append('Merged')
 
66
    return statuses
64
67
 
65
68
 
66
69
def plausible_launchpad_url(url):
108
111
        if self._mp.source_branch:
109
112
            return self._mp.source_branch.bzr_identity
110
113
        else:
 
114
            branch_name = ref_to_branch_name(
 
115
                self._mp.source_git_path.encode('utf-8'))
111
116
            return urlutils.join_segment_parameters(
112
117
                self._mp.source_git_repository.git_identity,
113
 
                {"branch": ref_to_branch_name(self._mp.source_git_path.encode('utf-8'))})
 
118
                {"branch": branch_name})
114
119
 
115
120
    def get_target_branch_url(self):
116
121
        if self._mp.target_branch:
117
122
            return self._mp.target_branch.bzr_identity
118
123
        else:
 
124
            branch_name = ref_to_branch_name(
 
125
                self._mp.target_git_path.encode('utf-8'))
119
126
            return urlutils.join_segment_parameters(
120
127
                self._mp.target_git_repository.git_identity,
121
 
                {"branch": ref_to_branch_name(self._mp.target_git_path.encode('utf-8'))})
 
128
                {"branch": branch_name})
122
129
 
123
130
    @property
124
131
    def url(self):
161
168
        url, params = urlutils.split_segment_parameters(branch.user_url)
162
169
        (scheme, user, password, host, port, path) = urlutils.parse_url(
163
170
            url)
164
 
        repo_lp = self.launchpad.git_repositories.getByPath(path=path.strip('/'))
 
171
        repo_lp = self.launchpad.git_repositories.getByPath(
 
172
            path=path.strip('/'))
165
173
        try:
166
174
            ref_path = params['ref']
167
175
        except KeyError:
174
182
        return (repo_lp, ref_lp)
175
183
 
176
184
    def _get_lp_bzr_branch_from_branch(self, branch):
177
 
        return self.launchpad.branches.getByUrl(url=urlutils.unescape(branch.user_url))
 
185
        return self.launchpad.branches.getByUrl(
 
186
            url=urlutils.unescape(branch.user_url))
178
187
 
179
188
    def _get_derived_git_path(self, base_path, owner, project):
180
189
        base_repo = self.launchpad.git_repositories.getByPath(path=base_path)
181
190
        if project is None:
182
191
            project = '/'.join(base_repo.unique_name.split('/')[1:])
183
 
        # TODO(jelmer): Surely there is a better way of creating one of these URLs?
 
192
        # TODO(jelmer): Surely there is a better way of creating one of these
 
193
        # URLs?
184
194
        return "~%s/%s" % (owner, project)
185
195
 
186
196
    def _publish_git(self, local_branch, base_path, name, owner, project=None,
203
213
                    lossy=True)
204
214
        else:
205
215
            try:
206
 
                dir_to = dir_to.push_branch(local_branch, revision_id, overwrite=overwrite, name=name)
 
216
                dir_to = dir_to.push_branch(
 
217
                    local_branch, revision_id, overwrite=overwrite, name=name)
207
218
            except errors.NoRoundtrippingSupport:
208
219
                if not allow_lossy:
209
220
                    raise
210
 
                dir_to = dir_to.push_branch(local_branch, revision_id, overwrite=overwrite, name=name, lossy=True)
 
221
                dir_to = dir_to.push_branch(
 
222
                    local_branch, revision_id, overwrite=overwrite, name=name,
 
223
                    lossy=True)
211
224
            br_to = dir_to.target_branch
212
 
        return br_to, ("https://git.launchpad.net/%s/+ref/%s" % (to_path, name))
 
225
        return br_to, (
 
226
            "https://git.launchpad.net/%s/+ref/%s" % (to_path, name))
213
227
 
214
228
    def _get_derived_bzr_path(self, base_branch, name, owner, project):
215
229
        if project is None:
216
230
            base_branch_lp = self._get_lp_bzr_branch_from_branch(base_branch)
217
231
            project = '/'.join(base_branch_lp.unique_name.split('/')[1:-1])
218
 
        # TODO(jelmer): Surely there is a better way of creating one of these URLs?
 
232
        # TODO(jelmer): Surely there is a better way of creating one of these
 
233
        # URLs?
219
234
        return "~%s/%s/%s" % (owner, project, name)
220
235
 
221
236
    def get_push_url(self, branch):
229
244
        else:
230
245
            raise AssertionError
231
246
 
232
 
    def _publish_bzr(self, local_branch, base_branch, name, owner, project=None,
233
 
                     revision_id=None, overwrite=False, allow_lossy=True):
 
247
    def _publish_bzr(self, local_branch, base_branch, name, owner,
 
248
                     project=None, revision_id=None, overwrite=False,
 
249
                     allow_lossy=True):
234
250
        to_path = self._get_derived_bzr_path(base_branch, name, owner, project)
235
251
        to_transport = get_transport("lp:" + to_path)
236
252
        try:
240
256
            dir_to = None
241
257
 
242
258
        if dir_to is None:
243
 
            br_to = local_branch.create_clone_on_transport(to_transport, revision_id=revision_id)
 
259
            br_to = local_branch.create_clone_on_transport(
 
260
                to_transport, revision_id=revision_id)
244
261
        else:
245
 
            br_to = dir_to.push_branch(local_branch, revision_id, overwrite=overwrite).target_branch
 
262
            br_to = dir_to.push_branch(
 
263
                local_branch, revision_id, overwrite=overwrite).target_branch
246
264
        return br_to, ("https://code.launchpad.net/" + to_path)
247
265
 
248
266
    def _split_url(self, url):
257
275
            raise ValueError("unknown host %s" % host)
258
276
        return (vcs, user, password, path, params)
259
277
 
260
 
    def publish_derived(self, local_branch, base_branch, name, project=None, owner=None,
261
 
                        revision_id=None, overwrite=False, allow_lossy=True):
 
278
    def publish_derived(self, local_branch, base_branch, name, project=None,
 
279
                        owner=None, revision_id=None, overwrite=False,
 
280
                        allow_lossy=True):
262
281
        """Publish a branch to the site, derived from base_branch.
263
282
 
264
283
        :param base_branch: branch to derive the new branch from
270
289
        """
271
290
        if owner is None:
272
291
            owner = self.launchpad.me.name
273
 
        (base_vcs, base_user, base_password, base_path, base_params) = self._split_url(
274
 
            base_branch.user_url)
 
292
        (base_vcs, base_user, base_password, base_path,
 
293
            base_params) = self._split_url(base_branch.user_url)
275
294
        # TODO(jelmer): Prevent publishing to development focus
276
295
        if base_vcs == 'bzr':
277
296
            return self._publish_bzr(
289
308
    def get_derived_branch(self, base_branch, name, project=None, owner=None):
290
309
        if owner is None:
291
310
            owner = self.launchpad.me.name
292
 
        (base_vcs, base_user, base_password, base_path, base_params) = self._split_url(
293
 
            base_branch.user_url)
 
311
        (base_vcs, base_user, base_password, base_path,
 
312
            base_params) = self._split_url(base_branch.user_url)
294
313
        if base_vcs == 'bzr':
295
 
            to_path = self._get_derived_bzr_path(base_branch, name, owner, project)
 
314
            to_path = self._get_derived_bzr_path(
 
315
                base_branch, name, owner, project)
296
316
            return _mod_branch.Branch.open("lp:" + to_path)
297
317
        elif base_vcs == 'git':
298
318
            to_path = self._get_derived_git_path(
302
322
        else:
303
323
            raise AssertionError('not a valid Launchpad URL')
304
324
 
305
 
    def get_proposal(self, source_branch, target_branch):
306
 
        (base_vcs, base_user, base_password, base_path, base_params) = (
307
 
            self._split_url(target_branch.user_url))
 
325
    def iter_proposals(self, source_branch, target_branch, status='open'):
 
326
        (base_vcs, base_user, base_password, base_path,
 
327
            base_params) = self._split_url(target_branch.user_url)
 
328
        statuses = status_to_lp_mp_statuses(status)
308
329
        if base_vcs == 'bzr':
309
330
            target_branch_lp = self.launchpad.branches.getByUrl(
310
331
                url=target_branch.user_url)
311
332
            source_branch_lp = self.launchpad.branches.getByUrl(
312
333
                url=source_branch.user_url)
313
 
            for mp in target_branch_lp.getMergeProposals(
314
 
                    status=MERGE_PROPOSAL_STATUSES):
315
 
                if mp.target_branch != target_branch_lp:
316
 
                    continue
317
 
                if mp.source_branch != source_branch_lp:
318
 
                    continue
319
 
                return LaunchpadMergeProposal(mp)
320
 
            raise NoMergeProposal()
 
334
            for mp in target_branch_lp.getMergeProposals(status=statuses):
 
335
                if mp.source_branch_link != source_branch_lp.self_link:
 
336
                    continue
 
337
                yield LaunchpadMergeProposal(mp)
321
338
        elif base_vcs == 'git':
322
339
            (source_repo_lp, source_branch_lp) = (
323
340
                self.lp_host._get_lp_git_ref_from_branch(source_branch))
324
341
            (target_repo_lp, target_branch_lp) = (
325
342
                self.lp_host._get_lp_git_ref_from_branch(target_branch))
326
 
            for mp in target_branch_lp.getMergeProposals(
327
 
                    status=MERGE_PROPOSAL_STATUSES):
 
343
            for mp in target_branch_lp.getMergeProposals(status=statuses):
328
344
                if (target_branch_lp.path != mp.target_git_path or
329
345
                        target_repo_lp != mp.target_git_repository or
330
346
                        source_branch_lp.path != mp.source_git_path or
331
347
                        source_repo_lp != mp.source_git_repository):
332
348
                    continue
333
 
                return LaunchpadMergeProposal(mp)
334
 
            raise NoMergeProposal()
 
349
                yield LaunchpadMergeProposal(mp)
335
350
        else:
336
351
            raise AssertionError('not a valid Launchpad URL')
337
352
 
338
353
    def get_proposer(self, source_branch, target_branch):
339
 
        (base_vcs, base_user, base_password, base_path, base_params) = (
340
 
            self._split_url(target_branch.user_url))
 
354
        (base_vcs, base_user, base_password, base_path,
 
355
            base_params) = self._split_url(target_branch.user_url)
341
356
        if base_vcs == 'bzr':
342
357
            return LaunchpadBazaarMergeProposalBuilder(
343
358
                self, source_branch, target_branch)
352
367
        yield cls()
353
368
 
354
369
    def iter_my_proposals(self, status='open'):
355
 
        statuses = []
356
 
        if status in ('open', 'all'):
357
 
            statuses.extend([
358
 
                'Work in progress',
359
 
                'Needs review',
360
 
                'Approved',
361
 
                'Code failed to merge',
362
 
                'Queued'])
363
 
        if status in ('closed', 'all'):
364
 
            statuses.extend(['Rejected', 'Superseded'])
365
 
        if status in ('merged', 'all'):
366
 
            statuses.append('Merged')
 
370
        statuses = status_to_lp_mp_statuses(status)
367
371
        for mp in self.launchpad.me.getMergeProposals(status=statuses):
368
372
            yield LaunchpadMergeProposal(mp)
369
373
 
392
396
        self.lp_host = lp_host
393
397
        self.launchpad = lp_host.launchpad
394
398
        self.source_branch = source_branch
395
 
        self.source_branch_lp = self.launchpad.branches.getByUrl(url=source_branch.user_url)
 
399
        self.source_branch_lp = self.launchpad.branches.getByUrl(
 
400
            url=source_branch.user_url)
396
401
        if target_branch is None:
397
402
            self.target_branch_lp = self.source_branch_lp.get_target()
398
 
            self.target_branch = _mod_branch.Branch.open(self.target_branch_lp.bzr_identity)
 
403
            self.target_branch = _mod_branch.Branch.open(
 
404
                self.target_branch_lp.bzr_identity)
399
405
        else:
400
406
            self.target_branch = target_branch
401
 
            self.target_branch_lp = self.launchpad.branches.getByUrl(url=target_branch.user_url)
 
407
            self.target_branch_lp = self.launchpad.branches.getByUrl(
 
408
                url=target_branch.user_url)
402
409
        self.commit_message = message
403
410
        self.approve = approve
404
411
        self.fixes = fixes
452
459
            _call_webservice(
453
460
                mp.createComment,
454
461
                vote=u'Approve',
455
 
                subject='', # Use the default subject.
 
462
                subject='',  # Use the default subject.
456
463
                content=u"Rubberstamp! Proposer approves of own proposal.")
457
464
            _call_webservice(mp.setStatus, status=u'Approved',
458
465
                             revid=self.source_branch.last_revision())
516
523
        self.lp_host = lp_host
517
524
        self.launchpad = lp_host.launchpad
518
525
        self.source_branch = source_branch
519
 
        (self.source_repo_lp, self.source_branch_lp) = self.lp_host._get_lp_git_ref_from_branch(source_branch)
 
526
        (self.source_repo_lp,
 
527
            self.source_branch_lp) = self.lp_host._get_lp_git_ref_from_branch(
 
528
                source_branch)
520
529
        if target_branch is None:
521
530
            self.target_branch_lp = self.source_branch.get_target()
522
 
            self.target_branch = _mod_branch.Branch.open(self.target_branch_lp.git_https_url)
 
531
            self.target_branch = _mod_branch.Branch.open(
 
532
                self.target_branch_lp.git_https_url)
523
533
        else:
524
534
            self.target_branch = target_branch
525
 
            (self.target_repo_lp, self.target_branch_lp) = self.lp_host._get_lp_git_ref_from_branch(target_branch)
 
535
            (self.target_repo_lp, self.target_branch_lp) = (
 
536
                self.lp_host._get_lp_git_ref_from_branch(target_branch))
526
537
        self.commit_message = message
527
538
        self.approve = approve
528
539
        self.fixes = fixes
576
587
            _call_webservice(
577
588
                mp.createComment,
578
589
                vote=u'Approve',
579
 
                subject='', # Use the default subject.
 
590
                subject='',  # Use the default subject.
580
591
                content=u"Rubberstamp! Proposer approves of own proposal.")
581
592
            _call_webservice(
582
593
                mp.setStatus, status=u'Approved',
588
599
        if labels:
589
600
            raise LabelsUnsupported()
590
601
        if prerequisite_branch is not None:
591
 
            (prereq_repo_lp, prereq_branch_lp) = self.lp_host._get_lp_git_ref_from_branch(prerequisite_branch)
 
602
            (prereq_repo_lp, prereq_branch_lp) = (
 
603
                self.lp_host._get_lp_git_ref_from_branch(prerequisite_branch))
592
604
        else:
593
605
            prereq_branch_lp = None
594
606
        if reviewers is None: