fx

package
v0.7.13 Latest Latest
Warning

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

Go to latest
Published: Mar 18, 2026 License: MIT Imports: 14 Imported by: 1

Documentation

Overview

Package fx provides terminal animation types (spinners, progress bars, shimmers, and pulses) with composable builders and group orchestration.

Index

Constants

View Source
const DefaultSymbol = "⏳"

DefaultSymbol is the default icon shown during pulse, shimmer, and bar animations.

Variables

This section is empty.

Functions

This section is empty.

Types

type Animation

type Animation int

Animation is the animation rendering mode for a Builder.

const (
	// AnimationBar renders a progress bar.
	AnimationBar Animation = iota
	// AnimationPulse renders a pulsing text effect.
	AnimationPulse
	// AnimationShimmer renders a shimmering text effect.
	AnimationShimmer
	// AnimationSpinner renders a spinning character.
	AnimationSpinner
)

type AnimationConfig

type AnimationConfig struct {
	Builder   *Builder
	FieldsPtr *atomic.Pointer[[]core.Field]
	LevelPtr  *atomic.Int64
	MsgPtr    *atomic.Pointer[string]
	StartTime time.Time
	SymbolPtr *atomic.Pointer[string]
	Task      TaskFunc
}

AnimationConfig holds the parameters for running a single animation.

type Builder

type Builder struct {
	core.FieldBuilder[Builder]

	BarPercentKey  string        // when set, a formatted percent field is injected each tick
	BarProgressPtr *atomic.Int64 // bar mode: current progress; nil for non-bar modes
	BarStyle       bar.Style     // bar mode: visual style
	BarTotalPtr    *atomic.Int64 // bar mode: total progress; nil for non-bar modes
	DelayDur       time.Duration // when set, suppresses animation until this duration elapses
	ElapsedKey     string        // when set, a formatted elapsed-time field is injected each tick
	IndentDepth    int           // additional indent depth applied to the animation
	Log            Logger        // the logger interface; nil uses Default
	Level          core.Level    // log level used during animation rendering (default: LevelInfo)
	Message        string
	Mode           Animation
	PartOverrides  *[]core.Part // nil = use logger's parts
	PulseStops     []gradient.ColorStop
	ShimmerDir     shimmer.Direction
	ShimmerStops   []gradient.ColorStop
	Speed          float64
	SpinnerStyle   spinner.Style
	SuppressNonTTY bool           // when true, no output is produced on non-TTY writers
	SymbolIcon     string         // icon shown during animation; defaults to DefaultSymbol for pulse/shimmer/bar
	TreePos        []core.TreePos // additional tree levels applied to the animation
}

Builder configures an animation before execution. Create one with NewBuilder or the root clog convenience constructors (Spinner, Pulse, Shimmer, Bar).

func NewBuilder

func NewBuilder(cfg BuilderConfig) *Builder

NewBuilder creates a new Builder from the given configuration.

func (*Builder) After

func (b *Builder) After(d time.Duration) *Builder

After sets a delay before the animation becomes visible.

func (*Builder) BarPercent

func (b *Builder) BarPercent(key string) *Builder

BarPercent enables an auto-updating percentage field for AnimationBar.

func (*Builder) BarPercentValue

func (b *Builder) BarPercentValue() core.Percent

BarPercentValue returns the current progress as a core.Percent.

func (*Builder) Column

func (b *Builder) Column(key, path string, line, column int) *Builder

Column adds a file path field with a line and column number as a clickable terminal hyperlink.

func (*Builder) Dedent

func (b *Builder) Dedent() *Builder

Dedent removes one indent level from the animation output, down to a minimum of zero.

func (*Builder) Depth

func (b *Builder) Depth(n int) *Builder

Depth adds multiple indent levels to the animation output.

func (*Builder) Elapsed

func (b *Builder) Elapsed(key string) *Builder

Elapsed enables an auto-updating elapsed-time field.

