/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/github.py

  • Committer: Jelmer Vernooij
  • Date: 2019-12-22 23:16:21 UTC
  • mfrom: (7422 work)
  • mto: This revision was merged to the branch mainline in revision 7426.
  • Revision ID: jelmer@jelmer.uk-20191222231621-3p14u9zaypv3q8zl
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
GITHUB_HOST = 'github.com'
56
56
WEB_GITHUB_URL = 'https://github.com'
57
57
API_GITHUB_URL = 'https://api.github.com'
 
58
DEFAULT_PER_PAGE = 50
58
59
 
59
60
 
60
61
def store_github_token(scheme, host, token):
207
208
def github_url_to_bzr_url(url, branch_name):
208
209
    if not PY3:
209
210
        branch_name = branch_name.encode('utf-8')
210
 
    return urlutils.join_segment_parameters(
211
 
        git_url_to_bzr_url(url), {"branch": branch_name})
 
211
    return git_url_to_bzr_url(url, branch_name)
212
212
 
213
213
 
214
214
class GitHub(Hoster):
303
303
            raise InvalidHttpResponse(path, response.text)
304
304
        return json.loads(response.text)
305
305
 
 
306
    def _list_paged(self, path, parameters=None, per_page=None):
 
307
        if parameters is None:
 
308
            parameters = {}
 
309
        else:
 
310
            parameters = dict(parameters.items())
 
311
        if per_page:
 
312
            parameters['per_page'] = str(per_page)
 
313
        page = 1
 
314
        i = 0
 
315
        while path:
 
316
            parameters['page'] = str(page)
 
317
            response = self._api_request(
 
318
                'GET', path + '?' +
 
319
                ';'.join(['%s=%s' % (k, urlutils.quote(v))
 
320
                          for (k, v) in parameters.items()]))
 
321
            if response.status != 200:
 
322
                raise InvalidHttpResponse(path, response.text)
 
323
            data = json.loads(response.text)
 
324
            for entry in data['items']:
 
325
                i += 1
 
326
                yield entry
 
327
            if i >= data['total_count']:
 
328
                break
 
329
            page += 1
 
330
 
306
331
    def _search_issues(self, query):
307
332
        path = 'search/issues'
308
 
        response = self._api_request(
309
 
            'GET', path + '?q=' + urlutils.quote(query))
310
 
        if response.status != 200:
311
 
            raise InvalidHttpResponse(path, response.text)
312
 
        return json.loads(response.text)
 
333
        return self._list_paged(path, {'q': query}, per_page=DEFAULT_PER_PAGE)
313
334
 
314
335
    def _create_fork(self, repo, owner=None):
315
 
        (orig_owner, orig_repo) = repo.split('/')
316
 
        path = '/repos/:%s/:%s/forks' % (orig_owner, orig_repo)
317
 
        if owner:
 
336
        path = '/repos/%s/forks' % (repo, )
 
337
        if owner and owner != self._current_user['login']:
318
338
            path += '?organization=%s' % owner
319
339
        response = self._api_request('POST', path)
320
340
        if response.status != 202:
321
 
            raise InvalidHttpResponse(path, response.text)
 
341
            raise InvalidHttpResponse(path, 'status: %d, %r' % (response.status, response.text))
322
342
        return json.loads(response.text)
323
343
 
324
344
    @property
333
353
    def publish_derived(self, local_branch, base_branch, name, project=None,
334
354
                        owner=None, revision_id=None, overwrite=False,
335
355
                        allow_lossy=True):
336
 
        import github
337
356
        base_owner, base_project, base_branch_name = parse_github_branch_url(base_branch)
338
357
        base_repo = self._get_repo('%s/%s' % (base_owner, base_project))
339
358
        if owner is None:
342
361
            project = base_repo['name']
343
362
        try:
344
363
            remote_repo = self._get_repo('%s/%s' % (owner, project))
345
 
        except github.UnknownObjectException:
346
 
            base_repo = self._get_repo('%s/%s' % (base_owner, base_project))
347
 
            remote_repo = self._create_fork(base_repo, owner)
 
364
        except NoSuchProject:
 
365
            base_repo_path = '%s/%s' % (base_owner, base_project)
 
366
            base_repo = self._get_repo(base_repo_path)
 
367
            remote_repo = self._create_fork(base_repo_path, owner)
348
368
            note(gettext('Forking new repository %s from %s') %
349
369
                 (remote_repo['html_url'], base_repo['html_url']))
350
370
        else:
369
389
        return github_url_to_bzr_url(repo['ssh_url'], branch_name)
370
390
 
371
391
    def get_derived_branch(self, base_branch, name, project=None, owner=None):
372
 
        import github
373
392
        base_owner, base_project, base_branch_name = parse_github_branch_url(base_branch)
374
393
        base_repo = self._get_repo('%s/%s' % (base_owner, base_project))
375
394
        if owner is None:
380
399
            remote_repo = self._get_repo('%s/%s' % (owner, project))
381
400
            full_url = github_url_to_bzr_url(remote_repo['ssh_url'], name)
382
401
            return _mod_branch.Branch.open(full_url)
383
 
        except github.UnknownObjectException:
 
402
        except NoSuchProject:
384
403
            raise errors.NotBranchError('%s/%s/%s' % (WEB_GITHUB_URL, owner, project))
385
404
 
386
405
    def get_proposer(self, source_branch, target_branch):
450
469
        elif status == 'merged':
451
470
            query.append('is:merged')
452
471
        query.append('author:%s' % self._current_user['login'])
453
 
        for issue in self._search_issues(query=' '.join(query))['items']:
 
472
        for issue in self._search_issues(query=' '.join(query)):
454
473
            url = issue['pull_request']['url']
455
474
            response = self._api_request('GET', url)
456
475
            if response.status != 200:
495
514
        if prerequisite_branch is not None:
496
515
            raise PrerequisiteBranchUnsupported(self)
497
516
        # Note that commit_message is ignored, since github doesn't support it.
498
 
        import github
499
517
        # TODO(jelmer): Probe for right repo name
500
518
        if self.target_repo_name.endswith('.git'):
501
519
            self.target_repo_name = self.target_repo_name[:-4]
510
528
                base=self.target_branch_name)
511
529
        except ValidationFailed:
512
530
            raise MergeProposalExists(self.source_branch.user_url)
 
531
        assignees = []
513
532
        if reviewers:
514
533
            for reviewer in reviewers:
515
534
                if '@' in reviewer:
516
535
                    user = self.gh._get_user_by_email(reviewer)
517
536
                else:
518
537
                    user = self.gh._get_user(reviewer)
519
 
                pull_request.assignees.append(user['login'])
520
 
        if labels:
521
 
            for label in labels:
522
 
                pull_request.issue.labels.append(label)
 
538
                assignees.append(user['login'])
 
539
        if labels or assignees:
 
540
            data = {}
 
541
            if labels:
 
542
                data['labels'] = labels
 
543
            if assignees:
 
544
                data['assignees'] = assignees
 
545
            response = self.gh._api_request(
 
546
                'PATCH', pull_request['issue_url'], body=json.dumps(data).encode('utf-8'))
 
547
            if response.status == 422:
 
548
                raise ValidationFailed(json.loads(response.text))
 
549
            if response.status != 200:
 
550
                raise InvalidHttpResponse(pull_request['issue_url'], response.text)
523
551
        return GitHubMergeProposal(self.gh, pull_request)