Documentation
¶
Overview ¶
Package cliui holds the framework-neutral parts of a self-update CLI's user interaction: the confirmation prompt (REQ: non-interactive-refusal), the terminal check it relies on, and the text/JSON writers for selfupdate.Outcome and selfupdate.CheckResult. It imports neither Cobra nor any other command framework — a hand-rolled CLI with no framework at all can build its own command straight from selfupdate.Config.Check/ .Update plus this package, and get the exact same prompting, formatting, and refusal behavior the cobracmd subpackage gives a Cobra-based CLI, including this package's own already-fixed bugs: a character device is not a terminal (see IsTerminal), and an empty read is a refusal, not a decline (see Confirm).
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 ¶
- func Confirm(opts ConfirmOptions) func(transition string) (bool, error)
- func IsTerminal() bool
- func ManagedCommandRunner(in io.Reader, out, errOut io.Writer) selfupdate.ManagedCommandRunner
- func VerifyManagedBinary(ctx context.Context, binary string, args []string) error
- func WriteAmbiguousGuidance(out io.Writer, cfg selfupdate.Config)
- func WriteCheck(out io.Writer, cfg selfupdate.Config, result selfupdate.CheckResult)
- func WriteCheckJSON(out io.Writer, cfg selfupdate.Config, result selfupdate.CheckResult, ...) error
- func WriteNextStep(out io.Writer, cfg selfupdate.Config, detection selfupdate.Detection, ...)
- func WriteOutcome(out, errOut io.Writer, cfg selfupdate.Config, outcome selfupdate.Outcome)
- func WriteOutcomeJSON(out io.Writer, outcome selfupdate.Outcome) error
- type ConfirmOptions
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Confirm ¶
func Confirm(opts ConfirmOptions) func(transition string) (bool, error)
Confirm builds a selfupdate.Options.Confirm callback: it prints the transition, honours a --yes-style skip via ConfirmOptions.Yes, refuses with a *selfupdate.Failure{Kind: selfupdate.KindNonInteractive} when no interactive terminal is available (REQ: non-interactive-refusal), and otherwise reads a y/N answer from ConfirmOptions.In.
An empty read — the terminal check said interactive but nothing came back, e.g. stdin is closed or redirected from an empty pipe — is treated the same as the non-interactive case: a refusal, not the user declining. Nobody was actually asked, so reporting success (as a plain decline would, via ActionAborted with a nil error) would let a script read exit 0 and believe an update ran. A decline the user actually typed ("n", or anything but y/yes) is reported as (false, nil), which selfupdate.Config.Update turns into ActionAborted, not a failure.
func IsTerminal ¶
func IsTerminal() bool
IsTerminal reports whether stdin is a real terminal.
The obvious test — os.Stdin.Stat() and a check for os.ModeCharDevice — is wrong, and wrong in the direction that matters: /dev/null IS a character device, so a command run as `cmd < /dev/null` (how agents, cron and CI habitually invoke things) was classified interactive, prompted into the void, read EOF, and reported "aborted" with exit 0. A caller reading that exit code sees success where nothing happened, which is precisely what REQ: non-interactive-refusal exists to prevent. Ask the terminal driver instead: an ioctl either answers for a tty or it does not.
func ManagedCommandRunner ¶ added in v0.6.0
func ManagedCommandRunner(in io.Reader, out, errOut io.Writer) selfupdate.ManagedCommandRunner
ManagedCommandRunner returns a framework-neutral runner that passes the configured executable and argv directly to the operating system. It never parses a display command or invokes a shell. Process input and output are streamed through the caller-owned readers and writers.
func VerifyManagedBinary ¶ added in v0.6.0
VerifyManagedBinary locates binary on PATH after a successful manager command and runs its configured version probe. A successful probe must emit non-empty output; callers surface a failure as a post-update warning.
func WriteAmbiguousGuidance ¶
func WriteAmbiguousGuidance(out io.Writer, cfg selfupdate.Config)
WriteAmbiguousGuidance prints the manual-update guidance REQ: ambiguous- safe-default leaves to the consumer: the core selfupdate package only reports that classification failed, not what the user should do about it.
func WriteCheck ¶
func WriteCheck(out io.Writer, cfg selfupdate.Config, result selfupdate.CheckResult)
WriteCheck writes result's human-readable text form to out.
func WriteCheckJSON ¶
func WriteCheckJSON(out io.Writer, cfg selfupdate.Config, result selfupdate.CheckResult, detection selfupdate.Detection) error
WriteCheckJSON writes result's --format json shape (checkJSON) to out, including detection's install-method classification so a machine caller can decide the next step the same way WriteNextStep states it in text. cfg is accepted for signature symmetry with WriteCheck/WriteOutcome — the JSON shape itself carries no field derived from it today.
func WriteNextStep ¶
func WriteNextStep(out io.Writer, cfg selfupdate.Config, detection selfupdate.Detection, commandPath string)
WriteNextStep states what to actually do about an available update, which depends entirely on how the binary was installed: an executable managed install can run this command, a redirect-only managed install must run the manager command directly, a manual one can run this command, and an ambiguous one gets the same refusal guidance the update path would print. commandPath is the fully-qualified invocation (e.g. "wb self-update") so the instruction is copy-pasteable in whatever CLI embeds this command.
func WriteOutcome ¶
func WriteOutcome(out, errOut io.Writer, cfg selfupdate.Config, outcome selfupdate.Outcome)
WriteOutcome writes outcome's human-readable text form to out, and a post-swap version-probe warning (REQ: post-swap-version-check), when one is present, to errOut.
func WriteOutcomeJSON ¶
func WriteOutcomeJSON(out io.Writer, outcome selfupdate.Outcome) error
WriteOutcomeJSON writes outcome's --format json shape to out.
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 transition line always, and the "Proceed? [y/N] "
// prompt text when one is shown.
Out io.Writer
// Yes skips the prompt and proceeds immediately without consulting
// Interactive at all — wire this from a --yes/-y style flag.
Yes bool
// Interactive reports whether an interactive terminal is available to
// ask on. Nil defaults to IsTerminal.
Interactive func() bool
}
ConfirmOptions configures the callback Confirm builds.