phasebox

package
v0.20.0 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2026 License: LGPL-3.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildProgress

func BuildProgress(sess Session, imageNames []string) func(docker.Progress)

BuildProgress adapts docker.Client.BuildCardinalImages' progress callback. imageNames pre-seeds every row as Pending ("queued") before its first Progress event, so not-yet-started builds show immediately instead of popping in late.

func ClusterLogRow

func ClusterLogRow(sess Session, id, label string) func(line string)

ClusterLogRow returns an OnK3DLog-compatible func(string) that live-updates one row's detail with each k3d log line. Each call site owns its own Session, so — unlike the bare-spinner approach it replaces — no global routing between concurrent sessions is needed.

func PullProgress

func PullProgress(sess Session) func(docker.Progress)

PullProgress adapts docker.Client.PullImages' progress into row updates: a real percent bar while pulling (Current is already 0-100), swapping to a done/failed icon row once the pull finishes.

Types

type Box added in v0.18.0

type Box struct {
	// contains filtered or unexported fields
}

Box is an opened section; opening it before Run fixes its place in the order.

func (*Box) Run added in v0.18.0

func (b *Box) Run(
	fn func(ctx context.Context, sess Session) error,
	summarize func(elapsed time.Duration) string,
) error

Run runs fn with a Session scoped to this box, then appends a summary below its rows (which stay visible, not replaced): summarize's on success, a fixed failed/canceled line otherwise, since the error is printed after the dashboard. fn gets the dashboard's shared, Ctrl+C-cancelable context, and a resulting context.Canceled becomes a silent error.

type Dashboard

type Dashboard struct {
	// contains filtered or unexported fields
}

Dashboard is one continuous bubbletea program spanning every section a command opens (e.g. "Image Pull", "Build", "Cluster", "Shards" for `world start`), rendered through a single Model so there's no hand-off gap where one box's border could visually merge with the next. With Plain progress there's no program; each section prints one summary line.

func Start

func Start(ctx context.Context, progress Progress) *Dashboard

Start opens a dashboard scoped to ctx, shown per progress. Ctrl+C cancels the shared context, so a cancellation is visible to every later section too, not just the active one. Callers should `defer dash.Complete()` immediately.

func (*Dashboard) Complete

func (d *Dashboard) Complete()

Complete stops the dashboard's program, leaving every section's final frame — rows and all — in the terminal scrollback. Idempotent: callers `defer dash.Complete()` and may also call it early to release the terminal before writing to it directly, so the deferred second call must be a no-op.

func (*Dashboard) Info

func (d *Dashboard) Info(title, body string)

Info adds a titled section showing body as static, finished content — no spinner, rows, or icon. For content that isn't a pass/fail task (e.g. endpoint URLs), since Run's summary always carries a ✓/✗ icon that reads oddly there.

func (*Dashboard) Open added in v0.18.0

func (d *Dashboard) Open(title string) *Box

Open appends a titled section.

func (*Dashboard) Run

func (d *Dashboard) Run(
	title string,
	fn func(ctx context.Context, sess Session) error,
	summarize func(elapsed time.Duration) string,
) error

Run opens and runs a section; see Box.Run.

type Model

type Model struct {
	// contains filtered or unexported fields
}

Model is the bubbletea model backing a Dashboard — one continuous program spanning every section opened during a command's run, rendered as a single box (style.MultiSectionBox). Routing every section through one Model instead of one tea.Program per section avoids the hand-off gap where a second program's first frame could land on the first program's last row.

func (Model) Init

func (m Model) Init() tea.Cmd

func (Model) Update

func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (Model) View

func (m Model) View() string

type Progress added in v0.18.1

type Progress string

Progress is how a Dashboard shows progress.

const (
	// TTY is the live box, redrawn in place; it needs an interactive terminal.
	TTY Progress = "tty"
	// Plain prints one line per finished section, for logs that can't redraw,
	// such as CI's.
	Plain Progress = "plain"
)

type Row

type Row struct {
	Label    string
	Detail   string
	State    RowState
	Progress *int
}

Row is one line within a section, keyed externally by an id (see rowMsg / progressMsg). Progress is non-nil only for a percent-bar row (set by UpsertProgress); a later plain UpsertRow call for the same id replaces the Row wholesale, implicitly clearing it back to an icon-rendered row.

type RowState

type RowState int

RowState is the lifecycle state of a single row within a phasebox.

const (
	// Pending marks a row that hasn't started yet (e.g. a build queued
	// behind another).
	Pending RowState = iota
	// Active marks a row currently in progress; it renders with the box's
	// shared animated spinner frame.
	Active
	// Done marks a row that finished successfully.
	Done
)

type Session

type Session interface {
	// UpsertRow renders id's row as an icon (per state) + label + detail.
	UpsertRow(id, label, detail string, state RowState)
	// UpsertProgress renders id's row as label + a percent-complete bar
	// (e.g. "golang:1.26.2 ████████░░░░░░░░ 42%") instead of an icon, for
	// determinate operations like image pulls. Always implicitly Active;
	// follow with UpsertRow(..., Done) or Fail to swap back to an icon row.
	UpsertProgress(id, label string, percent int)
	// Fail marks id's row ✗ "failed" or "canceled". err's text never goes in
	// the box (a row is one truncated line); it's printed after the dashboard.
	Fail(id, label string, err error)
}

Session is the live handle into a running phasebox, scoped to the lifetime of one Run call. UpsertRow/UpsertProgress insert a row on first use (by id) and update it on every subsequent call; rows render in first-insertion order.

type StepTracker

type StepTracker struct {
	// contains filtered or unexported fields
}

StepTracker turns a sequence of named steps (e.g. cluster.StartOpts.OnStep) into a live checklist of Session rows: each Next call marks the previous step Done and starts the next Active, showing which phase a multi-phase operation is in instead of one static spinner.

func NewStepTracker

func NewStepTracker(sess Session) *StepTracker

NewStepTracker returns a tracker that pushes rows into sess.

func (*StepTracker) Detail

func (t *StepTracker) Detail(detail string)

Detail updates the current step's trailing detail text (e.g. a log line) without changing its state. No-op before the first Next call.

func (*StepTracker) Done

func (t *StepTracker) Done()

Done marks the current (final) step Done. Call once the whole sequence finishes successfully. No-op before the first Next call.

func (*StepTracker) Failed

func (t *StepTracker) Failed(err error)

Failed marks the current step failed (see Session.Fail). No-op before the first Next call.

func (*StepTracker) Next

func (t *StepTracker) Next(label string)

Next marks the current step (if any) Done and starts a new Active row for label.

Jump to

Keyboard shortcuts

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