output

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: May 23, 2026 License: MIT Imports: 11 Imported by: 0

README

CLI Output Package

This package provides comprehensive CLI output formatting capabilities for UniRTM, including progress indicators, JSON output, and color-coded human-readable output.

Features

  • Multiple Output Formats: Human-readable (with colors) and JSON (for scripting)
  • Progress Indicators: Visual progress bars for long-running operations
  • Color Support: Automatic color detection with NO_COLOR support
  • Structured Output: Tables, key-value pairs, and structured data
  • Global Formatter: Thread-safe global formatter for consistent output

Usage

Basic Output
import "github.com/snowdreamtech/unirtm/internal/cli/output"

// Using global formatter
output.Info("Starting installation")
output.Success("Installation completed")
output.Warning("Configuration file not found, using defaults")
output.Error("Failed to connect to backend")

// With structured fields
output.Info("Tool installed", map[string]interface{}{
    "tool":    "node",
    "version": "20.0.0",
    "path":    "/usr/local/bin/node",
})
Creating a Formatter
// Human-readable formatter
formatter := output.NewFormatter(output.FormatterOptions{
    Format:  output.FormatHuman,
    NoColor: false,
    Verbose: true,
})

// JSON formatter for scripting
jsonFormatter := output.NewFormatter(output.FormatterOptions{
    Format: output.FormatJSON,
})

// Set as global formatter
output.SetGlobalFormatter(formatter)
Progress Indicators
// Create progress indicator
progress := output.NewProgressIndicator(output.ProgressOptions{
    Message:        "Downloading node-v20.0.0.tar.gz",
    ShowPercentage: true,
    ShowBytes:      true,
    ShowSpeed:      true,
})

// Start progress
progress.Start()

// Update progress
for downloaded := int64(0); downloaded < total; downloaded += chunkSize {
    progress.Update(downloaded, total)
}

// Finish successfully
progress.Finish()

// Or mark as failed
// progress.Fail(err)
Table Output
headers := []string{"Tool", "Version", "Status"}
rows := [][]string{
    {"node", "20.0.0", "installed"},
    {"python", "3.11.0", "installed"},
    {"go", "1.21.0", "not installed"},
}

output.Table(headers, rows)
Structured Data
data := map[string]interface{}{
    "tool":         "node",
    "version":      "20.0.0",
    "install_path": "/usr/local/bin/node",
    "installed_at": time.Now(),
}

output.Data(data)

Integration with CLI Commands

Setting Up Formatter Based on Flags
func setupFormatter(jsonOutput, noColor, quiet, verbose bool) {
    format := output.FormatHuman
    if jsonOutput {
        format = output.FormatJSON
    }

    formatter := output.NewFormatter(output.FormatterOptions{
        Format:  format,
        NoColor: noColor || !output.IsColorSupported(),
        Quiet:   quiet,
        Verbose: verbose,
    })

    output.SetGlobalFormatter(formatter)
}
Using in Commands
func installCommand(cmd *cobra.Command, args []string) error {
    tool := args[0]
    version := args[1]

    output.Info("Installing tool", map[string]interface{}{
        "tool":    tool,
        "version": version,
    })

    // Create progress indicator
    progress := output.NewProgressIndicator(output.ProgressOptions{
        Message:        fmt.Sprintf("Downloading %s@%s", tool, version),
        ShowPercentage: true,
        ShowBytes:      true,
        ShowSpeed:      true,
    })

    progress.Start()

    // Perform installation with progress updates
    err := installTool(tool, version, progress)
    if err != nil {
        progress.Fail(err)
        output.Error("Installation failed", map[string]interface{}{
            "tool":    tool,
            "version": version,
            "error":   err.Error(),
        })
        return err
    }

    progress.Finish()
    output.Success("Installation completed", map[string]interface{}{
        "tool":    tool,
        "version": version,
    })

    return nil
}

Output Formats

Human Format

Human-readable output with colors and symbols:

ℹ Starting installation tool=node version=20.0.0
Downloading node-v20.0.0.tar.gz [████████████████████░░░░░░░░] 75.0% 7.5 MB / 10.0 MB 1.2 MB/s
✓ Installation completed tool=node version=20.0.0
JSON Format

Structured JSON output for scripting:

{
  "timestamp": "2024-01-15T10:30:00Z",
  "level": "info",
  "message": "Starting installation",
  "fields": {
    "tool": "node",
    "version": "20.0.0"
  }
}
{
  "timestamp": "2024-01-15T10:30:15Z",
  "level": "success",
  "message": "Installation completed",
  "fields": {
    "tool": "node",
    "version": "20.0.0"
  }
}

