diff options
Diffstat (limited to 'gitlab')
-rw-r--r-- | gitlab/cli.py | 20 | ||||
-rw-r--r-- | gitlab/exceptions.py | 22 | ||||
-rw-r--r-- | gitlab/objects.py | 37 |
3 files changed, 76 insertions, 3 deletions
diff --git a/gitlab/cli.py b/gitlab/cli.py index 090978b..91c45a0 100644 --- a/gitlab/cli.py +++ b/gitlab/cli.py @@ -41,6 +41,12 @@ EXTRA_ACTIONS = { 'blob': {'required': ['id', 'project-id', 'filepath']}, 'builds': {'required': ['id', 'project-id']}}, + gitlab.ProjectMergeRequest: { + 'merge': {'required': ['id', 'project-id'], + 'optional': ['merge-commit-message', + 'should-remove-source-branch', + 'merged-when-build-succeeds']} + }, gitlab.ProjectMilestone: {'issues': {'required': ['id', 'project-id']}}, gitlab.Project: {'search': {'required': ['query']}, 'owned': {}, @@ -217,6 +223,18 @@ class GitlabCLI(object): except Exception as e: _die("Impossible to retry project build (%s)" % str(e)) + def do_project_merge_request_merge(self, cls, gl, what, args): + try: + o = self.do_get(cls, gl, what, args) + should_remove = args['should_remove_source_branch'] + build_succeeds = args['merged_when_build_succeeds'] + return o.merge( + merge_commit_message=args['merge_commit_message'], + should_remove_source_branch=should_remove, + merged_when_build_succeeds=build_succeeds) + except Exception as e: + _die("Impossible to validate merge request (%s)" % str(e)) + def do_project_milestone_issues(self, cls, gl, what, args): try: o = self.do_get(cls, gl, what, args) @@ -298,6 +316,8 @@ def _populate_sub_parser_by_class(cls, sub_parser): d = EXTRA_ACTIONS[cls][action_name] [sub_parser_action.add_argument("--%s" % arg, required=True) for arg in d.get('required', [])] + [sub_parser_action.add_argument("--%s" % arg, required=False) + for arg in d.get('optional', [])] def _build_parser(args=sys.argv[1:]): diff --git a/gitlab/exceptions.py b/gitlab/exceptions.py index 1b5ec6a..ce1f680 100644 --- a/gitlab/exceptions.py +++ b/gitlab/exceptions.py @@ -91,6 +91,18 @@ class GitlabUnblockError(GitlabOperationError): pass +class GitlabMRForbiddenError(GitlabOperationError): + pass + + +class GitlabMRClosedError(GitlabOperationError): + pass + + +class GitlabMROnBuildSuccessError(GitlabOperationError): + pass + + def raise_error_from_response(response, error, expected_code=200): """Tries to parse gitlab error message from response and raises error. @@ -99,7 +111,8 @@ def raise_error_from_response(response, error, expected_code=200): If response status code is 401, raises instead GitlabAuthenticationError. response: requests response object - error: Error-class to raise. Should be inherited from GitLabError + error: Error-class or dict {return-code => class} of possible error class + to raise. Should be inherited from GitLabError """ if expected_code == response.status_code: @@ -110,8 +123,11 @@ def raise_error_from_response(response, error, expected_code=200): except (KeyError, ValueError): message = response.content - if response.status_code == 401: - error = GitlabAuthenticationError + if isinstance(error, dict): + error = error.get(response.status_code, GitlabOperationError) + else: + if response.status_code == 401: + error = GitlabAuthenticationError raise error(error_message=message, response_code=response.status_code, diff --git a/gitlab/objects.py b/gitlab/objects.py index c5a47a0..3b8a467 100644 --- a/gitlab/objects.py +++ b/gitlab/objects.py @@ -1085,6 +1085,43 @@ class ProjectMergeRequest(GitlabObject): self.gitlab, id, project_id=self.project_id, merge_request_id=self.id, **kwargs) + def merge(self, merge_commit_message=None, + should_remove_source_branch=False, + merged_when_build_succeeds=False, + **kwargs): + """Accept the merge request. + + Args: + merge_commit_message (bool): Commit message + should_remove_source_branch (bool): If True, removes the source + branch + merged_when_build_succeeds (bool): Wait for the build to succeed, + then merge + + Returns: + ProjectMergeRequet: The updated MR + Raises: + GitlabConnectionError: If the server cannot be reached. + GitlabMRForbiddenError: If the user doesn't have permission to + close thr MR + GitlabMRClosedError: If the MR is already closed + """ + url = '/projects/%s/merge_requests/%s/merge' % (self.project_id, + self.id) + data = {} + if merge_commit_message: + data['merge_commit_message'] = merge_commit_message + if should_remove_source_branch: + data['should_remove_source_branch'] = 'should_remove_source_branch' + if merged_when_build_succeeds: + data['merged_when_build_succeeds'] = 'merged_when_build_succeeds' + + r = self.gitlab._raw_put(url, data=data, **kwargs) + errors = {401: GitlabMRForbiddenError, + 405: GitlabMRClosedError} + raise_error_from_response(r, errors) + return ProjectMergeRequest(self, r.json()) + class ProjectMergeRequestManager(BaseManager): obj_cls = ProjectMergeRequest |