goenv

package
v1.2.11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package goenv builds the environment a tool hands to a child `go` command.

A tool that runs `go test`, `go build`, `go vet` or `go list` for its own purposes reads the child's output: nova-review mutate counts the `--- PASS:` and `--- FAIL:` lines of an inner `go test`, nova-merge simulate quotes a check's first line. The environment the tool was started in can reshape that output under the parser's feet, and then the tool reports something that never happened.

That is not hypothetical. CI's `make test` exports GOFLAGS=-json. On a CI run, the inner `go test` inherits GOFLAGS=-json, so its output comes back as a JSON stream with no `--- PASS:` line in it, and the parser counted the run that stayed green as red: `MUTATE <sha> red=1 green=1 PASS` became `red=2 green=0`, and three legs of integration-4 failed on a tool that was working perfectly.

Clean is the one answer for the whole class: the parent's environment minus everything that can change the shape of a go command's output, and minus every variable whose NAME carries a credential. The first half is the output-shape filter above. The second is the same class one step further: simulate, batch and review mutate run a check -- code from the tree under test -- through a child, and a GH_TOKEN or any other secret-named variable the caller holds must not reach a process whose code came from a pull request. The value is never read: the drop is by NAME, so a finding, a log and a diff can all be read without one. A tool that needs a variable of its own appends it AFTER Clean, where the last value wins.

cmd := exec.CommandContext(ctx, "go", args...)
cmd.Env = append(goenv.Clean(os.Environ()), "GOTMPDIR="+scratch)

internal/ci enforces this: every exec.Command whose argv[0] is "go" outside this package must build its environment from Clean.

Index

Constants

View Source
const Removed = "" /* 136-byte string literal not displayed */

Removed is the documented list of what Clean drops, and the only list. It is read by people, not by code -- the rules below are the implementation -- so that a reader can see the whole set without reading the matcher.

GOFLAGS      flags the go command prepends to EVERY invocation. -json turns
             `go test` and `go build` into a JSON stream, -count and -race
             change what a run means, and -mod can make a build refuse.
GOTEST*      GOTESTFLAGS, GOTESTSUM_FORMAT and anything else a harness
             exports to steer a test run: not the go command's own, but
             read by the wrappers CI puts around it.
GO*=...-json any other GO-prefixed variable carrying a -json or --json
             flag, which is the shape of this bug wherever it turns up next.
*KEY* *TOKEN* an environment NAME carrying a credential -- a forge token
*SECRET*     (GH_TOKEN, GITHUB_TOKEN), a provider key (DEEPSEEK_API_KEY), a
*PASSWORD*   database password (PGPASSWORD, NOVA_PG_PASSWORD,
*PASSWD*     NOVA_REDIS_PASSWORD) or any other secret a caller holds. The
             matcher reads the name and never the value, so nothing has to
             see a secret to drop it, and a child running a pull request's
             code cannot read one.

GOTMPDIR is deliberately NOT dropped: it names a location, not an output shape, and a bench that sets it usually has a reason (a small /tmp). A tool that wants its own scratch appends GOTMPDIR= after Clean.

Variables

This section is empty.

Functions

func Clean

func Clean(env []string) []string

Clean returns a copy of env with the variables named in Removed taken out. The order of what remains is preserved, and env itself is not modified: the caller keeps its own os.Environ().

func WithoutSecrets

func WithoutSecrets(env []string) []string

WithoutSecrets returns a copy of env with every variable whose NAME carries KEY, TOKEN, SECRET, PASSWORD or PASSWD taken out. It is not the output-shape rule Clean is: Clean keeps the child `go` command's answers comparable, and this one keeps a program the gate did not write from reading the seat's credentials. The predicate is keyshape.SecretName, the same one Clean's credential case and the job shell's shim and the harvest's argv log redact by, so there is one definition of a secret name.

A gate runs a card's tree -- its git filters and its tests -- and the process it was started in already holds the provider key, GH_TOKEN, the database passwords and the rest. The value is never read, printed or copied: the name is what decides, and a variable that does not carry one is left alone.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL