cli

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 1, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package cli provides shared utilities for CLI startup commands.

Index

Constants

View Source
const KVMinColWidth = 20

KVMinColWidth is the minimum visual width for each key-value column. A consistent minimum ensures columns align across consecutive PrintKV calls.

View Source
const ShutdownTimeout = 10 * time.Second

ShutdownTimeout bounds everything a shutdown does: stopping the server and then every cleanup function, against one clock.

The cleanups are where the network is: a metrics provider and an OTLP exporter both flush on the way out, and an unreachable collector makes that flush block. Handing them a context.Background() — which is what they used to get — is how SIGTERM stops terminating the process.

Variables

View Source
var (
	Purple    = lipgloss.Color("99")
	Gray      = lipgloss.Color("245")
	LightGray = lipgloss.Color("241")
	White     = lipgloss.Color("15")
	Red       = lipgloss.Color("#ef4444") // matches UI --color-status-error
	Yellow    = lipgloss.Color("222")     // warm amber
	Green     = lipgloss.Color("#67ea94") // matches UI --color-status-ready
	Teal      = lipgloss.Color("#06ffa5")
)

Theme colors for terminal UI rendering.

View Source
var (

	// DimStyle is a muted style for secondary text.
	DimStyle = lipgloss.NewStyle().Foreground(Gray)
)

Reusable inline styles for compact key-value output.

Functions

func BoolToSafeString

func BoolToSafeString(
	b *bool,
) string

BoolToSafeString converts a *bool to a string. Returns "" if nil.

func BuildAuditStreamConfig

func BuildAuditStreamConfig(
	namespace string,
	auditCfg config.NATSAudit,
) jetstream.StreamConfig

BuildAuditStreamConfig builds a jetstream.StreamConfig from audit config values.

func BuildEnrollmentKVConfig

func BuildEnrollmentKVConfig(
	namespace string,
	enrollmentCfg config.NATSEnrollment,
) jetstream.KeyValueConfig

BuildEnrollmentKVConfig builds a jetstream.KeyValueConfig from enrollment config values. The enrollment bucket has no TTL so pending requests persist until accepted or rejected.

func BuildFactsKVConfig

func BuildFactsKVConfig(
	namespace string,
	factsCfg config.NATSFacts,
) jetstream.KeyValueConfig

BuildFactsKVConfig builds a jetstream.KeyValueConfig from facts config values.

func BuildFileStateKVConfig

func BuildFileStateKVConfig(
	namespace string,
	fileStateCfg config.NATSFileState,
) jetstream.KeyValueConfig

BuildFileStateKVConfig builds a jetstream.KeyValueConfig from file-state config values. The file-state bucket has no TTL so deployment SHA tracking persists indefinitely.

func BuildJobKVConfig

func BuildJobKVConfig(
	namespace string,
	kvCfg config.NATSKV,
) jetstream.KeyValueConfig

BuildJobKVConfig builds a jetstream.KeyValueConfig from job KV config values. The returned config includes TTL, MaxBytes, Storage, and Replicas from the NATSKV configuration.

func BuildNATSAuthOptions

func BuildNATSAuthOptions(
	auth config.NATSAuth,
) natsclient.AuthOptions

BuildNATSAuthOptions converts a config NATSAuth to natsclient.AuthOptions.

func BuildObjectStoreConfig

func BuildObjectStoreConfig(
	namespace string,
	objectsCfg config.NATSObjects,
) jetstream.ObjectStoreConfig

BuildObjectStoreConfig builds a jetstream.ObjectStoreConfig from objects config values.

func BuildRegistryKVConfig

func BuildRegistryKVConfig(
	namespace string,
	registryCfg config.NATSRegistry,
) jetstream.KeyValueConfig

BuildRegistryKVConfig builds a jetstream.KeyValueConfig from registry config values.

func BuildResponseKVConfig

func BuildResponseKVConfig(
	namespace string,
	kvCfg config.NATSKV,
) jetstream.KeyValueConfig

BuildResponseKVConfig builds a jetstream.KeyValueConfig for the job response KV bucket. It shares TTL, MaxBytes, Storage, and Replicas settings from the parent NATSKV configuration.

func BuildStateKVConfig

func BuildStateKVConfig(
	namespace string,
	stateCfg config.NATSState,
) jetstream.KeyValueConfig

BuildStateKVConfig builds a jetstream.KeyValueConfig from state config values. The state bucket has no TTL so drain flags and timeline events persist indefinitely.

func CalculateColumnWidths

func CalculateColumnWidths(
	headers []string,
	rows [][]string,
	minPadding int,
) []int

CalculateColumnWidths calculates the optimal width for each column based on content.

func CloseNATSClient

func CloseNATSClient(
	nc natsCloser,
)

CloseNATSClient safely closes a NATS client connection.

func DisplayJobDetail

func DisplayJobDetail(
	resp *client.JobDetail,
)

DisplayJobDetail displays detailed job information from domain types. Used by both job get and job run commands.

func Float64ToSafeString

func Float64ToSafeString(
	f *float64,
) string

Float64ToSafeString converts a *float64 to a string. Returns "N/A" if nil.

func FormatAge

func FormatAge(
	d time.Duration,
) string

FormatAge formats a duration as a human-readable age string. Returns "3d 4h", "12h 30m", "45m", "30s" etc.

func FormatBytes

func FormatBytes(
	b int,
) string

FormatBytes formats a byte count as a human-readable string (e.g., "5.2 KB", "1.0 MB").

func FormatLabels

func FormatLabels(
	labels map[string]string,
) string

FormatLabels formats a label map as "key:value, key:value" sorted by key.

func FormatList

func FormatList(
	list []string,
) string

FormatList helper function to convert []string to a formatted string.

