output

package
v0.31.0 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package output renders command results as human-readable text or JSON. Commands build explicit DTOs for their output — never genqlient-generated structs — so the --json contract stays stable across schema regenerations.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Dash added in v0.6.0

func Dash(s *string) string

Dash renders an optional string cell: the value, or an em-dash placeholder when the pointer is nil or empty. Keeps "no value" columns consistent across the table-rendering commands.

func SafeCell added in v0.29.0

func SafeCell(s string) string

SafeCell makes a server-supplied string safe to print as one table cell (#1065). Every control character (C0, C1, DEL, ESC, tab, CR, LF) and every Unicode format or line/paragraph separator (Cf, Zl, Zp: bidi overrides, zero-width characters, BOM, U+2028/2029) becomes a single space, so a value can neither forge a row nor recolor or reorder the terminal. Ordinary Unicode passes unchanged. The text is cut by rune at cellMaxRunes, which can split a combining sequence. ZWJ (U+200D) is Cf, so a ZWJ emoji sequence renders as separate emoji; that is the accepted cost of the stricter rule.

Text mode only: --json carries the original value. Other commands' tables are unchanged (roster, automation and member keep their own guards).

func Tracked added in v0.14.0

func Tracked(w io.Writer) io.Writer

Tracked wraps w so an IOStreams built around it can answer Wrote(). Exported so a test factory can give commands the same stdout they get in production — an untracked stream always reports "clean", which would let a test pass on a path the binary handles differently (review:a-test-double-must-satisfy-the-real-access-pattern).

func Write

func Write(s *IOStreams, asJSON bool, v any, table func(w io.Writer) error) error

Write renders v as indented JSON when asJSON is set, otherwise calls table to render the human view.

func WriteJSON

func WriteJSON(w io.Writer, v any) error

WriteJSON marshals v as indented JSON followed by a newline.

Types

type IOStreams

type IOStreams struct {
	In     io.Reader
	Out    io.Writer
	ErrOut io.Writer
	// contains filtered or unexported fields
}

IOStreams bundles the CLI's input/output handles so commands never touch os.Stdin/Stdout directly, keeping them testable.

func System

func System() *IOStreams

System returns IOStreams wired to the real process streams.

func Test

func Test() (*IOStreams, *bytes.Buffer, *bytes.Buffer)

Test returns IOStreams backed by buffers, plus the stdout and stderr buffers for assertions.

func TestTTY added in v0.13.0

func TestTTY(answers string) (*IOStreams, *bytes.Buffer, *bytes.Buffer)

TestTTY returns IOStreams whose stdin is an answerable terminal (#525), with `answers` standing in for what a person types — one line per prompt, in order. Stdout is left non-terminal. Returns the stdout and stderr buffers; a prompt renders on stderr.

Why it exists: cmdutil.Confirm and ConfirmDeletion refuse as non-interactive BEFORE composing their prompt, and Test() has no way to say otherwise, so every confirmation in the CLI was beyond the reach of a command-level test — a door with no handle that each new confirmation inherits.

Three properties, each load-bearing:

  • The answers are a CONSTRUCTOR argument, not a field set afterwards. Test()'s In is an empty buffer, so flipping the TTY bit alone makes scanner.Scan() return false and Confirm returns Cancelled — a different unreachable branch, indistinguishable from a person answering "no". A seam that can be half-used yields a green test proving nothing.
  • One line PER READ, via lineReader rather than strings.NewReader. See lineReader for why; a command that prompts twice is the case.
  • Stdout stays non-terminal. Confirm reads stdin only, and interactive stdin with redirected stdout is a real process state (`hadron … | less`), so this is an honest configuration rather than a test-only shape. Widen it when something needs the stdout branch, not before.

func (*IOStreams) IsInputTerminal

func (s *IOStreams) IsInputTerminal() bool

IsInputTerminal reports whether stdin is a TTY (i.e. a prompt can actually be answered).

func (*IOStreams) IsTerminal

func (s *IOStreams) IsTerminal() bool

IsTerminal reports whether stdout is a TTY.

func (*IOStreams) Wrote added in v0.14.0

func (s *IOStreams) Wrote() bool

Wrote reports whether anything has been written to stdout yet.

FALSE for an untracked stream, deliberately: "nothing has been written" is the state in which the envelope goes to stdout, which is the behaviour this change is for. A stream nobody wrapped therefore degrades to the new behaviour rather than silently keeping the old one.

type Table

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

Table is a thin tabwriter wrapper for aligned columnar output.

func NewTable

func NewTable(w io.Writer, headers ...string) *Table

func (*Table) Flush

func (t *Table) Flush() error

func (*Table) Row

func (t *Table) Row(cells ...string)

Jump to

Keyboard shortcuts

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