Centralize Go validation and build environments

This commit is contained in:
2026-10-06 16:38:15 +00:00
parent 12e866a94a
commit 08093124af
15 changed files with 637 additions and 129 deletions

View File

@@ -9,16 +9,18 @@ import (
"os"
"os/exec"
"sort"
"strings"
)
// Invocation describes one child process. Environment values overlay the
// current process environment for this child only.
// Invocation describes one child process. UnsetEnv removes inherited values
// before Env overlays values for this child only.
type Invocation struct {
Args []string
Dir string
Env map[string]string
Stdout io.Writer
Stderr io.Writer
Args []string
Dir string
Env map[string]string
UnsetEnv []string
Stdout io.Writer
Stderr io.Writer
}
// Run starts the command in the requested directory and waits for it to exit.
@@ -30,8 +32,8 @@ func Run(ctx context.Context, invocation Invocation) error {
command := exec.CommandContext(ctx, invocation.Args[0], invocation.Args[1:]...)
command.Dir = invocation.Dir
if len(invocation.Env) != 0 {
command.Env = append(os.Environ(), environmentEntries(invocation.Env)...)
if len(invocation.Env) != 0 || len(invocation.UnsetEnv) != 0 {
command.Env = environmentEntries(invocation.Env, invocation.UnsetEnv)
}
command.Stdout = invocation.Stdout
command.Stderr = invocation.Stderr
@@ -45,7 +47,21 @@ func Run(ctx context.Context, invocation Invocation) error {
return nil
}
func environmentEntries(environment map[string]string) []string {
func environmentEntries(overlay map[string]string, unset []string) []string {
environment := make(map[string]string, len(os.Environ())+len(overlay))
for _, entry := range os.Environ() {
key, value, ok := strings.Cut(entry, "=")
if ok {
environment[key] = value
}
}
for _, key := range unset {
delete(environment, key)
}
for key, value := range overlay {
environment[key] = value
}
keys := make([]string, 0, len(environment))
for key := range environment {
keys = append(keys, key)