func GetMaxLineWidth

func GetMaxLineWidth(
	text string,
) int

GetMaxLineWidth returns the width of the longest line in a multi-line string.

func HandleError

func HandleError(
	err error,
	logger *slog.Logger,
)

HandleError logs the error and exits with code 1.

func IntToSafeString

func IntToSafeString(
	i *int,
) string

IntToSafeString converts a *int to a string. Returns "N/A" if nil.

func IsOSFamilySupported

func IsOSFamilySupported(
	distro string,
	version string,
) (string, bool)

IsOSFamilySupported checks if the given distribution and version belong to a supported OS family. Returns the family name and true if supported.

func LogFatal

func LogFatal(
	logger *slog.Logger,
	message string,
	err error,
	kvPairs ...any,
)

LogFatal logs a fatal error message along with optional structured data and then exits the program with a status code of 1.

func MaxExitCode

func MaxExitCode(
	results []RawResult,
) int

MaxExitCode returns the highest exit code from a slice of RawResults.

func ParseJetstreamStorageType

func ParseJetstreamStorageType(
	s string,
) jetstream.StorageType

ParseJetstreamStorageType maps "memory"/"file" strings to jetstream.StorageType.

func PrintCompactTable

func PrintCompactTable(
	sections []Section,
)

PrintCompactTable renders a compact column-aligned table (kubectl-style). Headers are uppercase purple, data rows are teal, with 2-space indent. Multi-line cell values are flattened to a single line and long values are truncated with an ellipsis.

func PrintErrors

func PrintErrors(
	errors []ErrorEntry,
)

PrintErrors renders error and skip entries below a table. Errors are red, skips are yellow. Each entry shows hostname and message.

func PrintKV

func PrintKV(
	pairs ...string,
)

PrintKV prints labeled key-value pairs on a single indented line. Pairs are padded to equal column widths for alignment. Arguments alternate between labels and values: label1, val1, label2, val2, ...

func PrintRawOutput

func PrintRawOutput(
	stdout io.Writer,
	stderr io.Writer,
	results []RawResult,
	showStdout bool,
	showStderr bool,
)

PrintRawOutput writes raw command output to the given writers.

Every line is prefixed with a styled hostname, including a single result: a command run against one host today is run against ten tomorrow, and output that changes shape with the number of hosts cannot be parsed by anything downstream. showStdout/showStderr control which streams are printed.

func PrintRawOutputPlain

func PrintRawOutputPlain(
	stdout io.Writer,
	stderr io.Writer,
	results []RawResult,
	showStdout bool,
	showStderr bool,
)

PrintRawOutputPlain writes raw output without lipgloss styling. Used for testing and non-TTY output.

func RunServer

func RunServer(
	ctx context.Context,
	server Lifecycle,
	cleanupFns ...func(context.Context),
)

RunServer blocks until ctx is cancelled, then shuts down the server and runs the cleanup functions, all within ShutdownTimeout.

Cleanup receives the same context the server did, so one budget covers the whole shutdown rather than each phase having its own and the total being unbounded. A cleanup that ignores its context can still overrun; the ones here pass it to the calls that block.

func SafeString

func SafeString(
	s *string,
) string

SafeString function to safely dereference string pointers.

func SafeUUID

func SafeUUID(
	u *uuid.UUID,
) string

SafeUUID converts a *uuid.UUID to its string representation. Returns "" if nil.

func ValidateDistribution

func ValidateDistribution(
	logger *slog.Logger,
)

ValidateDistribution checks if the CLI is being run on a supported OS family.

Types

type ErrorEntry

type ErrorEntry struct {
	Hostname string
	Message  string
	Status   string // "err" or "skip"
}

ErrorEntry is an error or skip reason from a host, rendered below the table.

type Lifecycle

type Lifecycle interface {
	// Start starts the server without blocking.
	Start()
	// Stop gracefully shuts down the server.
	Stop(ctx context.Context)
}

Lifecycle represents a long-running server or agent.

type OSFamily

type OSFamily struct {
	// Name is the family name following Ansible conventions (e.g., "Debian", "RedHat").
	Name string
	// Distributions maps distribution names to their supported versions.
	Distributions map[string][]string
}

OSFamily represents a supported OS family with its member distributions.

type RawResult

type RawResult struct {
	Hostname string
	Stdout   string
	Stderr   string
	ExitCode int
}

RawResult holds raw command output for a single host.

type ResultRow

type ResultRow struct {
	Hostname string
	Status   string
	Changed  *bool
	Error    *string
	Fields   []string
}

ResultRow is a per-host result used by BuildBroadcastTable and BuildMutationTable.

type Section

type Section struct {
	Title    string
	Headers  []string
	Rows     [][]string
	Errors   []ErrorEntry
	Duration string // e.g. "286ms" — shown in summary line
}

Section represents a header with its corresponding rows.

type TableResult

type TableResult struct {
	Headers []string
	Rows    [][]string
	Errors  []ErrorEntry
}

TableResult holds the output of BuildBroadcastTable / BuildMutationTable.

func BuildBroadcastTable

func BuildBroadcastTable(
	results []ResultRow,
	fieldHeaders []string,
) TableResult

BuildBroadcastTable builds a TableResult for a broadcast response. HOSTNAME and STATUS are always shown. Errors are collected for rendering below the table by PrintCompactTable.

func BuildMutationTable

func BuildMutationTable(
	results []ResultRow,
	fieldHeaders []string,
) TableResult

BuildMutationTable builds a TableResult for a mutation response. Uses the same unified STATUS column (ok/changed/skip/err).

Directories

Path Synopsis
Package mocks provides mock implementations for testing.
Package mocks provides mock implementations for testing.

Jump to

Keyboard shortcuts

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