Files
releasekit/docs/internal/gotool.md

5.1 KiB

Go command environments

internal/gotool resolves effective Go settings when an operation first needs a Go command and applies the shared environment to its commands. Candidate validation and its build callback share an operation-local owner while the inherited environment and persistent Go settings file remain unchanged. Standalone and delivery builds create their own owners. The package uses internal/process for cancellation, the working directory, output, and wrapped errors.

Command output ownership

Tool.Run executes a status-only command. It forwards combined stdout and stderr to the optional writer while the child runs, retaining only the last 1,048,576 bytes for failure diagnostics. A truncation notice identifies omitted earlier bytes. Successful calls release their capture; failures preserve the underlying process or forwarding error. Dependency preparation uses the same bounded diagnostic capture.

Tool.Output returns combined stdout and stderr for commands whose output is needed by the caller, such as compiler identification. After the child stops, the capture's backing bytes transfer to the caller without a second copy. A failed output command returns both those bytes and an error containing the diagnostic text. The capture remains in memory for the duration of the child; the component benchmark compares full and bounded capture for modest output, one 8 MiB write, and 8 MiB in 32 KiB writes, forwarding to io.Discard. The output benchmark measures total allocated bytes per operation, excluding subprocess overhead and diagnostic strings. These totals count all allocations, including superseded buffers. The returned slice retains the final buffer holding the complete output. Peak live memory depends on buffer growth, garbage collection, and other command work and is not measured by allocation totals. Failed output also formats diagnostics into the error, so the returned bytes and diagnostic string can coexist. Disk-backed diagnostics could reduce large failure peaks, but add file lifecycle and cleanup work and remain a follow-up option.

Dependency preparation uses a separate command environment so proxy, private module, checksum, cache, and other effective settings remain available. Its go mod download -modfile= command overrides an alternate module file selected through GOFLAGS, preserving ordinary module discovery. Its bounded capture is formatted into the error on failure.

Configuration discovery

The owner asks the installed go command for GOHOSTOS, GOHOSTARCH, and the GOENV settings-file path, then queries effective operational settings with that host selected. Both queries use GOTOOLCHAIN=local and controlled GOFLAGS. Discovery sets GOEXPERIMENT=none and clears architecture feature variables so an invalid or nonbaseline tuning value cannot prevent settings from being read. The experiment override is discovery-only.

The persistent Go environment remains active during discovery. The owner copies the effective cache and module-cache locations, Go root, temporary directory, and native cgo/C-tool configuration into its settings. This captures values supplied by either the process environment or the persistent Go environment file.

The operation-local owner snapshots the inherited environment and selected settings file. It reuses the resolved tool across validation and its following build callback while those inputs match. Subsequent Go acquisition rediscovers settings when a consumer callback changes either input. An unavailable snapshot disables reuse while discovery follows the Go tool's accepted configuration. Ownership is operation-local.

Configuration discovery parses JSON from stdout. Stderr is captured separately and included in command-failure diagnostics, so a successful query can emit warnings while supplying valid configuration.

Command environments

Every Go command receives GOENV=off, so removed persistent values cannot return. ReleaseKit owns GOFLAGS=-mod=readonly, GOWORK=off, GOTOOLCHAIN=local, GOPROXY=off, GONOPROXY=none, and GOSUMDB=off. Native commands use GOHOSTOS and GOHOSTARCH and retain the effective CGO_ENABLED, CC, CXX, PKG_CONFIG, and CGO_CFLAGS, CGO_CPPFLAGS, CGO_CXXFLAGS, and CGO_LDFLAGS. Static commands use the selected target and CGO_ENABLED=0.

Both modes clear GOEXPERIMENT and the Go architecture feature variables GOAMD64, GOARM, GOARM64, GO386, GOMIPS, GOMIPS64, GOPPC64, GORISCV64, and GOWASM. The selected Go toolchain supplies its ordinary baseline values. Effective GOCACHE, GOCACHEPROG, GOMODCACHE, GOPATH, GOROOT, and GOTMPDIR values are retained. Other process variables remain available to child commands.

Candidate validation runs the offline go test suite and selected full go vet pass from the selected module directory using native mode. Package-compilation checks use static mode for each selected target and direct Go's output to the operating system null device, so they leave no binary artifact. Artifact builds also compile selected targets in static mode, then build the native version-check executable, which runs as a normal child process.