Framework-free core, opt-in cobra¶
output is a member of the phpboyscout Go toolkit:
small modules that carry no framework weight, so any project can adopt one without
inheriting a CLI framework, a config system, or a cloud SDK. For an output
formatter that principle has a specific edge: it must not force cobra on its
importers.
The tension¶
The predecessor package's JSON-envelope helpers took a *cobra.Command:
…but they only used two things off the command: the --output flag value and
cmd.OutOrStdout(). Neither needs cobra — or even pflag. Taking the whole command
coupled the entire package to spf13, so anyone importing it for a table dragged
in a CLI framework.
The resolution: plain parameters, opt-in sugar¶
The core takes no flag library at all. Output goes to an io.Writer; the format is
a plain Format. Both are configured on the Renderer:
That makes the core usable by anything — a cobra CLI, a urfave/cli app, a raw HTTP handler, a test — and if a tool ever swaps its CLI framework, the core never changes.
The convenience of pulling (writer, format) off a *cobra.Command still exists,
but as an opt-in subpackage, output/cobra:
cobra appears in the module's go.mod, but Go's package-level dead-code
elimination means it is never linked into a binary that does not import the
subpackage.
Guarded, not just intended¶
A depfootprint_test.go asserts that the root package's dependency graph
(go list -deps .) contains no cobra, no pflag, no Viper, no OpenTelemetry, no
cloud SDK, and no go-tool-base. The cobra subpackage legitimately imports cobra and
is excluded from that assertion. The promise "importing output stays
framework-free" is therefore enforced by CI, not left to discipline.
What the core does depend on¶
The interactive renderers (spinner, styled status) genuinely need the Charm stack —
lipgloss, glamour, bubbles/bubbletea — and charmbracelet/x/ansi for
Unicode-correct widths. Those are intrinsic to what the module is (a terminal
output formatter), plus cockroachdb/errors, yaml, and the standard library.
That is the whole graph.