Documentation
¶
Overview ¶
Package render turns the view model in internal/common/report into text for a terminal: it decides how wide a column is, how a value that does not fit is cut, and how much room the line has to begin with.
It is the presentation side of the split, and that is why it may import lipgloss ¶
The model holds facts about a run and carries no width, no padding and no escape sequence; a test there enforces that it imports nothing that renders. This package is the other half of that boundary, so measuring and styling belong here and nowhere upstream of here.
Nothing here declares a width ¶
Every width in this package is either measured from the values a run actually produced, or read from the device the report is being printed to. The one number that is written down is the width assumed when the device cannot be reached at all, and it is documented as such.
Index ¶
- func ColumnWidth(values []string) int
- func Fullscreen(blocks []report.Section, opts Options) error
- func Inline(blocks []report.Section, opts Options) error
- func JSON(w io.Writer, run report.Run) error
- func Markdown(w io.Writer, blocks []report.Section) error
- func Plain(w io.Writer, blocks []report.Section, opts Options) error
- func Shorten(s string, cells int) string
- type Options
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ColumnWidth ¶
ColumnWidth is columnWidth, exported.
Three typed widths still stand outside the check path — overlay prune, the autoupdate sweep, and the drift printer — each with the same defect. Exporting the measurement means whoever touches those files next has the replacement in reach instead of a reason to type a width again.
It must stay a thin call. A wrapper that drifted would hand those callers a different answer than this package's own renderer uses, leaving two columns that disagree about the same package list; a test pins the two together.
func Fullscreen ¶
Fullscreen renders blocks in an alternate screen, then prints the whole report to the scrollback when that screen goes away.
The report is the blocks argument, never the finished model: every exit path prints that slice, so the dump survives a model that crashed and a program that never started.
Bubble Tea catches a panic in Update or View by default: it leaves the alternate screen and Run returns ErrProgramPanic, so that case prints through the errors.Join at the end like any other return. The deferred recover covers what Bubble Tea does not catch: a panic outside Run, or in a program started without its panic handler. It restores the terminal itself, prints the report and re-panics, since swallowing the panic would turn a crash into a silent wrong answer.
ctrl+c adds one section, interruptNotice, at the top of the dump. Output goes to os.Stdout: the dump belongs in the scrollback the alternate screen hid.
func Inline ¶
Inline renders blocks into the terminal's scrollback, styled.
It is Plain plus escape sequences and nothing else: the same sections, wording, shortening and column widths come from the identical code, and the paint only decorates a line that is already laid out. The modes may differ in presentation, never in content, and here that cannot be broken without deleting the seam. It takes sections, not a report: the caller decides WHAT the report says, this decides only how it LOOKS, so a new command is a new file rather than an edit here.
It takes no io.Writer on purpose. Plain, Markdown and JSON write a stream that may go anywhere; an inline renderer owns a region of the terminal, whose escape sequences mean nothing to a byte sink. So the destination is os.Stdout, and a test captures the descriptor.
It is not an internal/common/tui.Reporter: that is a progress sink fed while work happens, this is a finished description printed once the work is over. Merging them would make the final report depend on the live UI having run, which an export must not; nothing here accepts a tea.Msg or starts a program.
func JSON ¶
JSON writes run as one indented JSON document: the whole report, for a reader that is a program rather than a person.
The model IS the document: report.Run goes to encoding/json as it stands, with no wire type, so the document carries every fact the renderers read by construction. No payload TYPE is named here, so a field added to any payload reaches the export with no edit. The model's json tags are therefore a contract (a renamed tag breaks a consumer's jq); root keys are declared in report/run.go, the ones under "payload" by each payload. kind and schema sit at the root: kind is what a consumer branches on, and schema is 2 because the unversioned pre-envelope shape is schema 1 in the field.
It takes no Options, so an export has no Width to shorten to and no ShowAll to honour: it always carries every unit and every reason in full. It writes and never reads (see report.Run). A nil slice reaches the wire as null, on purpose: rewriting it to [] would break the lossless round trip the payload is pinned on, so the producer that left it nil is where to fix it. HTML escaping stays on, matching renderValidateJSON in cmd/bentoo, so the CLI emits one dialect of JSON. A write error is returned, never swallowed.
func Markdown ¶
Markdown renders blocks as a Markdown document: the same sections, in the syntax a pull request comment, an issue and a file in a repository all read.
It takes no Options, and that absence IS the requirement: an export carries the complete report — every package, every reason in full, whatever the terminal was asked for — and with no width or ShowAll to honour, an export that mirrored screen truncation cannot be written. A report is kept BECAUSE the terminal is gone; if threading a width in here ever looks convenient, that is the defect arriving as a convenience.
Listing every scanned package (the screen only counts the up-to-date ones) is the caller's promise, made when the sections were built, so a kept report can answer "was this one checked at all". It differs from Plain by table syntax and nothing else: both hand the same sections to a style. A result whose reason repeats its plan entry prints no second copy here either, which drops a DUPLICATE: the sentence is still whole on the plan row.
func Plain ¶
Plain renders blocks as text with no escape sequence in it.
It takes sections, not a report: everything here is layout (column widths, cuts, underlined headings), and nothing knows what a package or a gate is, so a new command is a new payload rather than an edit here. The caller decides WHAT the report says; this decides only how it LOOKS.
It is the mode a pipe, a redirect, a cron mail and a CI transcript receive: no colour, no cursor movement, no live region. lipgloss is used only to MEASURE, never to render, so the no-escape property holds by construction. It draws no box, which a log cannot use and which costs two cells per line; sections are separated by a title and a rule built from borderStyle's own segment, so changing the border once changes every mode.
Every write is checked: the first failing write is returned, wrapped, and stops the rest, rather than reporting success for output nobody received.
Types ¶
type Options ¶
type Options struct {
// Width is the line budget in display cells: no rendered line exceeds it
// Zero means "ask the device", which is terminalWidth's job, so a caller
// that has no opinion does not have to invent one.
//
// Read it through cells() rather than directly: the zero is a question, not
// an answer.
Width int
}
Options is everything a caller may decide about one rendering. It holds no fact about the run — those all come from the sections it is rendering.
Its one field, Width, is a line budget measured off the terminal the output is going to, which nothing upstream of a renderer can know; that is the whole of what a renderer is entitled to decide.
ShowAll and SkipPlan are deliberately NOT here: whether a list is stated or only counted is content, so they live on report.SectionOptions, what a payload is ASKED. SectionOptions is what the report should SAY, Options is what the device ALLOWS; a renderer reading ShowAll would make plain and fullscreen say different things. Nothing may be added here that a payload could have answered. Markdown and JSON take no Options at all, so an export path cannot ask questions an export must never ask.