cliui

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2026 License: MIT Imports: 10 Imported by: 0

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

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

func VerifyManagedBinary(ctx context.Context, binary string, args []string) error

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.

Jump to

Keyboard shortcuts

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