Documentation Index Fetch the complete documentation index at: https://mintlify.com/raystack/salt/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Terminator provides utilities for detecting and interacting with terminal environments, including TTY detection, pager management, browser launching, and CI/CD environment detection.
Terminal Detection
IsTTY
Checks if the current output is a TTY (terminal) or Cygwin terminal.
True if running in a terminal environment, false if output is redirected or piped
Use Cases:
Disable colored output when piping to files
Disable interactive prompts in non-interactive environments
Adjust output formatting based on terminal capabilities
Example:
import " github.com/raystack/salt/cli/terminator "
if terminator . IsTTY () {
// Terminal output: use colors and spinners
spinner := printer . Spin ( "Loading" )
// ...
spinner . Stop ()
} else {
// Non-terminal: plain text output
fmt . Println ( "Loading..." )
}
IsColorDisabled
Checks if color output is disabled via the NO_COLOR environment variable.
func IsColorDisabled () bool
True if NO_COLOR environment variable is set, false otherwise
Example:
if terminator . IsColorDisabled () {
// Output plain text without ANSI color codes
fmt . Println ( "Status: OK" )
} else {
// Use colored output
printer . Successln ( "Status: OK" )
}
Environment Variable:
# Disable colors
export NO_COLOR = 1
# Enable colors (default)
unset NO_COLOR
IsCI
Checks if the code is running in a Continuous Integration environment.
True if running in a CI/CD environment, false otherwise
Detected CI Environments:
GitHub Actions
Travis CI
CircleCI
GitLab CI
Jenkins
TeamCity
AppVeyor
TaskCluster
And others (via standard CI environment variables)
Example:
if terminator . IsCI () {
// CI environment: disable interactive prompts
fmt . Println ( "Running in CI mode" )
useDefaults := true
} else {
// Local development: allow interactive prompts
prompter := prompter . New ()
confirmed , _ := prompter . Confirm ( "Continue?" , true )
}
Manage pager processes for paginated output (like less or more).
type Pager struct {
Out io . Writer // Output writer to pager
ErrOut io . Writer // Error output writer
// Private fields...
}
Creates a new Pager instance with default settings.
Configured Pager instance (uses PAGER env var or defaults to “more”)
Example:
pager := terminator . NewPager ()
Set
Updates the pager command.
func ( p * Pager ) Set ( cmd string )
Pager command (e.g., “less”, “more”, “cat”)
Example:
pager := terminator . NewPager ()
pager . Set ( "less -R" ) // Enable color support in less
Get
Returns the current pager command.
func ( p * Pager ) Get () string
Start
Starts the pager process to display output.
func ( p * Pager ) Start () error
Error if pager fails to start or command is invalid
Behavior:
Does nothing if pager command is “cat” or empty
Sets LESS=FRX environment variable if not already set
Sets LV=-c environment variable if not already set
Redirects output to pager’s stdin
Example:
pager := terminator . NewPager ()
if err := pager . Start (); err != nil {
log . Fatal ( err )
}
// Write to pager
fmt . Fprintln ( pager . Out , "Line 1" )
fmt . Fprintln ( pager . Out , "Line 2" )
// ... many more lines
// Clean up
pager . Stop ()
Stop
Terminates the running pager process and cleans up resources.
Example:
defer pager . Stop () // Ensure cleanup
// Use pager...
package main
import (
" fmt "
" log "
" github.com/raystack/salt/cli/terminator "
)
func main () {
// Create and start pager
pager := terminator . NewPager ()
if err := pager . Start (); err != nil {
log . Fatal ( err )
}
defer pager . Stop ()
// Generate long output
for i := 1 ; i <= 100 ; i ++ {
fmt . Fprintf ( pager . Out , "Line %d : Some content here \n " , i )
}
}
Error type returned when writing to a closed pager pipe (user quit pager).
type ErrClosedPagerPipe struct {
error
}
Handling:
_ , err := fmt . Fprintln ( pager . Out , "Content" )
if err != nil {
var closedPipe * terminator . ErrClosedPagerPipe
if errors . As ( err , & closedPipe ) {
// User closed pager, exit gracefully
return nil
}
return err
}
Browser Management
OpenBrowser
Opens the default web browser at a specified URL.
func OpenBrowser ( goos , url string ) * exec . Cmd
Operating system name (“darwin”, “windows”, “linux”)
URL to open in the browser
Configured command (must call Run() or Start() to execute)
Platform Commands:
macOS: open <url>
Windows: cmd /c start <url>
Linux: xdg-open <url> (or wslview for WSL)
Example:
import (
" runtime "
" github.com/raystack/salt/cli/terminator "
)
func openDocs () error {
url := "https://docs.example.com"
cmd := terminator . OpenBrowser ( runtime . GOOS , url )
return cmd . Start ()
}
With TTY Check:
if terminator . IsTTY () {
fmt . Println ( "Opening browser..." )
cmd := terminator . OpenBrowser ( runtime . GOOS , url )
if err := cmd . Start (); err != nil {
fmt . Printf ( "Failed to open browser: %v \n " , err )
fmt . Printf ( "Visit: %s \n " , url )
}
} else {
fmt . Printf ( "Visit: %s \n " , url )
}
Important: OpenBrowser will panic if called without a TTY. Always check with IsTTY() first.
Homebrew Detection
IsUnderHomebrew
Checks if a binary path is managed by Homebrew.
func IsUnderHomebrew ( path string ) bool
True if binary is in Homebrew’s bin directory, false otherwise
Example:
import " os "
exePath , _ := os . Executable ()
if terminator . IsUnderHomebrew ( exePath ) {
fmt . Println ( "Installed via Homebrew" )
fmt . Println ( "Update with: brew upgrade mycli" )
}
HasHomebrew
Checks if Homebrew is installed on the system.
True if Homebrew is available, false otherwise
Example:
if terminator . HasHomebrew () {
fmt . Println ( "Homebrew detected" )
fmt . Println ( "Install with: brew install mycli" )
} else {
fmt . Println ( "Download from: https://example.com/install" )
}
Best Practices
Check TTY Before Interactive Features
Always verify TTY before using interactive features: if terminator . IsTTY () {
// Use interactive features
spinner := printer . Spin ( "Loading" )
defer spinner . Stop ()
} else {
// Use simple output
fmt . Println ( "Loading..." )
}
Check color preferences before adding ANSI codes: useColor := terminator . IsTTY () && ! terminator . IsColorDisabled ()
if useColor {
printer . Successln ( "Done" )
} else {
fmt . Println ( "Done" )
}
Adjust behavior for CI/CD pipelines: if terminator . IsCI () {
// CI: Non-interactive, verbose output
fmt . Println ( "Step 1: Building..." )
fmt . Println ( "Step 2: Testing..." )
} else {
// Local: Interactive with progress bars
bar := printer . Progress ( 100 , "Building" )
// ...
}
Complete Example
package main
import (
" fmt "
" log "
" os "
" runtime "
" github.com/raystack/salt/cli/printer "
" github.com/raystack/salt/cli/prompter "
" github.com/raystack/salt/cli/terminator "
)
func main () {
// Detect environment
isTTY := terminator . IsTTY ()
isCI := terminator . IsCI ()
colorDisabled := terminator . IsColorDisabled ()
fmt . Printf ( "Environment: \n " )
fmt . Printf ( " TTY: %v \n " , isTTY )
fmt . Printf ( " CI: %v \n " , isCI )
fmt . Printf ( " Color: %v \n " , ! colorDisabled )
fmt . Println ()
// Adjust behavior based on environment
if isCI {
runCIMode ()
} else if isTTY {
runInteractiveMode ()
} else {
runBatchMode ()
}
// Show docs option
if isTTY {
showDocsOption ()
}
}
func runCIMode () {
fmt . Println ( "Running in CI mode..." )
fmt . Println ( "Using default configuration" )
// Non-interactive execution
}
func runInteractiveMode () {
fmt . Println ( "Running in interactive mode..." )
p := prompter . New ()
confirmed , err := p . Confirm ( "Continue?" , true )
if err != nil || ! confirmed {
fmt . Println ( "Cancelled" )
return
}
// Show progress
spinner := printer . Spin ( "Processing" )
// ... do work
spinner . Stop ()
printer . Successln ( "Complete" )
}
func runBatchMode () {
fmt . Println ( "Running in batch mode..." )
fmt . Println ( "Output can be piped or redirected" )
// Simple text output
}
func showDocsOption () {
p := prompter . New ()
openDocs , err := p . Confirm ( "Open documentation?" , false )
if err != nil || ! openDocs {
return
}
url := "https://docs.example.com"
cmd := terminator . OpenBrowser ( runtime . GOOS , url )
if err := cmd . Start (); err != nil {
fmt . Printf ( "Failed to open browser: %v \n " , err )
fmt . Printf ( "Visit: %s \n " , url )
}
}