Skip to main content

cmd/taisce/cliui.go

cmd/taisce · 308 lines · 19 declarations · source

Declarations

const envCLIOutput

const envCLIOutput = "TAISCE_OUTPUT"

source

const envCLIASCII

const envCLIASCII = "TAISCE_ASCII"

source

type cliTheme

type cliTheme struct {
width, amber, blue, green, red, dim, reset int
ascii, color bool
}

source

func fancyOutput

func fancyOutput(out io.Writer) bool

source

func currentTheme

func currentTheme() cliTheme

source

func paint

func paint(enabled bool, code, value string) string

source

func cleanTerminal

func cleanTerminal(value string) string

cleanTerminal makes a value safe to draw: invalid UTF-8 becomes a replacement character; a line break, tab, line separator or paragraph separator becomes one space, so a value cannot start a new line inside a panel; and every control character (category Cc) and format character (category Cf) is removed.

Control characters are removed because an escape sequence in a name would repaint the screen. Format characters are removed because they act on how a line looks without being visible: a direction override reorders what follows it, so an operator reads something other than the value, and a zero-width character makes two different names print identically. They also break width arithmetic — counted as a cell, they draw a panel's border off by one. Removing the zero-width joiner splits a joined emoji into its parts, which is the price of that and is accepted.

Who could put such a character here, read from the code at the time of writing: nobody but the operator. Every value the renderer draws is a constant, a UUID, a rebuild status the schema limits to three words, or a project name the provisioner holds to `^[a-z][a-z0-9_]{0,62}$`. This is defence for the value somebody adds next, not a hole anyone can reach today (#19).

It does NOT normalise whitespace. It once collapsed runs of spaces and trimmed both ends, and every caller that measures width runs text through here — so a label padded to line up a column lost its padding, and a title's surrounding spaces stopped being counted, which drew the top border two cells wider than the rows beneath it (#18). Spacing a caller wrote is layout, not a hazard.

source

func runeWidth

func runeWidth(r rune) int

source

func clipDisplay

func clipDisplay(value string, limit int) string

source

func displayWidth

func displayWidth(value string) int

source

func statusPanel

func statusPanel(t cliTheme, title string, lines []string) string

source

func renderHelp

func renderHelp(t cliTheme) string

source

func meter

func meter(current, total int64, cells int, ascii bool) string

source

func renderHealth

func renderHealth(t cliTheme, h pg.OperationalHealth, inferenceConfigured bool) string

source

func renderRebuild

func renderRebuild(t cliTheme, job pg.RebuildJob) string

source

func renderReportRebuild

func renderReportRebuild(t cliTheme, r reportRebuildResult) string

A report rewrite has no job to point at afterwards, and no progress bar worth drawing: the count that matters is how many subjects are still waiting, which this command reports as staleness beside its own result. So the next step is to read that, which is the JSON form of this same call.

source

func renderFailure

func renderFailure(t cliTheme, _ error) string

source

func inferenceIsConfigured

func inferenceIsConfigured() bool

source

func startCLIActivity

func startCLIActivity(ctx context.Context, label string) func()

startCLIActivity owns one bounded redraw loop on stderr. The deferred stop restores the line on success, failure, or cancellation; structured stdout remains untouched.

source