diff options
-rw-r--r-- | docs/gl_objects/projects.rst | 4 | ||||
-rw-r--r-- | gitlab/exceptions.py | 4 | ||||
-rw-r--r-- | gitlab/v4/objects/projects.py | 15 | ||||
-rw-r--r-- | tests/unit/objects/test_projects.py | 17 |
4 files changed, 40 insertions, 0 deletions
diff --git a/docs/gl_objects/projects.rst b/docs/gl_objects/projects.rst index 88a63aa..775908c 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 4a2f1dc..9ee64e3 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 96d802b..a90bffb 100644 --- a/gitlab/v4/objects/projects.py +++ b/gitlab/v4/objects/projects.py @@ -477,6 +477,21 @@ class Project(RefreshMixin, SaveMixin, ObjectDeleteMixin, RepositoryMixin, RESTO 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 85bae86..6134382 100644 --- a/tests/unit/objects/test_projects.py +++ b/tests/unit/objects/test_projects.py @@ -505,6 +505,19 @@ def resp_delete_push_rules_project(no_content): @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: rsps.add( @@ -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) |