Documentation
¶
Overview ¶
Package forgedelegate finds, and if need be builds, the forge a project pins, so a forge of another version can hand a command to it.
WHY. forge's templates, KCL schemas and analyzers ship inside the binary, so a command run by the wrong forge rewrites a project with the wrong output or fails with errors that blame the project. The forge on PATH is routinely not the project's: a Reliant workspace bundles one at image-build time, and every project pins its own. Refusing and printing a `go run …@<pin>` line made the version skew a wall that every agent climbed by hand. Delegating removes it: the project says which forge it is, and that forge runs.
WHERE THE PINNED FORGE COMES FROM, cheapest first:
- the project's own .tools/bin/forge, when it reports the pinned version (`task tools` / scripts/install-tools.sh installs it there);
- the content-addressed cache, <user cache>/forge/pinned/<version>/… A pseudo-version names one commit, so an entry never goes stale;
- a build: `go install github.com/reliant-labs/forge/cmd/forge@<version>` into a temp dir that is renamed into the cache, so a build that dies never leaves a half-written binary where step 2 would trust it.
A project whose go.mod or go.work points forge at a local checkout (the dev link) is a different case: the forge it runs is that checkout, built where it stands (Bridge).
This package only resolves and executes. Whether to delegate is the caller's decision (internal/cli/forge_pin_delegate.go).
Index ¶
Constants ¶
const CacheDirEnv = "FORGE_PINNED_CACHE"
CacheDirEnv relocates the builds the resolver keeps (default <user cache dir>/forge/pinned), for read-only home directories and test isolation.
const MarkerEnv = "FORGE_VERSION_DELEGATED"
MarkerEnv is set in the environment of a forge that was delegated to. It ends the hand-off: the parent has already decided this is the right forge, and a child that second-guessed it (its own version string can differ in spelling from the pin) would delegate again, forever.
Variables ¶
This section is empty.
Functions ¶
func Delegated ¶
func Delegated() bool
Delegated reports whether this process was started by a delegation.
func Env ¶
func Env() []string
Env is the environment to give the delegated forge: ours, plus the marker.
Types ¶
type Resolver ¶
type Resolver struct {
// Log receives the notice that a build is starting (a minute of silence
// reads as a hang).
Log io.Writer
// Version runs a forge binary and returns the version it reports.
Version func(ctx context.Context, path string) (string, error)
// Same reports whether version got is the forge want names.
Same func(want, got string) bool
// Install runs `go install pkg` with GOBIN=gobin.
Install func(ctx context.Context, pkg, gobin string) error
// Build runs `go build` of cmd/forge in checkout dir, writing out.
Build func(ctx context.Context, dir, out string) error
}
Resolver finds or builds forge binaries. The zero value is usable; the func fields are seams for tests and default to the real thing.
func (*Resolver) Bridge ¶
Bridge returns a forge built from the checkout at dir, the forge a project bridged to it (go.work `use`, or a directory `replace`) compiles against. stamp must change whenever the checkout's contents do (HEAD plus its uncommitted edits), so an unchanged checkout is built once. The build's own settings join the key (buildSettingsKey): two callers whose GOFLAGS differ (one with -trimpath, one without) build different bytes from the same checkout, and must not share — or replace — one cached binary.
func (*Resolver) LocalPinned ¶
LocalPinned reports the project's own .tools/bin/forge when it exists and reports the pinned version. It runs the binary (`forge version`), never builds anything.