Color Support

The package automatically detects color support:

  • Respects NO_COLOR environment variable
  • Checks TERM environment variable
  • Detects if stdout is a terminal
  • Can be explicitly disabled with NoColor option

Thread Safety

The global formatter is thread-safe and can be safely accessed from multiple goroutines:

// Safe to call from multiple goroutines
go func() {
    output.Info("Background task started")
}()

go func() {
    output.Success("Background task completed")
}()

Testing

The package includes comprehensive unit tests:

go test ./internal/cli/output/...

Run tests with coverage:

go test -cover ./internal/cli/output/...

Requirements Satisfied

This implementation satisfies the following requirements:

  • Requirement 23.5: Progress indicators for long-running operations (downloads, installations)
  • Requirement 23.6: JSON output format (--json flag) and color-coded output

Design Principles

  1. Separation of Concerns: Formatters are independent and can be easily extended
  2. Flexibility: Support for multiple output formats and customization options
  3. User Experience: Clear, informative output with visual feedback
  4. Automation-Friendly: JSON output for scripting and CI/CD integration
  5. Performance: Efficient rendering with minimal overhead
  6. Accessibility: Respects user preferences (NO_COLOR, quiet mode)

Documentation

Overview

Package output provides CLI output formatting capabilities including progress indicators, JSON output, and color-coded output.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Data

func Data(data interface{})

Data outputs structured data using the global formatter

func Error

func Error(message string, fields ...map[string]interface{})

Error outputs an error message using the global formatter

func Info

func Info(message string, fields ...map[string]interface{})

Info outputs an informational message using the global formatter

func IsColorSupported

func IsColorSupported() bool

IsColorSupported checks if the terminal supports color output

Example

ExampleIsColorSupported demonstrates checking color support

package main

import (
	"fmt"

	"github.com/snowdreamtech/unirtm/internal/cli/output"
)

func main() {
	if output.IsColorSupported() {
		fmt.Println("Terminal supports colors")
	} else {
		fmt.Println("Terminal does not support colors")
	}
}

func SetGlobalFormatter

func SetGlobalFormatter(formatter Formatter)

SetGlobalFormatter sets the global formatter instance

Example

ExampleSetGlobalFormatter demonstrates using the global formatter

package main

import (
	"github.com/snowdreamtech/unirtm/internal/cli/output"
)

func main() {
	// Set up global formatter
	formatter := output.NewFormatter(output.FormatterOptions{
		Format:  output.FormatHuman,
		NoColor: true,
	})
	output.SetGlobalFormatter(formatter)

	// Use global formatter functions
	output.Info("Starting operation")
	output.Success("Operation completed")
	output.Warning("Potential issue detected")
	output.Error("Operation failed")
}

func Success

func Success(message string, fields ...map[string]interface{})

Success outputs a success message using the global formatter

func Suggest

func Suggest(w io.Writer, target string, candidates []string)

Suggest prints fuzzy suggestions for a target string from a list of candidates.

func Table

func Table(headers []string, rows [][]string)

Table outputs tabular data using the global formatter

func Warning

func Warning(message string, fields ...map[string]interface{})

Warning outputs a warning message using the global formatter

Types

type DataOutput

type DataOutput struct {
	Timestamp string      `json:"timestamp"`
	Data      interface{} `json:"data"`
}

DataOutput represents structured data output

type Formatter

type Formatter interface {
	// Info outputs an informational message
	Info(message string, fields ...map[string]interface{})

	// Success outputs a success message
	Success(message string, fields ...map[string]interface{})

	// Warning outputs a warning message
	Warning(message string, fields ...map[string]interface{})

	// Error outputs an error message
	Error(message string, fields ...map[string]interface{})

	// Data outputs structured data
	Data(data interface{})

	// Table outputs tabular data
	Table(headers []string, rows [][]string)

	// SetWriter sets the output writer
	SetWriter(w io.Writer)
}

Formatter defines the interface for output formatting

func DefaultFormatter

func DefaultFormatter() Formatter

DefaultFormatter returns a formatter with default settings

func GetGlobalFormatter

func GetGlobalFormatter() Formatter

GetGlobalFormatter returns the global formatter instance If no formatter has been set, it returns a default human formatter

func NewFormatter

func NewFormatter(opts FormatterOptions) Formatter

NewFormatter creates a new formatter based on the specified options

