mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 19:11:25 +01:00
fix: send a team's permission before its units (Gitea 28), hidden private-org team reviews, long non-ASCII repo descriptions, -R NAME vs directory guard, flake fallback
Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
12 files changed
+150
-8
No files matched your search
@@ -11,6 +11,7 @@ import (
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"gitea.dev/tea/internal/clierr"
|
||||
"gitea.dev/tea/internal/services"
|
||||
@@ -209,8 +210,8 @@ func validateCreateFlags(cmd *cobra.Command, opts services.RepositoryOptions, or
|
||||
return clierr.Wrap(clierr.Usage, errors.New("--team requires --org and a team name"))
|
||||
case changed("template") && template == "":
|
||||
return clierr.Wrap(clierr.Usage, errors.New("--template requires owner/repo or a repository URL"))
|
||||
case len(opts.Description) > 2048:
|
||||
return clierr.Wrap(clierr.Usage, errors.New("description cannot exceed 2048 bytes"))
|
||||
case utf8.RuneCountInString(opts.Description) > 2048:
|
||||
return clierr.Wrap(clierr.Usage, errors.New("description cannot exceed 2048 characters"))
|
||||
case template == "" && (opts.Gitignores != "" || opts.License != "" || opts.Readme != "" || opts.DefaultBranch != "") && !opts.AutoInit:
|
||||
return clierr.Wrap(clierr.Usage, errors.New("initial content and default branch options require --auto-init"))
|
||||
case template != "" && changed("auto-init", "label-template", "gitignores", "license", "readme", "as-template", "trust-model", "object-format"):
|
||||
|
||||
@@ -9,6 +9,8 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -102,6 +104,10 @@ func (a *application) resolveRequest(ctx context.Context, req targetRequest) (ta
|
||||
}
|
||||
// A bare repository NAME belongs to the account tea acts as, which is known only now.
|
||||
if t.Repo != "" && !strings.Contains(t.Repo, "/") {
|
||||
// A name that is also a directory here may be meant as that checkout, as in tea -R ./project.
|
||||
if info, statErr := os.Stat(filepath.Join(cmp.Or(a.options.cwd, "."), t.Repo)); statErr == nil && info.IsDir() && t.RepoSource == "--repo" {
|
||||
return t, clierr.Wrap(clierr.Usage, fmt.Errorf("%q is both a repository name and a directory here; use OWNER/%s for the repository, or --cwd %s for that checkout", t.Repo, t.Repo, t.Repo))
|
||||
}
|
||||
owner := cmp.Or(a.options.sudo, t.User)
|
||||
if owner == "" {
|
||||
return t, clierr.Wrap(clierr.Usage, fmt.Errorf("cannot tell who owns repository %q; use OWNER/%s", t.Repo, t.Repo))
|
||||
|
||||
@@ -376,3 +376,21 @@ func TestEnvironmentCredentialOverridesTheActiveAccount(t *testing.T) {
|
||||
require.NoError(t, Execute(context.Background(), deps, []string{"issue", "create", "-R", "alice/project", "--title", "Issue", "--body", "Body", "--no-input", "--json"}))
|
||||
require.True(t, created)
|
||||
}
|
||||
|
||||
func TestRepositoryFlagNamedLikeADirectoryIsAmbiguous(t *testing.T) {
|
||||
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = w.Write([]byte(`{"full_name":"` + strings.TrimPrefix(r.URL.Path, "/api/v1/repos/") + `"}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
dir := t.TempDir()
|
||||
require.NoError(t, os.Mkdir(filepath.Join(dir, "project"), 0o755))
|
||||
deps, out, _ := testDeps(t)
|
||||
configureAccounts(t, deps, server.URL, "alice", "alice")
|
||||
err := Execute(context.Background(), deps, []string{"repo", "view", "-R", "project", "--cwd", dir, "--no-input", "--json=full_name"})
|
||||
require.Equal(t, clierr.Usage, clierr.ExitCode(err))
|
||||
require.ErrorContains(t, err, `"project" is both a repository name and a directory here; use OWNER/project`)
|
||||
// A qualified name, or a bare name without such a directory, is unambiguous.
|
||||
require.NoError(t, Execute(context.Background(), deps, []string{"repo", "view", "-R", "alice/project", "--cwd", dir, "--no-input", "--json=full_name"}))
|
||||
require.NoError(t, Execute(context.Background(), deps, []string{"repo", "view", "-R", "other", "--cwd", dir, "--no-input", "--json=full_name"}))
|
||||
require.Contains(t, out.String(), "alice/other")
|
||||
}
|
||||
@@ -216,12 +216,14 @@ func TestTeamPermissionSetsEveryUnit(t *testing.T) {
|
||||
}
|
||||
require.NoError(t, Execute(context.Background(), deps, []string{"team", "create", "acme/devs", "--permission", "write"}))
|
||||
require.NoError(t, Execute(context.Background(), deps, []string{"team", "edit", "5", "--permission", "read", "--unit", "repo.wiki=write"}))
|
||||
require.Len(t, sent, 2)
|
||||
require.Len(t, sent, 3)
|
||||
require.Equal(t, "devs", sent[0]["name"])
|
||||
require.Equal(t, every("write"), sent[0]["units_map"])
|
||||
// The permission goes first on its own, because Gitea 28 keeps an admin team admin otherwise.
|
||||
require.Equal(t, map[string]any{"name": "devs", "permission": "read"}, sent[1])
|
||||
wikiWrite := every("read")
|
||||
wikiWrite["repo.wiki"] = "write"
|
||||
require.Equal(t, map[string]any{"permission": "read", "units_map": wikiWrite}, sent[1])
|
||||
require.Equal(t, map[string]any{"permission": "read", "units_map": wikiWrite}, sent[2])
|
||||
}
|
||||
|
||||
func TestTeamMemberRemoveConfirmsOnce(t *testing.T) {
|
||||
|
||||
Reference in new issue
Block a user