mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 11:01:25 +01:00
refactor: add settings, transport and alias packages (#1122)
Part 1/5 of the tea 1.0 rewrite. **Stack** (split from #1121; each PR targets `main` and builds, tests and lints on its own — the shipped CLI only changes in part 5): 1. #1122 Toolchain and foundation packages ← this PR 2. #1123 Credentials and Git 3. #1124 Terminal 4. #1125 Services 5. #1126 CLI wiring, docs, removal of the old tree ## Changes - **build:** require Go 1.27; bump gofumpt and golangci-lint to releases that can read Go 1.27 export data (own commit). - `internal/clierr`: typed errors and executable exit codes. - `internal/version`: build version and tags. - `internal/filelock`: moved unchanged from `modules/filelock`. - `internal/aliases`: user-defined command aliases. - `internal/transport`: the HTTP client the Gitea SDK runs on (part 4): token, Sudo and SSH-signature auth, retries for safe reads, connect/TLS/response-header timeouts, typed API errors that keep Gitea's message, and a redacted request log for `--debug`; plus raw requests for `tea api`, signed downloads that follow object-storage redirects, and log streaming. - `internal/settings`: split `config.yml` / `hosts.yml` with locked transactions, plus remote URL parsing. Nothing imports these packages yet. Note: `flake.nix` now asks for `go_1_27`; the pinned nixpkgs in `flake.lock` predates Go 1.27 and still needs a `nix flake update nixpkgs`. Reviewed-on: https://gitea.com/gitea/tea/pulls/1122 Reviewed-by: TheFox0x7 <95654+thefox0x7@noreply.gitea.com>
This commit is contained in:
1 parent
bcd62a1fb2
commit
2b218a5bae
29 files changed
+2541
-77
No files matched your search
@@ -0,0 +1,74 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package settings
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRepositoryURL(t *testing.T) {
|
||||
ports := map[string]Host{"https://example.org:3000/base": {}, "https://example.org:3000": {}}
|
||||
bases := map[string]Host{"https://example.org": {}, "https://example.org/base": {}}
|
||||
sshPorts := map[string]Host{
|
||||
"https://example.org/first": {SSHHost: "git.example.org:2222"},
|
||||
"https://example.org/second": {SSHHost: "git.example.org:2223"},
|
||||
}
|
||||
for _, test := range []struct {
|
||||
raw string
|
||||
hosts map[string]Host
|
||||
wantHost, wantRepo string
|
||||
wantErr string
|
||||
}{
|
||||
{raw: "https://example.org:3000/base/alice/project.git", hosts: ports, wantHost: "https://example.org:3000/base", wantRepo: "alice/project"},
|
||||
{raw: "https://unconfigured.example.org/group/alice/project.git", wantHost: "https://unconfigured.example.org/group", wantRepo: "alice/project"},
|
||||
{raw: "ssh://git@git.example.org:2223/alice/project.git", hosts: sshPorts, wantHost: "https://example.org/second", wantRepo: "alice/project"},
|
||||
{raw: "git@git.example.org:alice/project.git", hosts: sshPorts, wantErr: "does not match"},
|
||||
{raw: "git@example.org:owner/repo.git", hosts: bases, wantErr: "multiple instances"},
|
||||
{raw: "https://example.org/alice/project/issues/7", hosts: bases, wantErr: "ambiguous"},
|
||||
{raw: "https://example.org/alice/project/pulls/3", hosts: bases, wantErr: "ambiguous"},
|
||||
{raw: "https://example.org/base/alice/project/src/branch/main", hosts: bases, wantErr: "ambiguous"},
|
||||
{raw: "https://example.org/alice/project/actions/runs/9", hosts: bases, wantErr: "ambiguous"},
|
||||
{raw: "https://unconfigured.example.org/alice/project/issues/7", wantErr: "ambiguous"},
|
||||
{raw: "https://unconfigured.example.org/alice/project/issues", wantErr: "ambiguous"},
|
||||
{raw: "https://unconfigured.example.org/alice/project/pulls", wantErr: "ambiguous"},
|
||||
{raw: "https://unconfigured.example.org/alice/project/src/branch/main", wantErr: "ambiguous"},
|
||||
{raw: "https://unconfigured.example.org/group/alice/issues.git", wantHost: "https://unconfigured.example.org/group", wantRepo: "alice/issues"},
|
||||
{raw: "ssh://git:private-test-password@example.org/alice/project.git", wantErr: "must not embed credentials"},
|
||||
} {
|
||||
host, repo, err := RepositoryURL(test.raw, test.hosts)
|
||||
if test.wantErr != "" {
|
||||
require.ErrorContains(t, err, test.wantErr, test.raw)
|
||||
require.NotContains(t, err.Error(), "private-test-password")
|
||||
continue
|
||||
}
|
||||
require.NoError(t, err, test.raw)
|
||||
require.Equal(t, test.wantHost, host, test.raw)
|
||||
require.Equal(t, test.wantRepo, repo, test.raw)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoteIsSSH(t *testing.T) {
|
||||
for remote, want := range map[string]bool{
|
||||
"ssh://git@example.org/alice/project.git": true,
|
||||
"git@example.org:alice/project.git": true,
|
||||
"https://example.org/alice/project.git": false,
|
||||
"http://example.org/alice/project.git": false,
|
||||
"file:///tmp/repo.git": false,
|
||||
} {
|
||||
require.Equal(t, want, RemoteIsSSH(remote), remote)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseRemoteReadsSCPStyleRemotes(t *testing.T) {
|
||||
u, err := ParseRemote("git@git.example.org:alice/project.git")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "ssh://git@git.example.org/alice/project.git", u.String())
|
||||
}
|
||||
|
||||
func TestValidSlugRejectsSCPStyleRemotes(t *testing.T) {
|
||||
require.True(t, ValidSlug("alice/project"))
|
||||
require.False(t, ValidSlug("git@example.org:alice/project.git"))
|
||||
}
|
||||
Reference in new issue
Block a user