Example

ExampleNewFormatter demonstrates creating different formatter types

package main

import (
	"github.com/snowdreamtech/unirtm/internal/cli/output"
)

func main() {
	// Create a human-readable formatter
	humanFormatter := output.NewFormatter(output.FormatterOptions{
		Format:  output.FormatHuman,
		NoColor: true, // Disable colors for example output
	})

	humanFormatter.Info("Starting installation")
	humanFormatter.Success("Installation completed")

	// Create a JSON formatter
	jsonFormatter := output.NewFormatter(output.FormatterOptions{
		Format: output.FormatJSON,
	})

	jsonFormatter.Info("Starting installation")
	// Output will be JSON formatted
}

type FormatterOptions

type FormatterOptions struct {
	// Format specifies the output format (human or json)
	Format OutputFormat

	// NoColor disables color output for human format
	NoColor bool

	// Color specifies the color mode (auto, always, never)
	Color string

	// Writer is the output writer (defaults to os.Stdout)
	Writer io.Writer

	// Quiet suppresses non-essential output
	Quiet bool

	// Verbose enables verbose output
	Verbose bool
}

FormatterOptions contains options for creating a formatter

type HumanFormatter

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

HumanFormatter implements human-readable output with color support

func (*HumanFormatter) Data

func (h *HumanFormatter) Data(data interface{})

Data outputs structured data in a human-readable format

func (*HumanFormatter) Error

func (h *HumanFormatter) Error(message string, fields ...map[string]interface{})

Error outputs an error message

func (*HumanFormatter) GetLogLevel

func (h *HumanFormatter) GetLogLevel() zerolog.Level

GetLogLevel returns the appropriate zerolog level based on formatter settings

func (*HumanFormatter) Info

func (h *HumanFormatter) Info(message string, fields ...map[string]interface{})

Info outputs an informational message

func (*HumanFormatter) IsColorEnabled

func (h *HumanFormatter) IsColorEnabled() bool

IsColorEnabled returns true if color output is enabled

func (*HumanFormatter) SetColorEnabled

func (h *HumanFormatter) SetColorEnabled(enabled bool)

SetColorEnabled enables or disables color output

func (*HumanFormatter) SetQuiet

func (h *HumanFormatter) SetQuiet(quiet bool)

SetQuiet enables or disables quiet mode

func (*HumanFormatter) SetVerbose

func (h *HumanFormatter) SetVerbose(verbose bool)

SetVerbose enables or disables verbose mode

func (*HumanFormatter) SetWriter

func (h *HumanFormatter) SetWriter(w io.Writer)

SetWriter sets the output writer

func (*HumanFormatter) Success

func (h *HumanFormatter) Success(message string, fields ...map[string]interface{})

Success outputs a success message

func (*HumanFormatter) Table

func (h *HumanFormatter) Table(headers []string, rows [][]string)

Table outputs tabular data

func (*HumanFormatter) Warning

func (h *HumanFormatter) Warning(message string, fields ...map[string]interface{})

Warning outputs a warning message

type JSONFormatter

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

JSONFormatter implements JSON output for scripting and automation

Example

ExampleJSONFormatter demonstrates JSON output format

package main

import (
	"github.com/snowdreamtech/unirtm/internal/cli/output"
)

func main() {
	formatter := output.NewFormatter(output.FormatterOptions{
		Format: output.FormatJSON,
	})

	formatter.Info("Starting installation", map[string]interface{}{
		"tool":    "node",
		"version": "20.0.0",
	})

	formatter.Success("Installation completed", map[string]interface{}{
		"tool":         "node",
		"version":      "20.0.0",
		"install_path": "/usr/local/bin/node",
	})

	// Output will be JSON formatted with timestamps
}

func (*JSONFormatter) Data

func (j *JSONFormatter) Data(data interface{})

Data outputs structured data in JSON format

func (*JSONFormatter) Error

func (j *JSONFormatter) Error(message string, fields ...map[string]interface{})

Error outputs an error message in JSON format

func (*JSONFormatter) Info

func (j *JSONFormatter) Info(message string, fields ...map[string]interface{})

Info outputs an informational message in JSON format

func (*JSONFormatter) SetQuiet

func (j *JSONFormatter) SetQuiet(quiet bool)

SetQuiet enables or disables quiet mode

func (*JSONFormatter) SetWriter

func (j *JSONFormatter) SetWriter(w io.Writer)

SetWriter sets the output writer

func (*JSONFormatter) Success