func (*Builder) Indent

func (b *Builder) Indent() *Builder

Indent adds one indent level to the animation output.

func (*Builder) IndentedLogger

func (b *Builder) IndentedLogger(def Logger) Logger

IndentedLogger returns the builder's logger with any builder-level indent depth and tree levels applied. Used for completion logging so the result message has the same indentation as the animation.

func (*Builder) Line

func (b *Builder) Line(key, path string, line int) *Builder

Line adds a file path field with a line number as a clickable terminal hyperlink.

func (b *Builder) Link(key, url, text string) *Builder

Link adds a field as a clickable terminal hyperlink with custom display text.

func (*Builder) NonTTYSilent

func (b *Builder) NonTTYSilent(silent bool) *Builder

NonTTYSilent controls whether animation output is suppressed entirely on non-TTY writers (CI, piped output). When silent is true, no output is produced. When false (default), a static line is printed.

func (*Builder) Parts

func (b *Builder) Parts(parts ...core.Part) *Builder

Parts overrides the log-line part order for this animation and its completion message.

func (*Builder) Path

func (b *Builder) Path(key, path string) *Builder

Path adds a file path field as a clickable terminal hyperlink.

func (*Builder) Progress

func (b *Builder) Progress(ctx context.Context, task UpdateFunc) *WaitResult

Progress executes the task with the animation whose message and fields can be updated via the Update builder.

func (*Builder) ResolveDynamicFields

func (b *Builder) ResolveDynamicFields(fields []core.Field, dur time.Duration) []core.Field

ResolveDynamicFields clones fields and injects elapsed/percent values.

func (*Builder) ResolveLogger

func (b *Builder) ResolveLogger(def Logger) Logger

ResolveLogger returns the builder's logger, falling back to the given default.

func (*Builder) StripDynamicFields

func (b *Builder) StripDynamicFields(fields []core.Field) []core.Field

StripDynamicFields returns fields with animation-only dynamic fields removed.

func (*Builder) Symbol

func (b *Builder) Symbol(symbol string) *Builder

Symbol sets the icon displayed beside the message during animation.

func (*Builder) Tree

func (b *Builder) Tree(pos core.TreePos) *Builder

Tree adds one tree-nesting level with the given position.

func (*Builder) URL

func (b *Builder) URL(key, url string) *Builder

URL adds a field as a clickable terminal hyperlink.

func (*Builder) Wait

func (b *Builder) Wait(ctx context.Context, task TaskFunc) *WaitResult

Wait executes the task with the animation and returns a WaitResult for chaining.

type BuilderConfig

type BuilderConfig struct {
	BarProgress  *atomic.Int64
	BarStyle     bar.Style
	BarTotal     *atomic.Int64
	Level        core.Level
	Logger       Logger
	Message      string
	Mode         Animation
	PulseStops   []gradient.ColorStop
	ShimmerDir   shimmer.Direction
	ShimmerStops []gradient.ColorStop
	Speed        float64
	SpinnerStyle spinner.Style
	SymbolIcon   string
}

BuilderConfig provides the initial configuration for a Builder.

type DoneEvent

type DoneEvent struct {
	Err    error
	Fields []core.Field
	Level  core.Level
	Msg    string
	Parts  *[]core.Part
	Symbol *string
}

DoneEvent holds the parameters for logging a done event.

type FieldAlignment added in v0.7.0

type FieldAlignment int

FieldAlignment controls optional group-level alignment behavior.

const (
	// FieldAlignmentNone disables group-level field alignment padding.
	FieldAlignmentNone FieldAlignment = iota
	// FieldAlignmentMessage aligns the first field column after the message.
	FieldAlignmentMessage
)

type Group

type Group struct {
	Ctx context.Context //nolint:containedctx // Group shares a single ctx with all child goroutines
	Mu  sync.Mutex

	FieldAlignment FieldAlignment
	Log            Logger
	Monotonic      bool
	Parallelism    int
	Tasks          []*GroupTask
	// contains filtered or unexported fields
}

