/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-08-11 13:21:03 UTC
  • mfrom: (7379 work)
  • mto: This revision was merged to the branch mainline in revision 7388.
  • Revision ID: jelmer@jelmer.uk-20190811132103-u3ne03yf37c1h57n
merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
from __future__ import absolute_import
20
20
 
 
21
import json
21
22
import os
22
23
 
23
24
from .propose import (
107
108
 
108
109
class GitHubMergeProposal(MergeProposal):
109
110
 
110
 
    def __init__(self, pr):
 
111
    def __init__(self, gh, pr):
 
112
        self._gh = gh
111
113
        self._pr = pr
112
114
 
113
115
    @property
129
131
    def get_commit_message(self):
130
132
        return None
131
133
 
 
134
    def set_commit_message(self, message):
 
135
        self._patch({'title': message})
 
136
 
 
137
    def _patch(self, data):
 
138
        response = self._gh._api_request(
 
139
            'PATCH', self._pr['url'], body=json.dumps(data).encode('utf-8'))
 
140
        if response != 200:
 
141
            raise InvalidHttpResponse(self._pr['url'], response.text)
 
142
        self._pr = json.loads(response.text)
 
143
 
132
144
    def set_description(self, description):
133
 
        self._pr.edit(body=description, title=determine_title(description))
 
145
        self._patch({
 
146
            'body': description,
 
147
            'title': determine_title(description),
 
148
            })
134
149
 
135
150
    def is_merged(self):
136
 
        return self._pr['merged']
 
151
        return self._pr['state'] == 'merged'
137
152
 
138
153
    def close(self):
139
 
        self._pr.edit(state='closed')
 
154
        self._patch({'state': 'closed'})
140
155
 
141
156
    def merge(self, commit_message=None):
142
157
        # https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button
177
192
    def __repr__(self):
178
193
        return "GitHub()"
179
194
 
180
 
    def _api_request(self, method, path):
 
195
    def _api_request(self, method, path, body=None):
181
196
        headers = {
182
197
            'Accept': 'application/vnd.github.v3+json'}
183
198
        if self._token:
184
199
            headers['Authorization'] = 'token %s' % self._token
185
200
        response = self.transport.request(
186
201
            method, urlutils.join(self.transport.base, path),
187
 
            headers=headers)
 
202
            headers=headers, body=body)
188
203
        if response.status == 401:
189
204
            raise GitHubLoginRequired(self)
190
205
        return response
195
210
        if response.status == 404:
196
211
            raise NoSuchProject(path)
197
212
        if response.status == 200:
198
 
            return response.json
 
213
            return json.loads(response.text)
 
214
        raise InvalidHttpResponse(path, response.text)
 
215
 
 
216
    def _get_repo_pulls(self, path, head=None, state=None):
 
217
        path = 'repos/' + path + '/pulls?'
 
218
        params = {}
 
219
        if head is not None:
 
220
            params['head'] = head
 
221
        if state is not None:
 
222
            params['state'] = state
 
223
        path += ';'.join(['%s=%s' % (k, urlutils.quote(v))
 
224
                         for k, v in params.items()])
 
225
        response = self._api_request('GET', path)
 
226
        if response.status == 404:
 
227
            raise NoSuchProject(path)
 
228
        if response.status == 200:
 
229
            return json.loads(response.text)
199
230
        raise InvalidHttpResponse(path, response.text)
200
231
 
201
232
    def _get_user(self, username=None):
206
237
        response = self._api_request('GET', path)
207
238
        if response.status != 200:
208
239
            raise InvalidHttpResponse(path, response.text)
209
 
        return response.json
 
240
        return json.loads(response.text)
210
241
 
211
242
    def _get_organization(self, name):
212
243
        path = 'orgs/:%s' % name
213
244
        response = self._api_request('GET', path)
214
245
        if response.status != 200:
215
246
            raise InvalidHttpResponse(path, response.text)
216
 
        return response.json
 
247
        return json.loads(response.text)
217
248
 
218
249
    def _search_issues(self, query):
219
250
        path = 'search/issues'
221
252
            'GET', path + '?q=' + urlutils.quote(query))
222
253
        if response.status != 200:
223
254
            raise InvalidHttpResponse(path, response.text)
224
 
        return response.json
 
255
        return json.loads(response.text)
225
256
 
226
257
    def _create_fork(self, repo, owner=None):
227
258
        (orig_owner, orig_repo) = repo.split('/')
231
262
        response = self._api_request('POST', path)
232
263
        if response != 202:
233
264
            raise InvalidHttpResponse(path, response.text)
234
 
        return response.json
 
265
        return json.loads(response.text)
235
266
 
236
267
    @property
237
268
    def base_url(self):
303
334
            parse_github_branch_url(source_branch))
304
335
        (target_owner, target_repo_name, target_branch_name) = (
305
336
            parse_github_branch_url(target_branch))
306
 
        target_repo = self._get_repo(
307
 
            "%s/%s" % (target_owner, target_repo_name))
 
337
        target_repo_path = "%s/%s" % (target_owner, target_repo_name)
 
338
        target_repo = self._get_repo(target_repo_path)
308
339
        state = {
309
340
            'open': 'open',
310
341
            'merged': 'closed',
311
342
            'closed': 'closed',
312
343
            'all': 'all'}
313
 
        for pull in target_repo.get_pulls(
314
 
                head=target_branch_name,
315
 
                state=state[status]):
316
 
            if (status == 'closed' and pull.merged or
317
 
                    status == 'merged' and not pull.merged):
318
 
                continue
319
 
            if pull.head.ref != source_branch_name:
320
 
                continue
321
 
            if pull.head.repo is None:
 
344
        pulls = self._get_repo_pulls(
 
345
            target_repo_path,
 
346
            head=target_branch_name,
 
347
            state=state[status])
 
348
        for pull in pulls:
 
349
            if (status == 'closed' and pull['merged'] or
 
350
                    status == 'merged' and not pull['merged']):
 
351
                continue
 
352
            if pull['head']['ref'] != source_branch_name:
 
353
                continue
 
354
            if pull['head']['repo'] is None:
322
355
                # Repo has gone the way of the dodo
323
356
                continue
324
 
            if (pull.head.repo.owner.login != source_owner or
325
 
                    pull.head.repo.name != source_repo_name):
 
357
            if (pull['head']['repo']['owner']['login'] != source_owner or
 
358
                    pull['head']['repo']['name'] != source_repo_name):
326
359
                continue
327
 
            yield GitHubMergeProposal(pull)
 
360
            yield GitHubMergeProposal(self, pull)
328
361
 
329
362
    def hosts(self, branch):
330
363
        try:
361
394
            query.append('is:merged')
362
395
        query.append('author:%s' % self._current_user['login'])
363
396
        for issue in self._search_issues(query=' '.join(query))['items']:
364
 
            yield GitHubMergeProposal(
365
 
                self.transport.request('GET', issue['pull_request']['url']).json)
 
397
            url = issue['pull_request']['url']
 
398
            response = self._api_request('GET', url)
 
399
            if response.status != 200:
 
400
                raise InvalidHttpResponse(url, response.text)
 
401
            yield GitHubMergeProposal(self, json.loads(response.text))
366
402
 
367
403
    def get_proposal_by_url(self, url):
368
404
        raise UnsupportedHoster(url)
426
462
        if labels:
427
463
            for label in labels:
428
464
                pull_request.issue.labels.append(label)
429
 
        return GitHubMergeProposal(pull_request)
 
465
        return GitHubMergeProposal(self.gh, pull_request)