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

  • Committer: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2020-07-28 02:47:10 UTC
  • mfrom: (7519.1.1 merge-3.1)
  • Revision ID: breezy.the.bot@gmail.com-20200728024710-a2ylds219f1lsl62
Merge lp:brz/3.1.

Merged from https://code.launchpad.net/~jelmer/brz/merge-3.1/+merge/388173

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Support for GitHub."""
18
18
 
19
 
from __future__ import absolute_import
20
 
 
21
19
import json
22
20
import os
23
21
 
44
42
    version_string as breezy_version,
45
43
    )
46
44
from ...config import AuthenticationConfig, GlobalStack
47
 
from ...errors import InvalidHttpResponse, PermissionDenied
 
45
from ...errors import (
 
46
    InvalidHttpResponse,
 
47
    PermissionDenied,
 
48
    UnexpectedHttpStatus,
 
49
    )
48
50
from ...git.urls import git_url_to_bzr_url
49
51
from ...i18n import gettext
50
 
from ...sixish import PY3
51
52
from ...trace import note
52
53
from ...transport import get_transport
53
54
from ...transport.http import default_user_agent
123
124
    def __repr__(self):
124
125
        return "<%s at %r>" % (type(self).__name__, self.url)
125
126
 
 
127
    name = 'GitHub'
 
128
 
126
129
    @property
127
130
    def url(self):
128
131
        return self._pr['html_url']
135
138
    def get_source_branch_url(self):
136
139
        return self._branch_from_part(self._pr['head'])
137
140
 
 
141
    def get_source_revision(self):
 
142
        """Return the latest revision for the source branch."""
 
143
        from breezy.git.mapping import default_mapping
 
144
        return default_mapping.revision_id_foreign_to_bzr(
 
145
            self._pr['head']['sha'].encode('ascii'))
 
146
 
138
147
    def get_target_branch_url(self):
139
148
        return self._branch_from_part(self._pr['base'])
140
149
 
159
168
        if response.status == 422:
160
169
            raise ValidationFailed(json.loads(response.text))
161
170
        if response.status != 200:
162
 
            raise InvalidHttpResponse(self._pr['url'], response.text)
 
171
            raise UnexpectedHttpStatus(self._pr['url'], response.status)
163
172
        self._pr = json.loads(response.text)
164
173
 
165
174
    def set_description(self, description):
188
197
 
189
198
    def merge(self, commit_message=None):
190
199
        # https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button
191
 
        self._pr.merge(commit_message=commit_message)
 
200
        data = {}
 
201
        if commit_message:
 
202
            data['commit_message'] = commit_messae
 
203
        response = self._gh._api_request(
 
204
            'PUT', self._pr['url'] + "/merge", body=json.dumps(data).encode('utf-8'))
 
205
        if response.status == 422:
 
206
            raise ValidationFailed(json.loads(response.text))
 
207
        if response.status != 200:
 
208
            raise UnexpectedHttpStatus(self._pr['url'], response.status)
192
209
 
193
210
    def get_merged_by(self):
194
211
        merged_by = self._pr.get('merged_by')
203
220
        import iso8601
204
221
        return iso8601.parse_date(merged_at)
205
222
 
 
223
    def post_comment(self, body):
 
224
        data = {'body': body}
 
225
        response = self._gh._api_request(
 
226
            'POST', self._pr['comments_url'], body=json.dumps(data).encode('utf-8'))
 
227
        if response.status == 422:
 
228
            raise ValidationFailed(json.loads(response.text))
 
229
        if response.status != 201:
 
230
            raise UnexpectedHttpStatus(
 
231
                self._pr['comments_url'], response.status)
 
232
        json.loads(response.text)
 
233
 
206
234
 
207
235
def parse_github_url(url):
208
236
    (scheme, user, password, host, port, path) = urlutils.parse_url(
222
250
 
223
251
 
224
252
def github_url_to_bzr_url(url, branch_name):
225
 
    if not PY3:
226
 
        branch_name = branch_name.encode('utf-8')
227
253
    return git_url_to_bzr_url(url, branch_name)
228
254
 
229
255
 
263
289
            raise NoSuchProject(path)
264
290
        if response.status == 200:
265
291
            return json.loads(response.text)
266
 
        raise InvalidHttpResponse(path, response.text)
 
292
        raise UnexpectedHttpStatus(path, response.status)
267
293
 
268
294
    def _get_repo_pulls(self, path, head=None, state=None):
269
295
        path = path + '?'
279
305
            raise NoSuchProject(path)
280
306
        if response.status == 200:
281
307
            return json.loads(response.text)
282
 
        raise InvalidHttpResponse(path, response.text)
 
308
        raise UnexpectedHttpStatus(path, response.status)
283
309
 
284
310
    def _create_pull(self, path, title, head, base, body=None, labels=None,
285
311
                     assignee=None, draft=False, maintainer_can_modify=False):
302
328
        if response.status == 403:
303
329
            raise PermissionDenied(path, response.text)
304
330
        if response.status != 201:
305
 
            raise InvalidHttpResponse(path, 'req is invalid %d %r: %r' % (response.status, data, response.text))
 
331
            raise UnexpectedHttpStatus(path, response.status)
306
332
        return json.loads(response.text)
307
333
 
308
334
    def _get_user_by_email(self, email):
309
335
        path = 'search/users?q=%s+in:email' % email
310
336
        response = self._api_request('GET', path)
311
337
        if response.status != 200:
312
 
            raise InvalidHttpResponse(path, response.text)
 
338
            raise UnexpectedHttpStatus(path, response.status)
313
339
        ret = json.loads(response.text)
314
340
        if ret['total_count'] == 0:
315
341
            raise KeyError('no user with email %s' % email)
324
350
            path = 'user'
325
351
        response = self._api_request('GET', path)
326
352
        if response.status != 200:
327
 
            raise InvalidHttpResponse(path, response.text)
 
353
            raise UnexpectedHttpStatus(path, response.status)
328
354
        return json.loads(response.text)
329
355
 
330
356
    def _get_organization(self, name):
331
357
        path = 'orgs/%s' % name
332
358
        response = self._api_request('GET', path)
333
359
        if response.status != 200:
334
 
            raise InvalidHttpResponse(path, response.text)
 
360
            raise UnexpectedHttpStatus(path, response.status)
335
361
        return json.loads(response.text)
336
362
 
337
363
    def _list_paged(self, path, parameters=None, per_page=None):
350
376
                ';'.join(['%s=%s' % (k, urlutils.quote(v))
351
377
                          for (k, v) in parameters.items()]))
352
378
            if response.status != 200:
353
 
                raise InvalidHttpResponse(path, response.text)
 
379
                raise UnexpectedHttpStatus(path, response.status)
354
380
            data = json.loads(response.text)
355
381
            for entry in data['items']:
356
382
                i += 1
364
390
        return self._list_paged(path, {'q': query}, per_page=DEFAULT_PER_PAGE)
365
391
 
366
392
    def _create_fork(self, path, owner=None):
367
 
        if owner and owner != self._current_user['login']:
 
393
        if owner and owner != self.current_user['login']:
368
394
            path += '?organization=%s' % owner
369
395
        response = self._api_request('POST', path)
370
396
        if response.status != 202:
371
 
            raise InvalidHttpResponse(path, 'status: %d, %r' % (response.status, response.text))
 
397
            raise UnexpectedHttpStatus(path, response.status)
372
398
        return json.loads(response.text)
373
399
 
374
400
    @property
378
404
    def __init__(self, transport):
379
405
        self._token = retrieve_github_token('https', GITHUB_HOST)
380
406
        self.transport = transport
381
 
        self._current_user = self._get_user()
 
407
        self._current_user = None
 
408
 
 
409
    @property
 
410
    def current_user(self):
 
411
        if self._current_user is None:
 
412
            self._current_user = self._get_user()
 
413
        return self._current_user
382
414
 
383
415
    def publish_derived(self, local_branch, base_branch, name, project=None,
384
416
                        owner=None, revision_id=None, overwrite=False,
386
418
        base_owner, base_project, base_branch_name = parse_github_branch_url(base_branch)
387
419
        base_repo = self._get_repo(base_owner, base_project)
388
420
        if owner is None:
389
 
            owner = self._current_user['login']
 
421
            owner = self.current_user['login']
390
422
        if project is None:
391
423
            project = base_repo['name']
392
424
        try:
422
454
        base_owner, base_project, base_branch_name = parse_github_branch_url(base_branch)
423
455
        base_repo = self._get_repo(base_owner, base_project)
424
456
        if owner is None:
425
 
            owner = self._current_user['login']
 
457
            owner = self.current_user['login']
426
458
        if project is None:
427
459
            project = base_repo['name']
428
460
        try:
497
529
            query.append('is:closed')
498
530
        elif status == 'merged':
499
531
            query.append('is:merged')
500
 
        query.append('author:%s' % self._current_user['login'])
 
532
        query.append('author:%s' % self.current_user['login'])
501
533
        for issue in self._search_issues(query=' '.join(query)):
502
534
            url = issue['pull_request']['url']
503
535
            response = self._api_request('GET', url)
504
536
            if response.status != 200:
505
 
                raise InvalidHttpResponse(url, response.text)
 
537
                raise UnexpectedHttpStatus(url, response.status)
506
538
            yield GitHubMergeProposal(self, json.loads(response.text))
507
539
 
508
540
    def get_proposal_by_url(self, url):
511
543
    def iter_my_forks(self):
512
544
        response = self._api_request('GET', '/user/repos')
513
545
        if response.status != 200:
514
 
            raise InvalidHttpResponse(url, response.text)
 
546
            raise UnexpectedHttpStatus(self.transport.user_url, response.status)
515
547
        for project in json.loads(response.text):
516
548
            if not project['fork']:
517
549
                continue
526
558
            return
527
559
        if response.status == 200:
528
560
            return json.loads(response.text)
529
 
        raise InvalidHttpResponse(path, response.text)
 
561
        raise UnexpectedHttpStatus(path, response.status)
 
562
 
 
563
    def get_current_user(self):
 
564
        return self.current_user['login']
 
565
 
 
566
    def get_user_url(self, username):
 
567
        return urlutils.join(self.base_url, username)
530
568
 
531
569
 
532
570
class GitHubMergeProposalBuilder(MergeProposalBuilder):