Group manages a set of concurrent animations rendered as a multi-line block. Create one with root clog's Group function, add animations with Group.Add, then call Group.Wait to run the render loop.

func (*Group) Add

func (g *Group) Add(b *Builder) *GroupEntry

Add registers an animation builder with the group and returns a GroupEntry for starting the task.

func (*Group) Wait

func (g *Group) Wait() *GroupResult

Wait runs the render loop, blocking until all tasks complete or the context is cancelled. The returned GroupResult can be used to log a single summary line.

type GroupEntry

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

GroupEntry is returned by Group.Add and provides [Run] and [Progress] methods to start a task within the group.

func (*GroupEntry) Progress

func (ge *GroupEntry) Progress(task UpdateFunc) *TaskResult

Progress starts a task with progress update capability and returns a TaskResult.

func (*GroupEntry) Run

func (ge *GroupEntry) Run(task TaskFunc) *TaskResult

Run starts a simple task (no progress updates) and returns a TaskResult.

type GroupResult

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

GroupResult holds the aggregate result of a Group.Wait.

func (*GroupResult) Err

func (r *GroupResult) Err() error

Err returns the joined error, logging success or failure.

func (*GroupResult) Msg

func (r *GroupResult) Msg(msg string) error

Msg logs at success level with the given message if all tasks succeeded.

func (*GroupResult) OnErrorLevel

func (b *GroupResult) OnErrorLevel(lvl core.Level) *T

OnErrorLevel sets the log level for the error case.

func (*GroupResult) OnErrorMessage

func (b *GroupResult) OnErrorMessage(msg string) *T

OnErrorMessage sets a custom message for the error case.

func (*GroupResult) OnSuccessLevel

func (b *GroupResult) OnSuccessLevel(lvl core.Level) *T

OnSuccessLevel sets the log level for the success case.

func (*GroupResult) OnSuccessMessage

func (b *GroupResult) OnSuccessMessage(msg string) *T

OnSuccessMessage sets the message for the success case.

func (*GroupResult) Parts

func (b *GroupResult) Parts(parts ...core.Part) *T

Parts overrides the log-line part order for the completion message.

func (*GroupResult) Send

func (r *GroupResult) Send() error

Send finalises the result.

func (*GroupResult) Silent

func (r *GroupResult) Silent() error

Silent returns the joined error without logging anything.

func (*GroupResult) Symbol

func (b *GroupResult) Symbol(symbol string) *T

Symbol sets a custom emoji symbol for the completion log message.

type GroupTask

type GroupTask struct {
	Builder    *Builder
	DoneErr    chan error // buffered(1); goroutine sends result here
	Err        error      // populated by Wait() after DoneErr is drained
	FieldsPtr  *atomic.Pointer[[]core.Field]
	FinishedAt atomic.Int64
	LevelPtr   *atomic.Int64
	MsgPtr     *atomic.Pointer[string]
	StartTime  time.Time
	StartedAt  atomic.Int64
	SymbolPtr  *atomic.Pointer[string]
}

GroupTask holds per-animation state for the group render loop. This is exported so the root clog rendering code can access it.

func (*GroupTask) Duration added in v0.7.0

func (t *GroupTask) Duration(now time.Time) time.Duration

Duration returns the elapsed execution time, or zero while the task is queued.

func (*GroupTask) FinishTime added in v0.7.2

func (t *GroupTask) FinishTime() time.Time

FinishTime returns the actual finish time, or the zero value if unfinished.

func (*GroupTask) MarkFinished added in v0.7.2

func (t *GroupTask) MarkFinished(now time.Time)

MarkFinished records the actual task finish time.

func (*GroupTask) MarkStarted added in v0.7.0

func (t *GroupTask) MarkStarted(now time.Time)

MarkStarted records the actual task start time.

