Skip to content

output

Structured, themeable output formatting for CLI tools.

output gives a command-line tool one configured Renderer that speaks both languages a CLI needs at once: human-readable text for a terminal and machine-readable JSON/YAML for a pipeline. It also provides tables, spinners, progress bars and live status lines. When stdout is not a terminal, or CI is true, the animated pieces print plain lines instead.

r := output.New(output.WithWriter(os.Stdout), output.WithFormat(format))

_ = r.Write(result, func(w io.Writer) {
    fmt.Fprintf(w, "%s is up to date (%s)\n", result.Name, result.Version)
})

Highlights

  • Configure once, render anywhere. The writer, format, theme and interactivity are fixed on the Renderer; every method reads them, so you can test against a bytes.Buffer. The one thing measured from the process is terminal geometry: table width and Markdown styling.
  • One façade, six formats. Write, Table, Render, Emit/EmitError, Status, Progress and Spin share the same configured destination. The data methods share its format too; the progress helpers ignore it.
  • Unicode-correct. Widths and truncation use display width, so CJK, emoji and combining characters never corrupt a table or a status line.
  • Framework-free core. Importing output never pulls cobra or pflag; the cobra wiring is the opt-in output/cobra subpackage.

Where next


Part of the phpboyscout Go toolkit: small, framework-free Go modules extracted from go-tool-base.

Further reading

The blog carries a curated route through this subject: Building a command-line tool in Go collects everything written about it, ordered so you can start at the beginning rather than newest-first.

Ask phpbotscout

phpbotscout

He answers questions about the projects over on the Discord, citing the docs where they already cover it, and offering to raise an issue where they don't. Bring a bug, an idea, or a questionable engineering decision.

Join the Discord