cli/cli
IOStreams
Active contributors: Mislav, Andy Feller, vilmibm
Purpose
pkg/iostreams abstracts everything terminal-related: stdin/stdout/stderr handles, ANSI color, the pager subprocess, spinners, progress indicators, terminal width detection, accessibility-aware rendering, and TTY status. It exists so that command code never has to call os.Stdout directly and so tests can swap in bytes.Buffers with the same shape.
Directory layout
pkg/iostreams/
iostreams.go # IOStreams struct and constructors
color.go # Color helpers (ColorEnabled, NewColorScheme, ...)
console.go # POSIX TTY check
console_windows.go # Windows-specific TTY + ANSI support
epipe_other.go / epipe_windows.go # SIGPIPE handling per platformKey abstractions
| Symbol | File | Role |
|---|---|---|
IOStreams |
iostreams.go |
The struct passed everywhere via Factory.IOStreams. |
System |
iostreams.go |
Returns an IOStreams wired to real stdin/stdout/stderr. |
Test |
iostreams.go |
Returns an IOStreams plus three *bytes.Buffer pointers for assertions. |
IsStdoutTTY / IsStdinTTY / IsStderrTTY |
iostreams.go |
TTY queries. Tests set them via SetStdoutTTY etc. |
ColorEnabled |
color.go |
Honours NO_COLOR, CLICOLOR, accessibility settings, and TTY status. |
ColorScheme |
color.go |
Project-specific palette (ColorScheme.Yellow, Bold, Red, ...). |
StartProgressIndicator / StopProgressIndicator |
iostreams.go |
Wraps briandowns/spinner. |
StartPager / StopPager |
iostreams.go |
Pipes output to the configured pager. |
TerminalWidth |
iostreams.go |
Width detection (golang.org/x/term). |
How it works
IOStreams is created in internal/ghcmd/cmd.go (newIOStreams), which reads the user's pager, prompt_disabled, and accessible settings out of the config to populate the streams. From there it travels to every command via the factory.
ColorEnabled rules of precedence:
NO_COLOR=1-> false.CLICOLOR_FORCE=1-> true.CLICOLOR=0-> false.- Accessibility setting from config -> false if "screen-reader".
- Falls back to
IsStdoutTTY().
Pager handling:
graph TD
A[command writes to opts.IO.Out] --> B{Pager configured?}
B -->|yes & TTY| C[StartPager replaces Out with a pipe]
C --> D[child process: less -FRX]
A -->|after run| E[StopPager waits for child]
B -->|no or non-TTY| F[Out stays as os.Stdout]Integration points
- Created by
internal/ghcmd/newIOStreamsand held on the factory. - Consumed by virtually every command and shared subsystem (table printer, markdown renderer, progress indicators).
- Tests use
iostreams.Test()and assert on the returned buffers; assertions on rendered output are common inpkg/cmd/*/list_test.gofiles.
Entry points for modification
- New color or icon: add to
ColorSchemeincolor.go. Avoid scattering ANSI escapes through commands. - New rendering mode (e.g. minimal-noise mode for AI agents): extend the construction in
newIOStreamsand gate behind a config key. - Pager change: edit
StartPager. Be careful with Windows behaviour; the platform-specific files exist for a reason.
Key source files
| File | Purpose |
|---|---|
pkg/iostreams/iostreams.go |
Streams, pager, spinner. |
pkg/iostreams/color.go |
Color enable/disable rules. |
pkg/iostreams/console.go / console_windows.go |
TTY detection. |
internal/ghcmd/cmd.go (newIOStreams) |
Construction with config-derived options. |
Related pages
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.