cliui

package
v0.22.0 Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package cliui holds the framework-neutral parts of an install CLI's user interaction: the Row view type a caller assembles from cliinstall's own catalog, status and batch-result types; the text and JSON writers for a listing, a details/dry-run/install-result view, and the batch confirmation prompt. It imports neither Cobra nor any other command framework — a hand-rolled CLI with no framework at all can build its own "install" command straight from cliinstall.Probe/Install plus this package, and get the exact same formatting, labelling and confirmation behavior the cobracmd subpackage gives a Cobra-based CLI.

This package deliberately mirrors github.com/strongo/cli-helpers/selfupdate/cliui's own shape: a Confirm callback matching the core package's own confirmation signature, a ManagedCommandRunner-style reuse of that package's IsTerminal check rather than a second one, and text/JSON writer pairs named the same way. cobracmd is the Cobra-specific flag/wiring layer built on top of this package; this package has no dependency on it, or on Cobra, at all.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Confirm

func Confirm(opts ConfirmOptions) func(planned []cliinstall.Result) (bool, error)

Confirm builds a cliinstall.Options.Confirm callback (cli-install#req:confirmation-gate: "one confirmation covering every target that would be installed"). cliinstall.Execute calls it at most once per batch, only when at least one target still needs confirming and Options.Yes is false, so this callback has no --yes concern of its own.

planned is exactly the plan Execute is about to install from — already printed once by the caller (typically via WriteResult on cliinstall.Plan's own output, before Execute ever runs) — so this callback only asks the yes/no question; it does not re-render descriptions, details or planned actions a second time (task-5 review B1: "printed once, no second pass").

It refuses with a *selfupdate.Failure{Kind: selfupdate.KindNonInteractive} when no interactive terminal is available (self-update#req:non-interactive-refusal, reused verbatim by cli-install#req:confirmation-gate's "Without --yes and without an interactive terminal the command MUST refuse... before any download or write"), and otherwise reads a y/N answer. An empty read — the terminal check said interactive but nothing came back — is treated the same as the non-interactive case, for the identical reason selfupdate/cliui.Confirm documents: nobody was actually asked, so reporting a decline (which callers may read as "nothing failed") would let a script believe the refusal never happened.

func RowName

func RowName(row Row) string

RowName is the id this row is about: Entry.ID when the target is a known catalog entry, otherwise Plan.Target — the raw name that was not a catalog id (cli-install#req:unknown-target-refused).

func UpgradeConfirm added in v0.21.0

func UpgradeConfirm(opts ConfirmOptions) func(pending []cliinstall.UpgradeResult) (bool, error)

UpgradeConfirm builds a cliinstall.UpgradeOptions.Confirm callback (cli-install#req:upgrade-batch-semantics inheriting cli-install#req: confirmation-gate: "one confirmation covering every target that would be replaced or have a manager command executed"), mirroring Confirm's own install-side shape and refusal rules exactly — see that function's own doc comment for the interactive/non-interactive/empty-answer contract, which this callback reuses verbatim, only asking "Upgrade" instead of "Install".

func UpgradeRowName added in v0.21.0

func UpgradeRowName(row UpgradeRow) string

UpgradeRowName is the id this row is about.

func WriteList

func WriteList(out, errOut io.Writer, host string, rows []Row)

WriteList writes rows' human-readable listing to out (cli-install#req:list-relevant, cli-install#req:list-all) and every row's warnings to errOut (cli-install#req:machine-readable-output's stderr convention, applied to text output too). rows is exactly what the caller wants listed, in the order it should appear: the host's relevant targets in matrix order for a bare listing, or every other catalog entry appended alphabetically for --all (cli-install#req:list-all) — this package makes no catalog decision of its own.

Like selfupdate/cliui's own text writers, individual terminal write errors are not propagated — a terminal or pipe write essentially never fails in practice, and threading that failure through every line would bloat every caller for no real benefit.

func WriteListJSON

func WriteListJSON(out, errOut io.Writer, host string, rows []Row) error

WriteListJSON writes rows' cli-install#req:machine-readable-output listing document — one JSON object with "host" and one "targets" entry per row — to out, and every row's warnings to errOut.

func WriteOutcome

func WriteOutcome(out, errOut io.Writer, rows []Row, batchErr error)

WriteOutcome writes rows' TERSE post-execution report to out — one line per target, its id and outcome only — and every row's warnings to errOut. This is the report Execute's own result gets, printed AFTER the full WriteResult preview a caller already showed once before confirming: repeating every description, details, homepage and relevance block a second time would be exactly the duplicated output task-5 review B1 found ("every description and details block prints twice"). batchErr is the same batch-level failure WriteResult accepts.

func WriteResult

func WriteResult(out, errOut io.Writer, host string, rows []Row, batchErr error)

WriteResult writes rows' human-readable details/dry-run/install-result view to out (cli-install#req:details-before-install, cli-install#req:install-dry-run, cli-install#req:multi-target-batch), and every row's warnings to errOut. A row with a nil Plan is rendered as a bare status/relevance preview (no planned or completed action line); a row with Plan set adds that action, rendered per its Outcome. batchErr is a batch-level failure that happened before, or independent of, any per-target row (an unknown name, or the confirmation gate's own non-interactive refusal) — reported as its own line so a batch-level refusal is never silent in text mode either (task-5 review S2).

As with WriteList, individual terminal write errors are not propagated — see that function's own doc comment.

func WriteResultJSON

func WriteResultJSON(out, errOut io.Writer, host string, rows []Row, batchErr error) error

WriteResultJSON writes rows' cli-install#req:machine-readable-output details/dry-run/install-result document — one JSON object with "host" and one "targets" entry per row, each carrying the "details" field the bare listing document omits — to out, and every row's warnings to errOut. batchErr is a batch-level failure (an unknown name, or the confirmation gate's own non-interactive refusal) that happened before, or independent of, any per-target row; nil for an ordinary result. Either way exactly one JSON document is written (task-5 review S2).

func WriteUpgradeNextStep added in v0.21.0

func WriteUpgradeNextStep(out io.Writer, host string)

WriteUpgradeNextStep writes REQ: upgrade-no-args-reports' own closing line — the bare report's "end with the next step" requirement — naming both ways to actually act on what the report just showed. It is never called for --check or a named/--all invocation: those are already the "next step" the bare report points to.

func WriteUpgradeReport added in v0.21.0

func WriteUpgradeReport(out, errOut io.Writer, rows []UpgradeRow, batchErr error)

WriteUpgradeReport writes rows' terse, one-line-per-target upgrade view to out, and every row's warnings to errOut. It is the ONE writer for the read-only report/--check, the pre-confirmation preview REQ: details- before-install requires, and the executed/dry-run result alike: the founder's own brief asks for terse, scannable output, and every fact those REQs require (current/latest version, verdict, manager command, resolved path) already fits on one line, so there is no separate verbose form to keep in sync with it (unlike install's WriteResult/WriteOutcome pair). batchErr is a batch-level refusal (an unknown name, or the confirmation gate's own non-interactive refusal) reported on its own line first, exactly as WriteResult reports one for install.

func WriteUpgradeReportJSON added in v0.21.0

func WriteUpgradeReportJSON(out, errOut io.Writer, host string, rows []UpgradeRow, batchErr error) error

WriteUpgradeReportJSON writes rows' cli-install#req:machine-readable- output report/dry-run/upgrade-result document — one JSON object with "host" and one "targets" entry per row — to out, and every row's warnings to errOut. batchErr is a batch-level failure (an unknown name, or the confirmation gate's own non-interactive refusal); nil for an ordinary result. Either way exactly one JSON document is written, mirroring WriteResultJSON's own "never an empty document" rule.

Types

type ConfirmOptions

type ConfirmOptions struct {
	// In is read for the user's y/N answer once a prompt is actually shown.
	In io.Reader
	// Out receives the "Install <names>? [y/N] " prompt text when one is
	// shown.
	Out io.Writer
	// Interactive reports whether an interactive terminal is available to
	// ask on. Nil defaults to selfupdate/cliui.IsTerminal — this package
	// reuses that check rather than a second one, since a character device
	// (e.g. /dev/null) must not be misread as an interactive terminal for
	// this confirmation any more than for self-update's own (see that
	// function's own doc comment).
	Interactive func() bool
}

ConfirmOptions configures the callback Confirm builds for cliinstall.Options.Confirm.

type Row

type Row struct {
	// Entry is the target's catalog entry. Zero for a name that was not a
	// catalog id (Plan.Failure's Kind is then selfupdate.KindUnknownTarget;
	// RowName falls back to Plan.Target for that case).
	Entry cliinstall.Entry
	// Relevant reports whether Entry is one of the host's relevant targets
	// (cli-install#req:relevance-matrix).
	Relevant bool
	// Relevance is the host -> target relevance text; empty when Relevant
	// is false (cli-install#req:non-relevant-target-allowed).
	Relevance string
	// Status is the target's probed install state — the pre-plan probe for
	// a bare listing row, or the same Status a Plan itself carries
	// (Plan.Status) once one exists.
	Status cliinstall.Status
	// Plan is set once a method/destination (or cask) has been decided for
	// this target: a dry run's Result (cli-install#req:install-dry-run) or
	// a real batch Install's Result (cli-install#req:multi-target-batch).
	// Nil for a bare listing row, where only Status is known.
	Plan *cliinstall.Result
}

Row is one target's combined catalog, status and (optionally) planned or completed install data for a listing, details, dry-run or install-result view. The caller — typically cliinstall/cobracmd, but equally a hand-rolled CLI with no framework at all — assembles Row values from cliinstall.Entries/Relevant/ByID and cliinstall.Probe/Install; this package reads them but never calls into cliinstall itself (cli-install#req:core-framework-neutral).

type UpgradeRow added in v0.21.0

type UpgradeRow struct {
	// Entry is the target's catalog entry (its own, or the host's own entry
	// for the host row).
	Entry cliinstall.Entry
	// Relevant reports whether Entry is one of the host's relevant targets
	// (cli-install#req:relevance-matrix). Always false for the host row
	// itself — a target is never relevant to itself.
	Relevant bool
	// Relevance is the host -> target relevance text; empty when Relevant
	// is false.
	Relevance string
	// Result is this target's planned or executed upgrade outcome.
	Result cliinstall.UpgradeResult
}

UpgradeRow is one target's combined catalog, relevance and upgrade-result data for the report, dry-run preview or executed-result view. Unlike install's Row, Result is never nil: cliinstall.PlanUpgrade/CheckUpgrades/ ExecuteUpgrade/Upgrade always produce one cliinstall.UpgradeResult per candidate — there is no bare-status-only row upgrade ever shows, since REQ: upgrade-no-args-reports' own bare report IS a full plan over the --all set, not a separate, cheaper listing.

Jump to

Keyboard shortcuts

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