❯ go-clikit
v0.10.0 pkg.go.dev ↗

concepts › displays and themes

Displays and themes

The command shows its spans as a live tree, a counter or plain lines, and leaves a summary. Each display shares the terminal with the command.

The library sends events. The command picks how to show them. The kit has three displays and a summary, in progress/display. Most programs let progress/cliprogress pick one from the words of --progress.

DisplayForShows
Treea person at a terminalthe work under way and what of it failed, in a few rows at the bottom
Countera small terminal, or a person who wants lessone line: how far the work got
Plaina log, such as a CI jobone line for each change worth a line, with the time
Summaryeveryoneone line once the command ended: how it ended, how long it ran, how many ended how
reinstall exe[01-12] --progress=tty
✓ fetching the base image  5.0s  2.0 GiB at 410 MiB/s
reinstall ◦ 0:10.5
╎ reinstalling the nodes  ◉◉◉◉◉◌◌◌◌◌ 6/12 ◦ 4 running ◦ 2 queued
  ╎ ◡ exe07  2.8s/30s  POST /redfish/v1/Systems/1
  ╎ ◡ exe08  2.1s/30s  POST /redfish/v1/Systems/1
  ╎ ◡ exe09  1.4s/30s  POST /redfish/v1/Systems/1
  ╎ ◡ exe10  0.7s/30s  POST /redfish/v1/Systems/1
  ╎ ✓ exe[01-06]
The tree. Twelve nodes, four at a time; exe07 fails. Pick a theme.
reinstall --progress=counter
◠ reinstalling the nodes ◦ 4/12 ◦ 4 running ◦ 4 queued ◦ 0:08.7
The counter: one line.
reinstall --progress=plain
[0:00] reinstall › fetching the base image: start
[0:05] reinstall › fetching the base image: done in 5.0s: 2.0 GiB at 410 MiB/s
[0:05] reinstall › reinstalling the nodes: start, 12 targets, 4 at a time
[0:10] reinstall › reinstalling the nodes › exe07 failed (target): BMC answered 503
[0:14] reinstall › reinstalling the nodes: failed in 9.0s: 11 ok, 1 failed
reinstall: failed in 14s: 11 ok, 1 failed, 2.0 GiB at 143 MiB/s
Plain lines, with the summary as the last line.

The terminal is shared#

The tree and the counter own a few rows at the bottom of the terminal, the region, and nothing else. The command still writes to the terminal, so the two must take turns. A display.Terminal does this:

  • The command writes through Terminal.Writer. It takes the region off first, and lets it back only once a line has ended. So a question that waits for its answer is never drawn over.
  • Goroutines beside the command, such as a logger, write through Terminal.Lines. It holds their lines, whole lines only, while a question is asked or the command has a line open.
  • progress.Suspend takes every display off the terminal, for a question, and returns once they are off.
$ clusterctl reinstall exe[01-12]note: exe03 has no BMC; using IPMI✓ fetching the base image 5.0s 2.0 GiB↑ lines above the regionreinstall ◦ 0:08.7╎ reinstalling the nodes 4/12 ◦ 4 running╎ ◞ exe05 1.1s/30s POST /redfish/v1/Systems/1╎ ✓ exe[01-04]the region, redrawn
The region at the bottom, and what scrolls above it. The command’s own lines and the lines a display leaves go above the region.

A display never hides the cursor. A process that is killed while it draws leaves a terminal that works, at worst with the rows of its last frame.

Many targets#

A step over 480 hosts cannot show 480 rows. The tree folds the targets that ended the same way into node sets, such as exe[0001-0480], with go-nodeset. It folds a large set again once a second (decision 16), and its cost per frame does not grow with the number of targets. A test of the kit holds it to that.

Themes#

The zero display.Theme draws plain text with no escape code. That text is an interface: programs compare it in their tests. Five themes add colours and marks: Classic, Aurora, Ember, Neon and Tide.

  • A theme only adds to what a display says. Names, errors and output lines stay in the terminal’s own colour.
  • Every glyph of a theme takes one column, in every locale.
  • display.Theme.In draws a theme in 256 colours, in the terminal’s 16, or in none, with its marks alone.
  • The colours and the art of a theme can change in a minor release. Its name and its words cannot (decision 20).
NOTE

The kit reads no environment. The program decides if it draws in colour, from NO_COLOR, TERM, COLORTERM and whether standard error is a terminal. cliprogress.ThemeFor applies the usual rule to the values that the program read.

The summary and standard error#

Once the command ended, the display leaves one line, and the program writes the error. The programs that use the kit share one convention for standard error:

  • Standard output holds the result, and nothing of the progress.
  • Standard error holds the progress, the notes of the command, the lines of its logger, then the summary and one line for the error, escaped.
  • Without a display, standard error holds exactly what it would hold without the kit, byte for byte. A command that is done in its first second draws nothing.