func (*GroupTask) Started added in v0.7.0

func (t *GroupTask) Started() bool

Started reports whether the task has begun executing.

type Logger

type Logger interface {
	// Done logs a done event after an animation finishes.
	Done(evt DoneEvent)

	// WithIndent returns a Logger with additional indent depth and tree positions.
	WithIndent(depth int, tree []core.TreePos) Logger

	// Output returns the Output associated with this Logger.
	Output() Output

	// RunAnimation runs the animation loop for a single builder.
	RunAnimation(ctx context.Context, cfg AnimationConfig) error

	// RunGroup runs the group render loop.
	RunGroup(ctx context.Context, g *Group) error
}

Logger is the interface that the root clog package implements. It decouples the fx animation types from the concrete *clog.Logger so the fx package can reference logging operations without importing root clog.

type Output

type Output interface {
	IsTTY() bool
	Writer() io.Writer
	Width() int
	ColorsDisabled() bool
	PathLink(path string, line, column int) string
	Hyperlink(url, text string) string
}

Output provides terminal capabilities needed by animation types.

type TaskFunc

type TaskFunc func(context.Context) error

TaskFunc is a function executed by Builder.Wait.

type TaskResult

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

TaskResult holds the result of a group animation task.

func (*TaskResult) Err

func (r *TaskResult) Err() error

Err returns the error, logging success or failure using the original message.

func (*TaskResult) Msg

func (r *TaskResult) Msg(msg string) error

Msg logs at success level with the given message on success, or at error level with the error string on failure. Returns the error.

func (*TaskResult) OnErrorLevel

func (b *TaskResult) OnErrorLevel(lvl core.Level) *T

OnErrorLevel sets the log level for the error case.

func (*TaskResult) OnErrorMessage

func (b *TaskResult) OnErrorMessage(msg string) *T

OnErrorMessage sets a custom message for the error case.

func (*TaskResult) OnSuccessLevel

func (b *TaskResult) OnSuccessLevel(lvl core.Level) *T

OnSuccessLevel sets the log level for the success case.

func (*TaskResult) OnSuccessMessage

func (b *TaskResult) OnSuccessMessage(msg string) *T

OnSuccessMessage sets the message for the success case.

func (*TaskResult) Parts

func (b *TaskResult) Parts(parts ...core.Part) *T

Parts overrides the log-line part order for the completion message.

func (*TaskResult) Send

func (r *TaskResult) Send() error

Send finalises the result, logging at the configured success or error level.

func (*TaskResult) Silent

func (r *TaskResult) Silent() error

Silent returns just the error without logging anything.

func (*TaskResult) Symbol

func (b *TaskResult) Symbol(symbol string) *T

Symbol sets a custom emoji symbol for the completion log message.

type Update

type Update struct {
	core.FieldBuilder[Update]

	Base        []core.Field
	FieldsPtr   *atomic.Pointer[[]core.Field]
	MsgPtr      *atomic.Pointer[string]
	MsgText     string
	ProgressPtr *atomic.Int64           // bar mode: current progress value; nil for non-bar modes
	LevelPtr    *atomic.Int64           // overridden level; nil when not updatable
	SymbolPtr   *atomic.Pointer[string] // symbol icon; nil when not updatable
	TotalPtr    *atomic.Int64           // bar mode: total progress value; nil for non-bar modes
}

Update is a fluent builder for updating an animation's message and fields during an UpdateFunc. Call Update.Msg and field methods to build the update, then Update.Send to apply it atomically.

func (*Update) AddTotal

func (p *Update) AddTotal(delta int) *Update

AddTotal atomically adds delta to the total progress value for a bar animation. The result is clamped to a minimum of 1. No-op if this is not a bar animation.

func (*Update) Msg

func (p *Update) Msg(msg string) *Update

Msg sets the animation's displayed message.

func (*Update) Msgf added in v0.7.8

func (p *Update) Msgf(format string, args ...any) *Update

