Documentation
¶
Overview ¶
Package ui provides Terraform streaming UI components.
Package ui provides a streaming TUI for Terraform operations. It parses Terraform's JSON streaming output and displays real-time resource status in a Docker-build-style inline interface.
Index ¶
- func ConfirmApply() (bool, error)
- func ConfirmDestroy() (bool, error)
- func Execute(ctx context.Context, opts *ExecuteOptions) error
- func ExecuteApply(ctx context.Context, opts *ExecuteOptions) error
- func ExecuteDestroy(ctx context.Context, opts *ExecuteOptions) error
- func ExecuteInit(ctx context.Context, opts *ExecuteOptions) error
- func ExecutePlan(ctx context.Context, opts *ExecuteOptions) error
- func RenderChangeSummaryBadges(add, change, remove int) string
- func ShouldUseStreamingUI(uiFlagSet, uiFlag, configEnabled bool, subCommand string) bool
- func UIRequestedButUnsupported(uiFlagSet, uiFlag, configEnabled bool, subCommand string) bool
- func WouldAttemptStreamingUI(uiFlagSet, uiFlag, configEnabled bool) bool
- type ApplyCompleteMessage
- type ApplyErroredMessage
- type ApplyHook
- type ApplyProgressMessage
- type ApplyStartMessage
- type AttributeChange
- type BaseMessage
- type ChangeSummaryMessage
- type Changes
- type Clock
- type DependencyTree
- type Diagnostic
- type DiagnosticLocation
- type DiagnosticMessage
- type DiagnosticRange
- type ExecuteOptions
- type InitModel
- type InitModelOption
- type InitOutputMessage
- type LogMessage
- type MessageType
- type Model
- type ModelOption
- type OutputValue
- type OutputsMessage
- type ParseResult
- type Parser
- type Phase
- type PlannedChange
- type PlannedChangeMessage
- type RefreshCompleteMessage
- type RefreshHook
- type RefreshStartMessage
- type RenderConfig
- type ResourceAddr
- type ResourceOperation
- type ResourceState
- type ResourceTracker
- func (rt *ResourceTracker) GetActiveCount() int
- func (rt *ResourceTracker) GetChangeSummary() *ChangeSummaryMessage
- func (rt *ResourceTracker) GetCompletedCount() int
- func (rt *ResourceTracker) GetCurrentActivity() *ResourceOperation
- func (rt *ResourceTracker) GetDiagnostics() []*DiagnosticMessage
- func (rt *ResourceTracker) GetErrorCount() int
- func (rt *ResourceTracker) GetOutputs() *OutputsMessage
- func (rt *ResourceTracker) GetPhase() Phase
- func (rt *ResourceTracker) GetResources() []*ResourceOperation
- func (rt *ResourceTracker) GetTotalCount() int
- func (rt *ResourceTracker) HandleMessage(msg any)
- func (rt *ResourceTracker) HasErrors() bool
- type TreeBuildOptions
- type TreeNode
- type VersionMessage
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ConfirmApply ¶
ConfirmApply prompts the user to confirm applying changes.
func ConfirmDestroy ¶
ConfirmDestroy prompts the user to confirm destroying resources.
func Execute ¶
func Execute(ctx context.Context, opts *ExecuteOptions) error
Execute runs a terraform command with streaming UI output. Returns an error with exit code preserved via errUtils.ExitCodeError.
func ExecuteApply ¶
func ExecuteApply(ctx context.Context, opts *ExecuteOptions) error
ExecuteApply runs terraform apply with optional confirmation. If -auto-approve is not present and not using --from-plan, it runs: (1) terraform plan -json -out=<temp> (with TUI) (2) Display dependency tree (3) Confirmation prompt (4) terraform apply -json <temp> (with TUI).
func ExecuteDestroy ¶
func ExecuteDestroy(ctx context.Context, opts *ExecuteOptions) error
ExecuteDestroy runs terraform destroy with confirmation. It runs: (1) terraform plan -destroy -json -out=<temp> (with TUI) (2) Display dependency tree (3) Confirmation prompt (4) terraform apply -json <temp> (with TUI).
func ExecuteInit ¶
func ExecuteInit(ctx context.Context, opts *ExecuteOptions) error
ExecuteInit runs terraform init with a spinner TUI that captures output. The output is shown in a viewport that clears when init completes.
func ExecutePlan ¶
func ExecutePlan(ctx context.Context, opts *ExecuteOptions) error
ExecutePlan runs terraform plan with streaming UI and displays the dependency tree. It generates a temp planfile to parse for the tree, then cleans it up.
func RenderChangeSummaryBadges ¶
RenderChangeSummaryBadges renders a badge-style change summary. Shows "NO CHANGES" badge if all counts are zero. Format: " 1 ADD 2 CHANGE 1 DELETE" with colored badges (green/yellow/red backgrounds).
func ShouldUseStreamingUI ¶
ShouldUseStreamingUI determines if streaming UI should be used. This checks the flag, config, TTY availability, and CI environment.
func UIRequestedButUnsupported ¶
UIRequestedButUnsupported reports whether the user explicitly opted in to the streaming UI (via --ui or atmos config) for a subcommand that doesn't support it (e.g. refresh), as opposed to streaming simply being unrequested, disabled by CI, or unavailable due to no TTY. Callers use this to warn the user instead of silently falling back to the plain execution path with no explanation.
func WouldAttemptStreamingUI ¶
WouldAttemptStreamingUI reports whether the streaming UI would actually be launched for this invocation, independent of which specific subcommand/phase is running: the user (or atmos config) opted in, and the environment can support it (a real TTY, not CI). Callers that need to reject a combination before dispatch (e.g. --ui with concurrent multi-component execution, which would race multiple full-screen TUI sessions for the same terminal) use this instead of ShouldUseStreamingUI, since the exact phase/gate isn't known yet at that point.
Types ¶
type ApplyCompleteMessage ¶
type ApplyCompleteMessage struct {
BaseMessage
Hook ApplyHook `json:"hook"`
}
ApplyCompleteMessage represents successful completion of a resource apply.
type ApplyErroredMessage ¶
type ApplyErroredMessage struct {
BaseMessage
Hook ApplyHook `json:"hook"`
}
ApplyErroredMessage represents a failed resource apply.
type ApplyHook ¶
type ApplyHook struct {
Resource ResourceAddr `json:"resource"`
Action string `json:"action"`
IDKey string `json:"id_key,omitempty"`
IDValue string `json:"id_value,omitempty"`
ElapsedSecs int `json:"elapsed_secs,omitempty"`
}
ApplyHook contains the hook details for apply operations.
type ApplyProgressMessage ¶
type ApplyProgressMessage struct {
BaseMessage
Hook ApplyHook `json:"hook"`
}
ApplyProgressMessage represents progress during apply.
type ApplyStartMessage ¶
type ApplyStartMessage struct {
BaseMessage
Hook ApplyHook `json:"hook"`
}
ApplyStartMessage represents the start of a resource apply operation.
type AttributeChange ¶
type AttributeChange struct {
Key string // Attribute name.
Before interface{} // Value before change (nil for create).
After interface{} // Value after change (nil for delete).
Unknown bool // True if value is "(known after apply)".
Sensitive bool // True if value is sensitive.
ForcesReplacement bool // True if this attribute forces resource replacement.
}
AttributeChange represents a single attribute change.
type BaseMessage ¶
type BaseMessage struct {
Level string `json:"@level"`
Message string `json:"@message"`
Module string `json:"@module"`
Timestamp string `json:"@timestamp"`
Type MessageType `json:"type"`
}
BaseMessage contains fields common to all Terraform JSON messages.
type ChangeSummaryMessage ¶
type ChangeSummaryMessage struct {
BaseMessage
Changes Changes `json:"changes"`
}
ChangeSummaryMessage represents the summary of changes.
type Changes ¶
type Changes struct {
Add int `json:"add"`
Change int `json:"change"`
Remove int `json:"remove"`
Import int `json:"import,omitempty"`
Operation string `json:"operation"` // plan, apply.
}
Changes contains the change counts for a summary.
type DependencyTree ¶
type DependencyTree struct {
Root *TreeNode
Stack string // Atmos stack name (e.g., "plat-ue2-dev").
Component string // Atmos component name (e.g., "vpc").
// contains filtered or unexported fields
}
DependencyTree represents the resource hierarchy.
func BuildDependencyTree ¶
func BuildDependencyTree(ctx context.Context, opts *TreeBuildOptions) (*DependencyTree, error)
BuildDependencyTree parses a planfile and builds the dependency tree.
func (*DependencyTree) GetChangeSummary ¶
func (t *DependencyTree) GetChangeSummary() (add, change, remove int)
GetChangeSummary returns a summary of changes from the tree.
func (*DependencyTree) RenderTree ¶
func (t *DependencyTree) RenderTree() string
RenderTree renders the tree as a string with box-drawing characters. Uses a two-column layout: action symbol (fixed width) | tree structure.
func (*DependencyTree) RenderTreeWithConfig ¶
func (t *DependencyTree) RenderTreeWithConfig(config *RenderConfig) string
RenderTreeWithConfig renders the tree with custom rendering configuration.
type Diagnostic ¶
type Diagnostic struct {
Severity string `json:"severity"` // error, warning.
Summary string `json:"summary"`
Detail string `json:"detail,omitempty"`
Address string `json:"address,omitempty"`
Range *DiagnosticRange `json:"range,omitempty"`
}
Diagnostic contains the diagnostic details.
type DiagnosticLocation ¶
type DiagnosticLocation struct {
Line int `json:"line"`
Column int `json:"column"`
Byte int `json:"byte"`
}
DiagnosticLocation represents a source code location.
type DiagnosticMessage ¶
type DiagnosticMessage struct {
BaseMessage
Diagnostic Diagnostic `json:"diagnostic"`
}
DiagnosticMessage represents warnings and errors.
type DiagnosticRange ¶
type DiagnosticRange struct {
Filename string `json:"filename"`
Start DiagnosticLocation `json:"start"`
End DiagnosticLocation `json:"end"`
}
DiagnosticRange represents a source code range.
type ExecuteOptions ¶
type ExecuteOptions struct {
Command string // terraform or opentofu binary.
Args []string // Command arguments (plan, apply, etc.).
WorkingDir string // Component directory.
Env []string // Environment variables.
Component string // Component name for display.
Stack string // Stack name for display.
SubCommand string // "plan", "apply", "init", "refresh", "workspace".
Workspace string // Workspace name (for workspace select/new).
DryRun bool // If true, don't execute.
// RenderConfig controls dependency-tree rendering (compact spacing, attribute bar,
// max lines). Nil uses RenderTreeWithConfig's built-in defaults.
RenderConfig *RenderConfig
}
ExecuteOptions configures streaming execution.
type InitModel ¶
type InitModel struct {
// contains filtered or unexported fields
}
InitModel is the bubbletea model for streaming terraform init/workspace output.
func NewInitModel ¶
func NewInitModel(component, stack, subCommand string, reader io.Reader, opts ...InitModelOption) *InitModel
NewInitModel creates a new init/workspace streaming model. Use WithWorkspace to set the workspace name for workspace select/new commands.
func (InitModel) Cancelled ¶
Cancelled reports whether the user explicitly quit (Ctrl-C/q) rather than the underlying terraform command completing on its own. Value receiver: bubbletea returns models by value, so this must be callable on the InitModel value stored in the tea.Model interface.
func (*InitModel) GetExitCode ¶
GetExitCode returns the exit code.
type InitModelOption ¶
type InitModelOption func(*InitModel)
InitModelOption configures an InitModel.
func WithInitClock ¶
func WithInitClock(c Clock) InitModelOption
WithInitClock sets the clock implementation for time operations.
func WithWorkspace ¶
func WithWorkspace(workspace string) InitModelOption
WithWorkspace sets the workspace name (used for workspace select/new display).
type InitOutputMessage ¶
type InitOutputMessage struct {
BaseMessage
InitOutput struct {
// Init has various message subtypes.
MessageType string `json:"message_type,omitempty"`
} `json:"init_output,omitempty"`
}
InitOutputMessage represents init command output.
type LogMessage ¶
type LogMessage struct {
BaseMessage
}
LogMessage represents unstructured log output.
type MessageType ¶
type MessageType string
MessageType represents the type of Terraform JSON message.
const ( MessageTypeVersion MessageType = "version" MessageTypePlannedChange MessageType = "planned_change" MessageTypeChangeSummary MessageType = "change_summary" MessageTypeApplyStart MessageType = "apply_start" MessageTypeApplyProgress MessageType = "apply_progress" MessageTypeApplyComplete MessageType = "apply_complete" MessageTypeApplyErrored MessageType = "apply_errored" MessageTypeRefreshStart MessageType = "refresh_start" MessageTypeRefreshComplete MessageType = "refresh_complete" MessageTypeDiagnostic MessageType = "diagnostic" MessageTypeOutputs MessageType = "outputs" MessageTypeResourceDrift MessageType = "resource_drift" MessageTypeInitOutput MessageType = "init_output" MessageTypeLog MessageType = "log" )
Message types from Terraform's machine-readable UI.
type Model ¶
type Model struct {
// contains filtered or unexported fields
}
Model is the bubbletea model for streaming terraform output.
func NewModel ¶
func NewModel(component, stack, command string, reader io.Reader, opts ...ModelOption) *Model
NewModel creates a new streaming model.
func (Model) Cancelled ¶
Cancelled reports whether the user explicitly quit (Ctrl-C/q) rather than the underlying terraform command completing on its own. Value receiver: bubbletea returns models by value, so this must be callable on the Model value stored in the tea.Model interface.
func (*Model) GetExitCode ¶
GetExitCode returns the exit code after completion.
func (*Model) GetTracker ¶
func (m *Model) GetTracker() *ResourceTracker
GetTracker returns the resource tracker.
func (*Model) LogDiagnostics ¶
func (m *Model) LogDiagnostics()
LogDiagnostics sends all diagnostics to the Atmos logger at appropriate severity levels. Call this after the TUI completes to display warnings after the completion message.
type ModelOption ¶
type ModelOption func(*Model)
ModelOption configures a Model.
func WithClock ¶
func WithClock(c Clock) ModelOption
WithClock sets the clock implementation for time operations.
type OutputValue ¶
type OutputValue struct {
Sensitive bool `json:"sensitive"`
Type any `json:"type"`
Value any `json:"value"`
Action string `json:"action,omitempty"`
}
OutputValue represents a single output value.
type OutputsMessage ¶
type OutputsMessage struct {
BaseMessage
Outputs map[string]OutputValue `json:"outputs"`
}
OutputsMessage represents output values after successful operations.
type ParseResult ¶
ParseResult represents a parsed message or error.
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser reads and parses Terraform JSON streaming output.
func (*Parser) Next ¶
func (p *Parser) Next() (*ParseResult, error)
Next reads and parses the next JSON message. Returns io.EOF when there are no more messages.
type Phase ¶
type Phase int
Phase represents the terraform operation phase.
type PlannedChange ¶
type PlannedChange struct {
Resource ResourceAddr `json:"resource"`
Action string `json:"action"`
PreviousAction string `json:"previous_action,omitempty"`
Reason string `json:"reason,omitempty"`
}
PlannedChange contains the change details for a planned resource.
type PlannedChangeMessage ¶
type PlannedChangeMessage struct {
BaseMessage
Change PlannedChange `json:"change"`
}
PlannedChangeMessage represents a planned resource change.
type RefreshCompleteMessage ¶
type RefreshCompleteMessage struct {
BaseMessage
Hook RefreshHook `json:"hook"`
}
RefreshCompleteMessage represents successful completion of a resource refresh.
type RefreshHook ¶
type RefreshHook struct {
Resource ResourceAddr `json:"resource"`
IDKey string `json:"id_key,omitempty"`
IDValue string `json:"id_value,omitempty"`
}
RefreshHook contains the hook details for refresh operations.
type RefreshStartMessage ¶
type RefreshStartMessage struct {
BaseMessage
Hook RefreshHook `json:"hook"`
}
RefreshStartMessage represents the start of a resource refresh.
type RenderConfig ¶
type RenderConfig struct {
// ShowAttributeBar shows a thick ┃ bar alongside attributes.
ShowAttributeBar bool
// Compact removes blank lines between resources.
Compact bool
// MaxLines controls collapsing of large JSON values (0 = show all).
MaxLines int
// CreateStyle, UpdateStyle, DeleteStyle, DimStyle, TreeStyle, and BarStyle are the
// styles used when rendering the tree and attribute changes. Populated with defaults
// by resolveRenderConfig when not explicitly set.
CreateStyle lipgloss.Style
UpdateStyle lipgloss.Style
DeleteStyle lipgloss.Style
DimStyle lipgloss.Style
TreeStyle lipgloss.Style
BarStyle lipgloss.Style
}
RenderConfig holds configuration for tree rendering, including display options and the styles used to render create/update/delete attribute changes.
func BuildRenderConfig ¶
func BuildRenderConfig(uiConfig schema.TerraformUI) *RenderConfig
BuildRenderConfig translates atmos.yaml's components.terraform.ui.{compact, show_attribute_bar,max_lines} into a RenderConfig, applying the documented defaults (compact=true, show_attribute_bar=false) when left unset.
type ResourceAddr ¶
type ResourceAddr struct {
Addr string `json:"addr"`
Module string `json:"module"`
Resource string `json:"resource"`
ResourceType string `json:"resource_type"`
ResourceName string `json:"resource_name"`
ResourceKey string `json:"resource_key,omitempty"`
ImpliedProvider string `json:"implied_provider"`
}
ResourceAddr contains common resource identification fields.
type ResourceOperation ¶
type ResourceOperation struct {
Address string // e.g., "aws_instance.example".
Module string // Module path if applicable.
ResourceType string // e.g., "aws_instance".
ResourceName string // e.g., "example".
Action string // create, update, delete, read, no-op.
State ResourceState // Current state.
StartTime time.Time // When operation started.
EndTime time.Time // When operation completed.
ElapsedSecs int // Elapsed time from terraform.
Error string // Error message if failed.
IDKey string // For existing resources.
IDValue string // For existing resources.
LastUpdate time.Time // For progress updates.
}
ResourceOperation tracks the lifecycle of a single resource.
type ResourceState ¶
type ResourceState int
ResourceState represents the current state of a resource operation.
const ( ResourceStatePending ResourceState = iota ResourceStateRefreshing ResourceStateInProgress ResourceStateComplete ResourceStateError )
Resource operation states.
func (ResourceState) String ¶
func (s ResourceState) String() string
String returns the string representation of the resource state.
type ResourceTracker ¶
type ResourceTracker struct {
// contains filtered or unexported fields
}
ResourceTracker manages all resource operations.
func NewResourceTracker ¶
func NewResourceTracker() *ResourceTracker
NewResourceTracker creates a new resource tracker.
func (*ResourceTracker) GetActiveCount ¶
func (rt *ResourceTracker) GetActiveCount() int
GetActiveCount returns the number of resources currently in progress.
func (*ResourceTracker) GetChangeSummary ¶
func (rt *ResourceTracker) GetChangeSummary() *ChangeSummaryMessage
GetChangeSummary returns the change summary if available.
func (*ResourceTracker) GetCompletedCount ¶
func (rt *ResourceTracker) GetCompletedCount() int
GetCompletedCount returns the number of completed resources.
func (*ResourceTracker) GetCurrentActivity ¶
func (rt *ResourceTracker) GetCurrentActivity() *ResourceOperation
GetCurrentActivity returns the first in-progress or refreshing resource, if any. Returns nil if no resource is currently active.
func (*ResourceTracker) GetDiagnostics ¶
func (rt *ResourceTracker) GetDiagnostics() []*DiagnosticMessage
GetDiagnostics returns all diagnostic messages.
func (*ResourceTracker) GetErrorCount ¶
func (rt *ResourceTracker) GetErrorCount() int
GetErrorCount returns the number of failures: failed resources plus error-severity diagnostics with no resource address (e.g. a plan-file write failure). Must stay in sync with HasErrors' definition of "has an error" -- otherwise a diagnostic-only failure (no resource individually errored) trips the "failed" banner while this reports 0, producing a confusing "failed: 0 error(s)" summary.
func (*ResourceTracker) GetOutputs ¶
func (rt *ResourceTracker) GetOutputs() *OutputsMessage
GetOutputs returns the captured output values.
func (*ResourceTracker) GetPhase ¶
func (rt *ResourceTracker) GetPhase() Phase
GetPhase returns the current operation phase.
func (*ResourceTracker) GetResources ¶
func (rt *ResourceTracker) GetResources() []*ResourceOperation
GetResources returns a snapshot of all resources in order.
func (*ResourceTracker) GetTotalCount ¶
func (rt *ResourceTracker) GetTotalCount() int
GetTotalCount returns the total number of resources.
func (*ResourceTracker) HandleMessage ¶
func (rt *ResourceTracker) HandleMessage(msg any)
HandleMessage processes a Terraform JSON message and updates state.
func (*ResourceTracker) HasErrors ¶
func (rt *ResourceTracker) HasErrors() bool
HasErrors returns true if any resources failed.
type TreeBuildOptions ¶
type TreeBuildOptions struct {
PlanfilePath string
TerraformPath string
WorkingDir string
Stack string
Component string
}
TreeBuildOptions groups the parameters needed to build a dependency tree from a planfile.
type TreeNode ¶
type TreeNode struct {
Address string // Full Terraform address (e.g., "aws_vpc.main").
Action string // create, update, delete, read, no-op.
Children []*TreeNode
Parent *TreeNode
IsModule bool // True if this is a module node.
Changes []*AttributeChange // Attribute-level changes.
}
TreeNode represents a resource in the dependency tree.
type VersionMessage ¶
type VersionMessage struct {
BaseMessage
Terraform string `json:"terraform"`
UI string `json:"ui"`
}
VersionMessage represents the initial version message.