6a82b88947
agentws manages per-branch git worktrees for the unkin-agent user: it clones repos into the source root (~/src/prodenv/<repo>) so branches are visible in Ben's main checkout, and creates isolated worktrees under the worktree root (~/.cache/agentws/<repo>__<branch>). - New internal/agent/git.go: small, testable git helpers shelling out to the git binary (clone/fetch/worktree add/remove/list/prune, branch + config ops, porcelain parsing, path sanitizing). No go-git dependency. - New cmd/agentws: new / list / rm / clean / token / credential subcommands. Auth uses an ephemeral git credential helper (agentws credential get) so the ~1h Gitea token is never persisted in a remote URL or config; per-worktree config keeps the shared checkout's identity untouched. - Wire agentws into Makefile, scripts/build-rpm.sh, packaging/nfpm.yaml (binary + bash/zsh/fish completions), .woodpecker/release.yaml (cross-compile + assets) and .gitignore. - Tests: table tests for parsing/sanitizing/dir-naming, a real temp-git repo for the worktree lifecycle, and hermetic cmd tests (bad input + credential-helper host guard) that never touch the network. - Document agentws in README.md and AGENTS.md.
64 lines
1.8 KiB
Go
64 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// `new` with a bad repo name (contains a slash) must fail before any network
|
|
// call, keeping the test hermetic.
|
|
func TestNewRejectsOwnerQualifiedRepo(t *testing.T) {
|
|
cmd := newRootCmd()
|
|
cmd.SetArgs([]string{"new", "unkin/argocd-apps", "--branch", "benvin/x"})
|
|
cmd.SetOut(io.Discard)
|
|
cmd.SetErr(io.Discard)
|
|
if err := cmd.Execute(); err == nil {
|
|
t.Fatal("Execute() = nil, want error for owner-qualified repo name")
|
|
}
|
|
}
|
|
|
|
// `new` without --branch must fail (cobra required-flag check) before any
|
|
// network call.
|
|
func TestNewRequiresBranch(t *testing.T) {
|
|
cmd := newRootCmd()
|
|
cmd.SetArgs([]string{"new", "argocd-apps"})
|
|
cmd.SetOut(io.Discard)
|
|
cmd.SetErr(io.Discard)
|
|
if err := cmd.Execute(); err == nil {
|
|
t.Fatal("Execute() = nil, want error when --branch is missing")
|
|
}
|
|
}
|
|
|
|
// An unknown credential action must fail.
|
|
func TestCredentialUnknownAction(t *testing.T) {
|
|
cmd := newRootCmd()
|
|
cmd.SetArgs([]string{"credential", "bogus"})
|
|
cmd.SetOut(io.Discard)
|
|
cmd.SetErr(io.Discard)
|
|
if err := cmd.Execute(); err == nil {
|
|
t.Fatal("Execute() = nil, want error for unknown credential action")
|
|
}
|
|
}
|
|
|
|
// credentialGet must stay silent (and never mint a token) when git asks about a
|
|
// host other than the configured Gitea host. This exercises the stdin parser
|
|
// without any network access.
|
|
func TestCredentialGetIgnoresOtherHost(t *testing.T) {
|
|
in := strings.NewReader("protocol=https\nhost=github.com\n\n")
|
|
var out bytes.Buffer
|
|
if err := credentialGet(in, &out); err != nil {
|
|
t.Fatalf("credentialGet: %v", err)
|
|
}
|
|
if out.Len() != 0 {
|
|
t.Errorf("expected no output for non-Gitea host, got %q", out.String())
|
|
}
|
|
}
|
|
|
|
func TestGiteaHost(t *testing.T) {
|
|
if h := giteaHost(); h != "git.unkin.net" {
|
|
t.Errorf("giteaHost() = %q, want git.unkin.net", h)
|
|
}
|
|
}
|