Skip to content

Getting started

Install

go get gitlab.com/phpboyscout/go/output

Requires the Go version on the go line of the module's go.mod. 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. The cobra guide 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