output

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package output renders command results.

stdout is data, stderr is everything else

One rule governs everything here. Warnings, notices, prompts, progress, totals, truncation notices and update banners go to stderr; stdout carries the data a command was asked for and nothing else. So `fft facility list -o json | jq` receives JSON even when fft also had something to say to the human at the keyboard, and a script's stdout never depends on whether a warning fired.

Commands reach these streams through cmd.OutOrStdout() and cmd.ErrOrStderr(), never through os.Stdout — which is what lets a spec assert on both.

Two renderings of the same thing, on purpose

A table is a hand-written view model: the generated models are anyOf/oneOf unions with two dozen optional pointers, and printing one is unreadable. The view model flattens it into the few columns a human wants.

`-o json` prints the API's own JSON, unaltered (Printer.RenderRaw). A script that pipes fft into jq needs every field the API sent, including the ones fft's view model dropped and the ones the swagger forgot to declare — and there are some. Reshaping it through a Go struct would silently discard exactly the fields that made the script necessary.

Forcing one shape to serve both is what produces tables full of struct dumps and JSON full of padding.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Formats

func Formats() []string

Formats lists every valid -o value, for help text and shell completion.

Types

type Format

type Format string

Format is how a command renders its result.

const (
	Table Format = "table"
	JSON  Format = "json"
	YAML  Format = "yaml"
)

The supported formats.

func ParseFormat

func ParseFormat(s string) (Format, error)

ParseFormat validates a -o value.

type Printer

type Printer struct {
	// contains filtered or unexported fields
}

Printer renders to a command's output and error streams.

func New

func New(out, err io.Writer, format Format, color bool) *Printer

New returns a Printer writing data to out and diagnostics to err.

func (*Printer) Empty

func (p *Printer) Empty(noun string) error

Empty reports a result set with nothing in it.

An empty result is not an error, and a lone header row for it is noise a script has to filter out. So a table says so on *stderr* and leaves stdout genuinely empty, while -o json prints `[]` — which is what `| jq length` needs in order to answer 0 rather than to fail.

noun names what there was none of, plural: "facilities", "listings".

func (*Printer) Format

func (p *Printer) Format() Format

Format is the format the printer renders in.

func (*Printer) Notef

func (p *Printer) Notef(format string, args ...any)

Notef tells the human something. It goes to stderr, so it is safe to call from a command whose stdout is being piped into jq.

func (*Printer) Out

func (p *Printer) Out() io.Writer

Out is the data stream. Anything written here is what a pipe receives.

It exists for the one command whose output is not a rendered entity — `fft auth token --raw`, which prints a bare token for a shell to capture. Everything else should render, not write.

func (*Printer) Render

func (p *Printer) Render(table Rows, data any) error

Render writes data in the printer's format: table from the view model, JSON and YAML from data.

Use it when fft owns the shape of the answer — `fft project list`, `fft ping`. For an entity that came off the API, use Printer.RenderRaw: a script wants the API's fields, not fft's summary of them.

func (*Printer) RenderDocument

func (p *Printer) RenderDocument(raw []byte) error

RenderDocument writes an API answer that fft has no view model for — what the Tier-2 and Tier-3 commands get back from the 451 operations nobody has curated.

There is no table here, and there deliberately is not going to be one: a table needs a hand-written view model, and an operation fft knows nothing about but its schema has none. So `-o table` prints JSON, which is the readable form of an arbitrary document. `-o yaml` is the same document in YAML.

This is not Printer.RenderRaw with a nil view model, because that would render an empty table and leave the user thinking the API said nothing.

func (*Printer) RenderRaw

func (p *Printer) RenderRaw(table Rows, raw []byte) error

RenderRaw writes the API's own JSON, byte for byte, under -o json.

raw must be the bytes the API sent (or an array assembled from them). It is re-indented and not re-encoded: every field survives, including the ones fft has no model for. -o yaml is the same document in YAML, and the table is the view model, because a raw entity has no readable table form.

func (*Printer) Style

func (p *Printer) Style() Style

Style paints text, or does not, according to --no-color, NO_COLOR and whether anything is watching.

func (*Printer) Warnf

func (p *Printer) Warnf(format string, args ...any)

Warnf reports something that may be wrong but is not fatal — a truncated result, a missing credential. Also stderr, and marked so it is not mistaken for output.

type Rows

type Rows struct {
	Headers []string
	Rows    [][]string
}

Rows is a rendered table: a header and its rows, already stringified.

A cell may carry colour, because [width] measures what a terminal will actually show rather than how many bytes it took to say it.

type Style

type Style struct {
	// contains filtered or unexported fields
}

Style paints text for a terminal.

A disabled Style returns its argument unchanged, so one call site produces a coloured table in a terminal and a byte-for-byte plain one under test — which is what makes a golden-file spec possible at all.

Every colour is built with its own *color.Color and forced on explicitly. fatih/color otherwise consults a package-level NoColor global that it initialises from os.Stdout: a value that is wrong for a Printer writing somewhere else, and a data race between two specs running in parallel.

func (Style) Bold

func (s Style) Bold(v string) string

Bold is for table headers.

func (Style) Faint

func (s Style) Faint(v string) string

Faint is for values a reader should skim past — an absent field, a hint.

func (Style) Green

func (s Style) Green(v string) string

Green, Yellow and Red carry meaning, not decoration: healthy, degraded, stopped. Choosing which is the caller's job, because what counts as healthy is the domain's business and not this package's.

func (Style) Red

func (s Style) Red(v string) string

func (Style) Yellow

func (s Style) Yellow(v string) string

Jump to

Keyboard shortcuts

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