Getting started¶
Install¶
Requires Go 1.26.5 or newer — that is the version declared in the module's
go.mod, so an older toolchain refuses to build it.
The cobra binding lives in the output/cobra subpackage and is fetched by the
same go get. cobra therefore appears in your module graph, but Go links only
the packages you import, so a binary that never imports the subpackage never
contains cobra — see
framework-free core.
The Renderer¶
Everything starts with a Renderer, built once from options and reused. It holds
four things: a destination writer, an output format, a
theme, and whether output is interactive.
import "gitlab.com/phpboyscout/go/output"
r := output.New(
output.WithWriter(os.Stdout), // default: os.Stderr
output.WithFormat(output.FormatText), // default: text
// output.WithTheme(myTheme), // default: DefaultTheme()
// output.WithInteractive(true), // default: auto-detected
)
If you do not call WithInteractive, the renderer auto-detects: interactive when
stdout is a TTY and CI is not set to true. Interactive renderers animate;
non-interactive ones print plain lines — the same code path works in a terminal
and under CI.
Writing data¶
Write is format-aware. You supply the data and a function that renders the
human-readable form; the renderer decides which to use:
type Result struct {
Name string `json:"name" table:"Name,sortable"`
Version string `json:"version" table:"Version"`
}
r := output.New(output.WithWriter(os.Stdout), output.WithFormat(format))
_ = r.Write(res, func(w io.Writer) {
fmt.Fprintf(w, "%s %s\n", res.Name, res.Version)
})
| Configured format | What Write does |
|---|---|
text |
calls your textFunc |
json / yaml |
marshals data directly |
csv / tsv / markdown |
renders data as a table (needs a slice) |
Write calls Table with no options on that last row, so column definitions
and sorting are not available through it — call Table directly when you need
them. The full matrix is in
behaviour by format.
Formats¶
The supported set is text, json, yaml, csv, tsv, markdown.
output.Formats() // the canonical slice, stable order
f, ok := output.ParseFormat(s) // case-insensitive; ok=false → falls back to FormatText
ParseFormat lower-cases its input, so JSON, Json and json all parse to
FormatJSON. An empty or unrecognised string returns (FormatText, false) — it
never errors, so a typo silently produces text output unless you check ok.
Formats() is exactly the value set a CLI's --output flag should accept — see
the cobra guide, which wires it up for you.
Your first table¶
rows := []Result{
{Name: "alpha", Version: "1.2.0"},
{Name: "beta", Version: "0.9.1"},
}
r := output.New(output.WithWriter(os.Stdout), output.WithFormat(output.FormatText))
_ = r.Table(rows, output.WithSortBy("Name"))
Columns come from the table:"Header,sortable" struct tags, or pass
output.WithColumns(...) explicitly (required for []map[string]any). More in
Render a table.
Next¶
- Build a CLI that speaks text and JSON — a full guided lesson from an empty directory to a working tool.
- Emit JSON for scripting · Show progress and spinners
- Formats & options reference — the complete surface at a glance.
- Behaviour by format — what each method does in each format, and which options are ignored where.
- What this does not do — the boundaries, before you go looking for an option that is not there.
- The Renderer façade — why it is shaped this way.