Msgf sets the animation's displayed message with formatting.

func (*Update) Send

func (p *Update) Send()

Send applies the accumulated message and field changes to the animation atomically.

func (*Update) SetLevel added in v0.7.7

func (p *Update) SetLevel(level core.Level) *Update

SetLevel overrides the log level used when rendering the final done line. No-op if the animation does not support level updates.

func (*Update) SetProgress

func (p *Update) SetProgress(current int) *Update

SetProgress sets the current progress value for a bar animation. Values are clamped to [0, total]. No-op if this is not a bar animation.

func (*Update) SetSymbol added in v0.7.0

func (p *Update) SetSymbol(symbol string) *Update

SetSymbol changes the icon displayed beside the message during animation. The change takes effect on the next render tick. No-op if the animation does not support symbol updates.

func (*Update) SetTotal

func (p *Update) SetTotal(total int) *Update

SetTotal updates the total progress value for a bar animation. No-op if this is not a bar animation.

type UpdateFunc

type UpdateFunc func(context.Context, *Update) error

UpdateFunc is a function executed by Builder.Progress. The Update allows updating the animation's message and fields.

type WaitResult

type WaitResult struct {
	TaskErr error
	// contains filtered or unexported fields
}

WaitResult holds the result of a Builder.Wait or Builder.Progress operation and allows chaining additional fields before finalising the log output.

func NewWaitResult

func NewWaitResult(
	err error,
	logger Logger,
	parts *[]core.Part,
	lvl core.Level,
	msg string,
) *WaitResult

NewWaitResult creates a WaitResult with default settings.

func (*WaitResult) Err

func (w *WaitResult) Err() error

Err returns the error, logging success at info level or failure at error level using the original animation message.

func (*WaitResult) Msg

func (w *WaitResult) Msg(msg string) error

Msg logs at info level with the given message on success, or at error level with the error string on failure. Returns the error.

func (*WaitResult) Msgf added in v0.7.12

func (w *WaitResult) Msgf(format string, a ...any) error

Msgf is like WaitResult.Msg but accepts a format string.

func (*WaitResult) OnErrorLevel

func (b *WaitResult) OnErrorLevel(lvl core.Level) *T

OnErrorLevel sets the log level for the error case.

func (*WaitResult) OnErrorMessage

func (b *WaitResult) OnErrorMessage(msg string) *T

OnErrorMessage sets a custom message for the error case.

func (*WaitResult) OnSuccessLevel

func (b *WaitResult) OnSuccessLevel(lvl core.Level) *T

OnSuccessLevel sets the log level for the success case.

func (*WaitResult) OnSuccessMessage

func (b *WaitResult) OnSuccessMessage(msg string) *T

OnSuccessMessage sets the message for the success case.

func (*WaitResult) Parts

func (b *WaitResult) Parts(parts ...core.Part) *T

Parts overrides the log-line part order for the completion message.

func (*WaitResult) Send

func (w *WaitResult) Send() error

Send finalises the result, logging at the configured success or error level. Returns the error from the task.

func (*WaitResult) Silent

func (w *WaitResult) Silent() error

Silent returns just the error without logging anything.

func (*WaitResult) Symbol

func (b *WaitResult) Symbol(symbol string) *T

Symbol sets a custom emoji symbol for the completion log message.

Directories

Path Synopsis
bar
Package bar provides bar animation styles and presets for clog.
Package bar provides bar animation styles and presets for clog.
widget
Package widget provides composable text widgets for progress bars.
Package widget provides composable text widgets for progress bars.
Package pulse provides pulse animation rendering for clog.
Package pulse provides pulse animation rendering for clog.
Package shimmer provides shimmer animation rendering for clog.
Package shimmer provides shimmer animation rendering for clog.
Package spinner provides spinner animation styles and presets for clog.
Package spinner provides spinner animation styles and presets for clog.

Jump to

Keyboard shortcuts

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