Documentation
¶
Overview ¶
Package build executes a detected target as a subprocess and reports a structured pass/fail Result with captured output — the raw material the UI turns into a build report.
Index ¶
- func EnvUp(ctx context.Context, env []string, e *detect.ComposeEnv, out io.Writer, ...) error
- func PrepareEnv(ctx context.Context, t detect.Target, out io.Writer) ([]string, []string, error)
- func TearDown(ctx context.Context, e detect.ComposeEnv) error
- type Conflict
- type LiveLog
- type Result
- type Summary
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EnvUp ¶
func EnvUp(ctx context.Context, env []string, e *detect.ComposeEnv, out io.Writer, services ...string) error
EnvUp brings a compose env up (build, detached) in dependency waves, then waits for it to become healthy — the `run` counterpart of the env handling Run does inline. Progress streams to out.
services, when non-empty, is a positional list of compose service names to bring up (instead of every profile-less service). The runner uses it in global mode to skip services that duplicate a sibling already running from its own repo.
func PrepareEnv ¶
PrepareEnv builds the process environment for a target: os.Environ() plus, when the target has a compose env, Go-allocated host ports, their derived URLs/DSN, standard local test creds for referenced vars, and finally whatever scripts/setup-env.sh defines (service constants). It is the single source of env truth shared by `build`/`test` (Run) and `run`. The `── env ──` / `── setup-env ──` progress is written to out.
func TearDown ¶
func TearDown(ctx context.Context, e detect.ComposeEnv) error
TearDown removes ONE compose project's containers, volumes AND orphans — scoped to that env via `-p <project> -f <file>`, never a global podman wipe. --remove-orphans cleans up containers the current compose no longer declares (e.g. after a profile change), which is what otherwise triggers `container name … already in use / use --replace`.
Two-pass teardown:
- Graceful: `compose down -t 10`. 10s is generous for postgres' shutdown checkpoint (which can stretch past 2s once the DB has dirty buffers from migrations + key rotation), but still snappy on quit.
- Force fallback if pass 1 errored: podman pod rm -f + network rm -f scoped to this env. Order matters — removing the pod first frees its containers, which de-references the network so its rm can succeed. podman-compose 1.5.0 occasionally returns success while leaving a running container — that container holds its pod, which holds the network — and the next run then fails to claim the same project name. Errors at this stage are intentionally swallowed: the resources may already be gone (first pass partially succeeded), or may never have come up.
Pod / network naming follows podman-compose's conventions:
- Pod: "pod_<project>" (podman-compose's resolve_pod_name convention)
- Network: "<project>_api" (matches every current service's compose `networks: { api: }` declaration; if a future service uses a different network name we'll need to read e.Networks instead).
Types ¶
type Conflict ¶
type Conflict struct {
Env detect.ComposeEnv
Containers []string
}
Conflict is a compose project that already has containers on the host — almost always the leftover of a previously aborted run that would collide with a target's env (deterministic project names mean the same env reuses the same project).
func EnvConflicts ¶
EnvConflicts returns the distinct env projects among targets that already have containers (running or not). It is a fail-safe preflight: running on top of a half-up env from an aborted command is the bug we want to catch.
type LiveLog ¶
type LiveLog struct {
// contains filtered or unexported fields
}
LiveLog holds the most recent output line per target, written concurrently by the parallel runners and read by the TUI each spinner tick so devs get a brief idea of progress and can spot a stalled command early. A nil *LiveLog is a valid no-op (non-interactive path).
func NewLiveLog ¶
func NewLiveLog() *LiveLog
NewLiveLog returns an empty LiveLog ready for concurrent writes and reads.
type Result ¶
type Result struct {
Target detect.Target
// Success is true iff the process exited zero.
Success bool
// ExitErr is the non-nil error from a failed/aborted process (non-zero
// exit, context cancellation, or a binary that could not be spawned).
ExitErr error
// Output is the combined stdout+stderr, trimmed. On success it is usually
// noise; on failure it is the thing the user actually needs to see, so it
// is always captured rather than streamed-and-dropped.
Output string
// Duration is wall-clock time spent in the subprocess.
Duration time.Duration
}
Result is the outcome of running one detect.Target.
func Run ¶
Run executes t.Cmd with t.Args in t.Dir, capturing combined output. It blocks until the process exits or ctx is cancelled. timeout > 0 bounds the whole target (env up + command); env teardown still runs on a detached context so a timed-out target is always cleaned up. live (may be nil) receives the most recent output line for the live TUI tail. It never panics and never returns a partially-zero Result — every field is meaningful.
type Summary ¶
type Summary struct {
Total int
Passed int
Failed int
// CumulativeDuration is the sum of every target's own build time. Under
// the interactive parallel runner this exceeds wall-clock time (overlapping
// builds are counted in full each), so it is NOT what the report shows as
// "took" — that is real elapsed time, tracked by the runner and passed in
// separately. CumulativeDuration is kept as the total work performed.
CumulativeDuration time.Duration
}
Summary aggregates a set of results for the report screen.