mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 19:11:25 +01:00
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>
59 lines
1.4 KiB
Go
59 lines
1.4 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package transport
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
)
|
|
|
|
type debugTransport struct {
|
|
base http.RoundTripper
|
|
out io.Writer
|
|
}
|
|
|
|
func (t debugTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
|
start := time.Now()
|
|
resp, err := t.base.RoundTrip(req)
|
|
var outcome string
|
|
if err != nil {
|
|
outcome = "error: " + err.Error()
|
|
} else {
|
|
outcome = resp.Status
|
|
}
|
|
_, _ = fmt.Fprintf(t.out, "[debug] %s %s -> %s (%s)\n", req.Method, redactURL(req.URL), outcome, time.Since(start).Round(time.Millisecond))
|
|
return resp, err
|
|
}
|
|
|
|
// redactURL drops userinfo and query values, which can carry tokens or signatures.
|
|
func redactURL(u *url.URL) string {
|
|
clean := *u
|
|
clean.User = nil
|
|
if clean.RawQuery != "" {
|
|
query := clean.Query()
|
|
for key := range query {
|
|
query[key] = []string{"REDACTED"}
|
|
}
|
|
clean.RawQuery = query.Encode()
|
|
}
|
|
return clean.String()
|
|
}
|
|
|
|
// Debug returns a copy of c that logs the method, redacted URL, status, and duration of each
|
|
// request to w. Headers and bodies are never logged.
|
|
func (c *Client) Debug(w io.Writer) *Client {
|
|
clone := *c
|
|
httpClient := *c.HTTP
|
|
base := httpClient.Transport
|
|
if base == nil {
|
|
base = http.DefaultTransport
|
|
}
|
|
httpClient.Transport = debugTransport{base: base, out: w}
|
|
clone.HTTP = &httpClient
|
|
return &clone
|
|
}
|