Documentation
¶
Overview ¶
Package notify provides utilities for sending formatted notifications to CLI users.
This package includes:
- WriteMessage for displaying formatted messages with type-specific symbols and colors
- ProgressGroup for parallel task execution with live progress indicators
- StageSeparatingWriter for automatic blank line insertion between CLI stages
Message types include success (✔), error (✗), warning (⚠), info (ℹ), activity (►), generate (✚), and title messages with customizable emojis.
The StageSeparatingWriter wraps an io.Writer and automatically detects stage titles (lines starting with emojis) to insert visual separation between workflow stages.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func WriteMessage ¶
func WriteMessage(msg Message)
WriteMessage writes a formatted message based on the message configuration. It handles message styling, optional timing information, and proper output formatting.
Note: Leading newlines between stages are handled automatically by StageSeparatingWriter. Wrap the output writer with NewStageSeparatingWriter() in command handlers to enable automatic stage separation.
Types ¶
type Message ¶
type Message struct {
// Type determines the message styling (color, symbol).
Type MessageType
// Content is the main message text to display.
Content string
// Timer is optional. If provided and the message type is SuccessType,
// timing information will be printed in a separate block after the message.
Timer timer.Timer
// Emoji is used only for TitleType messages to customize the title icon.
Emoji string
// Writer is the output destination. If nil, defaults to os.Stdout.
Writer io.Writer
// Args are format arguments for Content if it contains format specifiers.
Args []any
}
Message represents a notification message to be displayed to the user.
type MessageType ¶
type MessageType int
MessageType defines the type of notification message.
const ( // ErrorType represents an error message (red, with ✗ symbol). ErrorType MessageType = iota // WarningType represents a warning message (yellow, with ⚠ symbol). WarningType // ActivityType represents an activity/progress message (default color, with ► symbol). ActivityType // GenerateType represents a file generation message (default color, with ✚ symbol). GenerateType // SuccessType represents a success message (green, with ✔ symbol). SuccessType // InfoType represents an informational message (blue, with ℹ symbol). InfoType // TitleType represents a title/header message (bold, with emoji (custom or default)). TitleType )
Message type constants. Each type determines the message styling (color and symbol).
type ProgressGroup ¶
type ProgressGroup struct {
// contains filtered or unexported fields
}
ProgressGroup manages parallel execution of tasks with synchronized progress output. It shows a title line followed by a line per task with live spinner updates. Tasks are ordered by start time, with pending tasks shown at the bottom.
In TTY environments (interactive terminals), it uses ANSI escape codes to update lines in place with animated spinners.
In non-TTY environments (CI, pipes), it uses a simpler output that only prints state changes (started, completed, failed) to avoid log spam.
Example TTY output during execution (with InstallingLabels):
📦 Installing components... ⠦ metrics-server installing ⠦ flux installing ○ argocd pending
Example TTY output during validation (with ValidatingLabels):
✅ Validating kustomizations... ⠦ apps validating ✔ base validated ○ cluster pending
Example CI output:
📦 Installing components... ► metrics-server started ► flux started ✔ flux installed ✔ metrics-server installed
func NewProgressGroup ¶
func NewProgressGroup( title, emoji string, writer io.Writer, opts ...ProgressOption, ) *ProgressGroup
NewProgressGroup creates a new ProgressGroup for parallel task execution. title: The title shown during execution (e.g., "Installing components") emoji: Optional emoji for the title (defaults to ►) writer: Output writer (defaults to os.Stdout if nil) opts: Optional configuration options (WithLabels, WithTimer).
func (*ProgressGroup) Run ¶
func (pg *ProgressGroup) Run(ctx context.Context, tasks ...ProgressTask) error
Run executes all tasks in parallel with live progress updates. Returns an error if any task fails.
type ProgressLabels ¶
type ProgressLabels struct {
// Pending is shown for tasks that haven't started yet (default: "pending").
Pending string
// Running is shown for tasks currently executing (default: "running").
Running string
// Completed is shown for tasks that finished successfully (default: "completed").
Completed string
}
ProgressLabels defines the text labels for each task state. Use this to customize the status text for different contexts.
func DefaultLabels ¶
func DefaultLabels() ProgressLabels
DefaultLabels returns the default progress labels.
func InstallingLabels ¶
func InstallingLabels() ProgressLabels
InstallingLabels returns labels suitable for installation tasks.
func ValidatingLabels ¶
func ValidatingLabels() ProgressLabels
ValidatingLabels returns labels suitable for validation tasks.
type ProgressOption ¶
type ProgressOption func(*ProgressGroup)
ProgressOption is a functional option for configuring a ProgressGroup.
func WithLabels ¶
func WithLabels(labels ProgressLabels) ProgressOption
WithLabels sets custom labels for task states.
func WithTimer ¶
func WithTimer(tmr timer.Timer) ProgressOption
WithTimer sets the timer for duration tracking.
type ProgressTask ¶
type ProgressTask struct {
// Name is the display name of the task (e.g., "metrics-server", "argocd").
Name string
// Fn is the function to execute. It receives a context for cancellation.
Fn func(ctx context.Context) error
}
ProgressTask represents a named task to be executed with progress tracking.
type StageSeparatingWriter ¶ added in v5.15.0
type StageSeparatingWriter struct {
// contains filtered or unexported fields
}
StageSeparatingWriter wraps an io.Writer and automatically adds blank lines between CLI stages. It detects "title lines" (lines starting with an emoji) and inserts a leading newline before them when there has been previous output.
This eliminates the need for manual `LeadingNewline` tracking or `firstActivityShown` patterns in command handlers. The writer intelligently determines when stage separation is needed based on the output flow.
Title detection: A title line starts with an emoji (Unicode Symbol category). Examples: "🚀 Create cluster...", "📦 Installing components..."
Usage:
writer := notify.NewStageSeparatingWriter(cmd.OutOrStdout()) cmd.SetOut(writer) // All cmd.Println and notify.WriteMessage calls use this // Stages are now automatically separated with blank lines
func NewStageSeparatingWriter ¶ added in v5.15.0
func NewStageSeparatingWriter(underlying io.Writer) *StageSeparatingWriter
NewStageSeparatingWriter creates a new StageSeparatingWriter wrapping the given writer.
func (*StageSeparatingWriter) HasWritten ¶ added in v5.15.0
func (w *StageSeparatingWriter) HasWritten() bool
HasWritten returns whether any content has been written.
func (*StageSeparatingWriter) Reset ¶ added in v5.15.0
func (w *StageSeparatingWriter) Reset()
Reset clears the hasWritten state. Call this to treat the next title as the first output (no leading newline).
func (*StageSeparatingWriter) Write ¶ added in v5.15.0
func (w *StageSeparatingWriter) Write(data []byte) (int, error)
Write implements io.Writer. It detects title lines and automatically adds a leading newline when:
- There has been previous output (hasWritten is true).
- The current line starts with an emoji (title line).