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

  • Committer: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2019-08-12 19:51:40 UTC
  • mfrom: (7380.1.2 more-git-fixes)
  • Revision ID: breezy.the.bot@gmail.com-20190812195140-guyldqnadc30atyj
Several more fixes for git merge proposals.

Merged from https://code.launchpad.net/~jelmer/brz/more-git-fixes/+merge/371172

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
import json
22
22
import os
 
23
import time
23
24
 
24
25
from ... import (
25
26
    bedding,
30
31
    )
31
32
from ...git.urls import git_url_to_bzr_url
32
33
from ...sixish import PY3
 
34
from ...trace import mutter
33
35
from ...transport import get_transport
34
36
 
35
37
from .propose import (
172
174
        self.gl = gl
173
175
        self._mr = mr
174
176
 
 
177
    def _update(self, **kwargs):
 
178
        self.gl._update_merge_request(self._mr['project_id'], self._mr['iid'], kwargs)
 
179
 
175
180
    @property
176
181
    def url(self):
177
182
        return self._mr['web_url']
180
185
        return self._mr['description']
181
186
 
182
187
    def set_description(self, description):
183
 
        self._mr['description'] = description
184
 
        self.gl._update_merge_requests(self._mr)
 
188
        self._update(description=description, title=description.splitlines()[0])
185
189
 
186
190
    def get_commit_message(self):
187
 
        return None
 
191
        return self._mr.get('merge_commit_message')
 
192
 
 
193
    def set_commit_message(self, message):
 
194
        raise errors.UnsupportedOperation(self.set_commit_message, self)
188
195
 
189
196
    def _branch_url_from_project(self, project_id, branch_name):
 
197
        if project_id is None:
 
198
            return None
190
199
        project = self.gl._get_project(project_id)
191
200
        return gitlab_url_to_bzr_url(project['http_url_to_repo'], branch_name)
192
201
 
202
211
        return (self._mr['state'] == 'merged')
203
212
 
204
213
    def close(self):
205
 
        self._mr['state_event'] = 'close'
206
 
        self.gl._update_merge_requests(self._mr)
 
214
        self._update(state_event='close')
207
215
 
208
216
    def merge(self, commit_message=None):
209
217
        # https://docs.gitlab.com/ee/api/merge_requests.html#accept-mr
210
218
        self._mr.merge(merge_commit_message=commit_message)
211
219
 
 
220
    def can_be_merged(self):
 
221
        if self._mr['merge_status'] == 'cannot_be_merged':
 
222
            return False
 
223
        elif self._mr['merge_status'] == 'can_be_merged':
 
224
            return True
 
225
        else:
 
226
            raise ValueError(self._mr['merge_status'])
 
227
 
212
228
 
213
229
def gitlab_url_to_bzr_url(url, name):
214
230
    if not PY3:
230
246
    def base_url(self):
231
247
        return self.transport.base
232
248
 
233
 
    def _api_request(self, method, path, data=None):
 
249
    def _api_request(self, method, path, fields=None):
234
250
        return self.transport.request(
235
251
            method, urlutils.join(self.base_url, 'api', 'v4', path),
236
 
            headers=self.headers, body=data)
 
252
            headers=self.headers, fields=fields)
237
253
 
238
254
    def __init__(self, transport, private_token):
239
255
        self.transport = transport
249
265
            return json.loads(response.data)
250
266
        raise errors.InvalidHttpResponse(path, response.text)
251
267
 
252
 
    def _fork_project(self, project_name):
 
268
    def _fork_project(self, project_name, timeout=50, interval=5):
253
269
        path = 'projects/%s/fork' % urlutils.quote(str(project_name), '')
254
270
        response = self._api_request('POST', path)
255
 
        if response != 201:
 
271
        if response.status not in (200, 201):
256
272
            raise errors.InvalidHttpResponse(path, response.text)
257
 
        return json.loads(response.data)
 
273
        # The response should be valid JSON, but let's ignore it
 
274
        json.loads(response.data)
 
275
        # Spin and wait until import_status for new project
 
276
        # is complete.
 
277
        deadline = time.time() + timeout
 
278
        while True:
 
279
            project = self._get_project(project_name)
 
280
            if project['import_status'] in ('finished', 'none'):
 
281
                return project
 
282
            mutter('import status is %s', project['import_status'])
 
283
            if time.time() > deadline:
 
284
                raise Exception('timeout waiting for project to become available')
 
285
            time.sleep(interval)
258
286
 
259
287
    def _get_logged_in_username(self):
260
288
        return self._current_user['username']
278
306
            return json.loads(response.data)
279
307
        raise errors.InvalidHttpResponse(path, response.text)
280
308
 
 
309
    def _update_merge_request(self, project_id, iid, mr):
 
310
        path = 'projects/%s/merge_requests/%s' % (
 
311
            urlutils.quote(str(project_id), ''), iid)
 
312
        response = self._api_request('PUT', path, fields=mr)
 
313
        if response.status == 200:
 
314
            return json.loads(response.data)
 
315
        raise errors.InvalidHttpResponse(path, response.text)
 
316
 
281
317
    def _create_mergerequest(
282
318
            self, title, source_project_id, target_project_id,
283
319
            source_branch_name, target_branch_name, description,
292
328
            }
293
329
        if labels:
294
330
            fields['labels'] = labels
295
 
        response = self._api_request(
296
 
            'POST', path, data=json.dumps(fields).encode('utf-8'))
 
331
        response = self._api_request('POST', path, fields=fields)
297
332
        if response.status == 403:
298
333
            raise errors.PermissionDenied(response.text)
299
334
        if response.status == 409:
320
355
            target_project = self._get_project('%s/%s' % (owner, project))
321
356
        except NoSuchProject:
322
357
            target_project = self._fork_project(base_project)
323
 
            # TODO(jelmer): Spin and wait until import_status for new project
324
 
            # is complete.
325
358
        remote_repo_url = git_url_to_bzr_url(target_project['ssh_url_to_repo'])
326
359
        remote_dir = controldir.ControlDir.open(remote_repo_url)
327
360
        try: