mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 19:11:25 +01:00
feat(repo): add repo unarchive and repo rename, and report archive and delete
repo unarchive restores an archived repository, and repo rename renames one, moving the Git remote or the saved default repository that selected it to the new name. The archived-repository hint now points to tea repo unarchive. repo archive asks "Archive alice/x? It becomes read-only." and warns "! alice/x is already archived" without a request when there is nothing to do. Archive, unarchive, rename and delete confirm with a ✓ line on a terminal, and --json returns the repository. Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
6 files changed
+327
-46
No files matched your search
@@ -5,6 +5,7 @@ package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
@@ -72,3 +73,100 @@ func TestRepoDeleteAsksToTypeTheRepositoryName(t *testing.T) {
|
||||
require.Equal(t, []string{"DELETE /api/v1/repos/alice/project"}, requests)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepoArchiveStates(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
args []string
|
||||
archived bool
|
||||
requests []string
|
||||
feedback string
|
||||
}{
|
||||
{"archive", []string{"repo", "archive", "alice/x", "--yes"}, false, []string{"GET", "PATCH"}, "✓ Archived repository alice/x\n"},
|
||||
{"already archived", []string{"repo", "archive", "alice/x", "--yes"}, true, []string{"GET"}, "! alice/x is already archived\n"},
|
||||
{"unarchive", []string{"repo", "unarchive", "alice/x"}, true, []string{"GET", "PATCH"}, "✓ Unarchived repository alice/x\n"},
|
||||
{"not archived", []string{"repo", "unarchive", "alice/x"}, false, []string{"GET"}, "! alice/x is not archived\n"},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
var requests []string
|
||||
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, "/api/v1/repos/alice/x", r.URL.Path)
|
||||
requests = append(requests, r.Method)
|
||||
archived := test.archived
|
||||
if r.Method == http.MethodPatch {
|
||||
requirePayload(t, fmt.Sprintf(`{"archived":%t}`, !archived), r.Body)
|
||||
archived = !archived
|
||||
}
|
||||
_, _ = fmt.Fprintf(w, `{"full_name":"alice/x","archived":%t}`, archived)
|
||||
}))
|
||||
defer server.Close()
|
||||
deps, out, diagnostics := repoTTYDeps(t, server.URL)
|
||||
require.NoError(t, Execute(context.Background(), deps, test.args))
|
||||
require.Equal(t, test.requests, requests)
|
||||
require.Empty(t, out.String())
|
||||
require.Equal(t, test.feedback, diagnostics.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepoArchiveAsksWithTheConsequence(t *testing.T) {
|
||||
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodGet, r.Method)
|
||||
_, _ = w.Write([]byte(`{"full_name":"alice/project"}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
deps, _, _ := serverDeps(t, server.URL)
|
||||
deps.Git = upstreamCheckout(server)
|
||||
prompt := &scriptedPrompter{}
|
||||
deps.Prompter, deps.Streams.InTTY, deps.Streams.ErrTTY = prompt, true, true
|
||||
err := Execute(context.Background(), deps, []string{"repo", "archive"})
|
||||
require.Equal(t, clierr.Canceled, clierr.ExitCode(err), "%v", err)
|
||||
require.Equal(t, []string{"Archive alice/project (from git remote upstream)? It becomes read-only."}, prompt.confirmations)
|
||||
}
|
||||
|
||||
func TestRepoRenameFollowsTheRemote(t *testing.T) {
|
||||
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodPatch+" /api/v1/repos/alice/project", r.Method+" "+r.URL.Path)
|
||||
requirePayload(t, `{"name":"renamed"}`, r.Body)
|
||||
_, _ = w.Write([]byte(`{"name":"renamed","full_name":"alice/renamed"}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
deps, out, diagnostics := repoTTYDeps(t, server.URL)
|
||||
runner := &fakeGit{results: map[string]string{
|
||||
"symbolic-ref --short HEAD": "main",
|
||||
"config --get branch.main.remote": "origin",
|
||||
"remote get-url origin": server.URL + "/alice/project.git",
|
||||
"remote set-url origin " + server.URL + "/alice/renamed.git": "",
|
||||
}}
|
||||
deps.Git = runner
|
||||
require.NoError(t, Execute(context.Background(), deps, []string{"repo", "rename", "renamed", "--yes"}))
|
||||
require.Contains(t, runner.calls, "remote set-url origin "+server.URL+"/alice/renamed.git")
|
||||
require.Empty(t, out.String())
|
||||
require.Equal(t, "✓ Renamed repository alice/project to alice/renamed\n✓ Updated Git remote origin to alice/renamed\n", diagnostics.String())
|
||||
}
|
||||
|
||||
func TestRenamedURL(t *testing.T) {
|
||||
for _, test := range []struct{ raw, want string }{
|
||||
{"https://gitea.test/alice/project.git", "https://gitea.test/alice/renamed.git"},
|
||||
{"https://gitea.test/alice/project/", "https://gitea.test/alice/renamed"},
|
||||
{"git@gitea-alias:alice/Project.git", "git@gitea-alias:alice/renamed.git"},
|
||||
{"ssh://git@gitea.test:2222/alice/project", "ssh://git@gitea.test:2222/alice/renamed"},
|
||||
{"https://gitea.test/alice/subproject.git", ""},
|
||||
} {
|
||||
renamed, ok := renamedURL(test.raw, "project", "renamed")
|
||||
require.Equal(t, test.want != "", ok, test.raw)
|
||||
require.Equal(t, test.want, renamed, test.raw)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepoDeleteReportsTheDeletion(t *testing.T) {
|
||||
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodDelete+" /api/v1/repos/alice/x", r.Method+" "+r.URL.Path)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}))
|
||||
defer server.Close()
|
||||
deps, out, diagnostics := repoTTYDeps(t, server.URL)
|
||||
require.NoError(t, Execute(context.Background(), deps, []string{"repo", "rm", "alice/x", "--yes"}))
|
||||
require.Empty(t, out.String())
|
||||
require.Equal(t, "✓ Deleted repository alice/x\n", diagnostics.String())
|
||||
}
|
||||
Reference in new issue
Block a user