func (j *JSONFormatter) Success(message string, fields ...map[string]interface{})

Success outputs a success message in JSON format

func (*JSONFormatter) Table

func (j *JSONFormatter) Table(headers []string, rows [][]string)

Table outputs tabular data in JSON format

func (*JSONFormatter) Warning

func (j *JSONFormatter) Warning(message string, fields ...map[string]interface{})

Warning outputs a warning message in JSON format

type NoOpProgressIndicator

type NoOpProgressIndicator struct{}

NoOpProgressIndicator is a progress indicator that does nothing

Example

ExampleNoOpProgressIndicator demonstrates a no-op progress indicator

package main

import (
	"github.com/snowdreamtech/unirtm/internal/cli/output"
)

func main() {
	// Useful for testing or when progress output is not desired
	progress := output.NewNoOpProgressIndicator()

	progress.Start()
	progress.Update(50, 100)
	progress.Finish()

	// No output is produced
}

func (*NoOpProgressIndicator) Fail

func (n *NoOpProgressIndicator) Fail(err error)

Fail does nothing

func (*NoOpProgressIndicator) Finish

func (n *NoOpProgressIndicator) Finish()

Finish does nothing

func (*NoOpProgressIndicator) SetMessage

func (n *NoOpProgressIndicator) SetMessage(message string)

SetMessage does nothing

func (*NoOpProgressIndicator) Start

func (n *NoOpProgressIndicator) Start()

Start does nothing

func (*NoOpProgressIndicator) Update

func (n *NoOpProgressIndicator) Update(current, total int64)

Update does nothing

type OutputFormat

type OutputFormat string

OutputFormat represents the output format type

const (
	// FormatHuman is the human-readable output format with colors
	FormatHuman OutputFormat = "human"
	// FormatJSON is the JSON output format for scripting
	FormatJSON OutputFormat = "json"
)

type OutputMessage

type OutputMessage struct {
	Timestamp string                 `json:"timestamp"`
	Level     string                 `json:"level"`
	Message   string                 `json:"message"`
	Fields    map[string]interface{} `json:"fields,omitempty"`
}

OutputMessage represents a JSON output message

type ProgressIndicator

type ProgressIndicator interface {
	// Start starts the progress indicator
	Start()

	// Update updates the progress with current and total values
	Update(current, total int64)

	// SetMessage sets the progress message
	SetMessage(message string)

	// Finish completes the progress indicator
	Finish()

	// Fail marks the progress as failed
	Fail(err error)
}

ProgressIndicator represents a progress indicator for long-running operations

func NewNoOpProgressIndicator

func NewNoOpProgressIndicator() ProgressIndicator

NewNoOpProgressIndicator creates a no-op progress indicator

func NewProgressIndicator

func NewProgressIndicator(opts ProgressOptions) ProgressIndicator

NewProgressIndicator creates a new progress indicator

Example

ExampleNewProgressIndicator demonstrates creating and using a progress indicator

package main

import (
	"time"

	"github.com/snowdreamtech/unirtm/internal/cli/output"
)

func main() {
	progress := output.NewProgressIndicator(output.ProgressOptions{
		Message:        "Downloading node-v20.0.0.tar.gz",
		ShowPercentage: true,
		ShowBytes:      true,
		ShowSpeed:      true,
		NoColor:        true,
	})

	progress.Start()

	// Simulate download progress
	total := int64(10 * 1024 * 1024) // 10 MB
	for downloaded := int64(0); downloaded < total; downloaded += 1024 * 1024 {
		progress.Update(downloaded, total)
		time.Sleep(100 * time.Millisecond)
	}

	progress.Finish()
}

type ProgressOptions

type ProgressOptions struct {
	// Writer is the output writer (defaults to os.Stderr)
	Writer io.Writer

	// Message is the initial progress message
	Message string

	// ShowPercentage shows percentage completion
	ShowPercentage bool

	// ShowBytes shows byte counts (for downloads)
	ShowBytes bool

	// ShowSpeed shows transfer speed (for downloads)
	ShowSpeed bool

	// Width is the progress bar width in characters
	Width int

	// NoColor disables color output
	NoColor bool

	// Quiet suppresses progress output
	Quiet bool
}

ProgressOptions contains options for creating a progress indicator

type TableOutput

type TableOutput struct {
	Timestamp string     `json:"timestamp"`
	Headers   []string   `json:"headers"`
	Rows      [][]string `json:"rows"`
}

TableOutput represents tabular data output

Jump to

Keyboard shortcuts

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