Files
ReleaseKit/docs/internal/gotool.md

88 lines
4.7 KiB
Markdown

# 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, then releases its capture
on success. Failures include the captured diagnostic text and preserve the
underlying process or forwarding error.
`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 one 8 MiB write with the same output in
32 KiB writes, forwarding to `io.Discard`. Smaller writes incur buffer-growth
allocations. The [output benchmark](../../internal/gotool/performance_test.go)
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, and cache settings remain available. Its completed capture
uses the same ownership transfer when formatting a 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, and rediscovers after a consumer
callback changes either input. It does not cache settings across operations.
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.