From 0fd9058b752400de33ca10c801c4c237cc364726 Mon Sep 17 00:00:00 2001 From: Nejc Habjan Date: Sat, 23 Jul 2022 18:16:24 +0200 Subject: [PATCH] feat(projects): add support for project restore API --- docs/gl_objects/projects.rst | 4 ++++ gitlab/exceptions.py | 4 ++++ gitlab/v4/objects/projects.py | 15 +++++++++++++++ tests/unit/objects/test_projects.py | 17 +++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/docs/gl_objects/projects.rst b/docs/gl_objects/projects.rst index 88a63aa87..775908cfb 100644 --- a/docs/gl_objects/projects.rst +++ b/docs/gl_objects/projects.rst @@ -115,6 +115,10 @@ Delete a project:: # or project.delete() +Restore a project marked for deletion (Premium only):: + + project.restore() + Fork a project:: fork = project.forks.create({}) diff --git a/gitlab/exceptions.py b/gitlab/exceptions.py index 4a2f1dc6d..9ee64e33c 100644 --- a/gitlab/exceptions.py +++ b/gitlab/exceptions.py @@ -286,6 +286,10 @@ class GitlabRepairError(GitlabOperationError): pass +class GitlabRestoreError(GitlabOperationError): + pass + + class GitlabRevertError(GitlabOperationError): pass diff --git a/gitlab/v4/objects/projects.py b/gitlab/v4/objects/projects.py index 96d802bb0..a90bffbe8 100644 --- a/gitlab/v4/objects/projects.py +++ b/gitlab/v4/objects/projects.py @@ -477,6 +477,21 @@ def upload( assert isinstance(data, dict) return {"alt": data["alt"], "url": data["url"], "markdown": data["markdown"]} + @cli.register_custom_action("Project") + @exc.on_http_error(exc.GitlabRestoreError) + def restore(self, **kwargs: Any) -> None: + """Restore a project marked for deletion. + + Args: + **kwargs: Extra options to send to the server (e.g. sudo) + + Raises: + GitlabAuthenticationError: If authentication is not correct + GitlabRestoreError: If the server failed to perform the request + """ + path = f"/projects/{self.encoded_id}/restore" + self.manager.gitlab.http_post(path, **kwargs) + @cli.register_custom_action("Project", optional=("wiki",)) @exc.on_http_error(exc.GitlabGetError) def snapshot( diff --git a/tests/unit/objects/test_projects.py b/tests/unit/objects/test_projects.py index 85bae8600..6134382f8 100644 --- a/tests/unit/objects/test_projects.py +++ b/tests/unit/objects/test_projects.py @@ -504,6 +504,19 @@ def resp_delete_push_rules_project(no_content): yield rsps +@pytest.fixture +def resp_restore_project(created_content): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/restore", + json=created_content, + content_type="application/json", + status=201, + ) + yield rsps + + @pytest.fixture def resp_start_pull_mirroring_project(): with responses.RequestsMock() as rsps: @@ -753,6 +766,10 @@ def test_project_pull_mirror(project, resp_start_pull_mirroring_project): project.mirror_pull() +def test_project_restore(project, resp_restore_project): + project.restore() + + def test_project_snapshot(project, resp_snapshot_project): tar_file = project.snapshot() assert isinstance(tar_file, bytes)