26f897c1ec
release / release-please (push) Failing after 1m49s
docs / build (push) Failing after 6m34s
release / build-and-upload (arm64, linux) (push) Has been cancelled
release / build-and-upload (arm64, windows) (push) Has been cancelled
release / build-darwin (amd64, darwin) (push) Has been cancelled
release / checksums (push) Has been cancelled
release / finalize (push) Has been cancelled
release / build-darwin (arm64, darwin) (push) Has been cancelled
release / build-and-upload (amd64, linux) (push) Has been cancelled
release / build-and-upload (amd64, windows) (push) Has been cancelled
docs / deploy (push) Has been cancelled
123 lines
3.4 KiB
Go
123 lines
3.4 KiB
Go
package git
|
|
|
|
import (
|
|
"os"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// resolveEnv collapses a KEY=VALUE slice into a map using last-wins semantics,
|
|
// matching how exec resolves duplicate keys.
|
|
func resolveEnv(env []string) map[string]string {
|
|
m := make(map[string]string, len(env))
|
|
for _, kv := range env {
|
|
k, v, ok := strings.Cut(kv, "=")
|
|
if !ok {
|
|
continue
|
|
}
|
|
m[k] = v
|
|
}
|
|
return m
|
|
}
|
|
|
|
func TestNonInteractiveEnv_SetsGitOverrides(t *testing.T) {
|
|
got := resolveEnv(NonInteractiveEnv(""))
|
|
|
|
want := map[string]string{
|
|
"GIT_EDITOR": "true",
|
|
"GIT_SEQUENCE_EDITOR": "true",
|
|
"GIT_TERMINAL_PROMPT": "0",
|
|
}
|
|
for k, v := range want {
|
|
if got[k] != v {
|
|
t.Errorf("env %s = %q, want %q", k, got[k], v)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNonInteractiveEnv_OverridesAmbientEditor(t *testing.T) {
|
|
t.Setenv("GIT_EDITOR", "vim")
|
|
t.Setenv("GIT_SEQUENCE_EDITOR", "nano")
|
|
t.Setenv("GIT_TERMINAL_PROMPT", "1")
|
|
|
|
got := resolveEnv(NonInteractiveEnv(""))
|
|
|
|
if got["GIT_EDITOR"] != "true" {
|
|
t.Errorf("GIT_EDITOR = %q, want \"true\" (ambient vim must be overridden)", got["GIT_EDITOR"])
|
|
}
|
|
if got["GIT_SEQUENCE_EDITOR"] != "true" {
|
|
t.Errorf("GIT_SEQUENCE_EDITOR = %q, want \"true\"", got["GIT_SEQUENCE_EDITOR"])
|
|
}
|
|
if got["GIT_TERMINAL_PROMPT"] != "0" {
|
|
t.Errorf("GIT_TERMINAL_PROMPT = %q, want \"0\"", got["GIT_TERMINAL_PROMPT"])
|
|
}
|
|
}
|
|
|
|
func TestNonInteractiveEnv_PreservesAmbientEnv(t *testing.T) {
|
|
t.Setenv("NM_ENV_PROBE_XYZ", "kept")
|
|
|
|
got := resolveEnv(NonInteractiveEnv(""))
|
|
|
|
if got["NM_ENV_PROBE_XYZ"] != "kept" {
|
|
t.Errorf("ambient env not preserved: NM_ENV_PROBE_XYZ = %q, want \"kept\"", got["NM_ENV_PROBE_XYZ"])
|
|
}
|
|
}
|
|
|
|
// TestNonInteractiveEnv_SetsPWDToDir locks in the PWD coupling. Assigning
|
|
// cmd.Env disables os/exec's automatic PWD=Cmd.Dir injection, so the helper
|
|
// must restore it; otherwise os.Getwd in the child resolves symlinks (e.g.
|
|
// /tmp -> /private/tmp on macOS) and reports a different working directory.
|
|
func TestNonInteractiveEnv_SetsPWDToDir(t *testing.T) {
|
|
t.Setenv("PWD", "/somewhere/else")
|
|
|
|
got := resolveEnv(NonInteractiveEnv("/work/dir"))
|
|
|
|
if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
|
|
if got["PWD"] != "/somewhere/else" {
|
|
t.Errorf("PWD = %q, want ambient PWD on %s", got["PWD"], runtime.GOOS)
|
|
}
|
|
return
|
|
}
|
|
|
|
if got["PWD"] != "/work/dir" {
|
|
t.Errorf("PWD = %q, want \"/work/dir\"", got["PWD"])
|
|
}
|
|
}
|
|
|
|
// TestNonInteractiveEnv_AbsolutizesRelativeDir locks in that a relative dir is
|
|
// absolutized before injection, matching os/exec (go.dev/issue/50599). POSIX
|
|
// defines PWD as an absolute pathname; a relative value like "." propagates
|
|
// through git receive-pack into hooks, where macOS /bin/sh (bash 3.2) trusts
|
|
// it and `pwd` collapses to "." (issue #269).
|
|
func TestNonInteractiveEnv_AbsolutizesRelativeDir(t *testing.T) {
|
|
t.Setenv("PWD", "/somewhere/else")
|
|
|
|
got := resolveEnv(NonInteractiveEnv("."))
|
|
|
|
if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
|
|
if got["PWD"] != "/somewhere/else" {
|
|
t.Errorf("PWD = %q, want ambient PWD on %s", got["PWD"], runtime.GOOS)
|
|
}
|
|
return
|
|
}
|
|
|
|
wd, err := os.Getwd()
|
|
if err != nil {
|
|
t.Fatalf("Getwd: %v", err)
|
|
}
|
|
if got["PWD"] != wd {
|
|
t.Errorf("PWD = %q, want absolute %q for relative dir \".\"", got["PWD"], wd)
|
|
}
|
|
}
|
|
|
|
func TestNonInteractiveEnv_EmptyDirLeavesAmbientPWD(t *testing.T) {
|
|
t.Setenv("PWD", "/ambient/pwd")
|
|
|
|
got := resolveEnv(NonInteractiveEnv(""))
|
|
|
|
if got["PWD"] != "/ambient/pwd" {
|
|
t.Errorf("PWD = %q, want ambient \"/ambient/pwd\" when dir is empty", got["PWD"])
|
|
}
|
|
}
|