cli

package
v0.3.5 Latest Latest
Warning

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

Go to latest
Published: Mar 31, 2026 License: Apache-2.0 Imports: 60 Imported by: 0

Documentation

Overview

Package cli implements the Cobra-based command-line interface for FinFocus.

The CLI provides the primary user interface with subcommands for:

  • cost projected: Calculate projected costs from Pulumi preview JSON
  • cost actual: Fetch actual historical costs with time ranges
  • plugin list: List installed plugins
  • plugin validate: Validate plugin installations

Usage Patterns

Commands use RunE for proper error handling and cmd.Printf() for output. Date inputs support multiple formats including "2006-01-02" and RFC3339.

Configuration

CLI flags take precedence over environment variables and config file settings. Debug output can be enabled with --debug flag or FINFOCUS_LOG_LEVEL=debug.

Index

Constants

View Source
const DirPermBase = 0o700

DirPermBase is the permission mode for the base and standard directories.

View Source
const DirPermPlugins = 0o750

DirPermPlugins is the permission mode for the plugins directory.

View Source
const MaxBudgetFilters = 100

MaxBudgetFilters is the maximum number of filter arguments allowed. This prevents potential DoS from excessive filter arguments.

View Source
const MaxBudgetTags = 50

MaxBudgetTags is the maximum number of tag filters allowed. This prevents memory exhaustion from unbounded tag map growth.

Variables

View Source
var DefaultPlugins = []string{
	"aws-public",
}

DefaultPlugins is the set of plugins installed by default during setup.

View Source
var ErrInvalidBudgetFilter = errors.New("invalid budget filter syntax")

ErrInvalidBudgetFilter is returned when a budget filter has invalid syntax.

View Source
var ErrPluginValidationFailed = errors.New("one or more plugins failed validation")

ErrPluginValidationFailed is returned when one or more plugins fail validation. This replaces os.Exit(1) to allow proper testing and error handling (SC-002 fix).

Functions

func ApplyFilters added in v0.2.2

func ApplyFilters(
	ctx context.Context,
	resources []engine.ResourceDescriptor,
	filters []string,
) ([]engine.ResourceDescriptor, error)

ApplyFilters validates and applies a slice of filter strings to a resource set. It logs validation failures and filter application results for debugging.

The function performs two passes:

  1. Validation: All filters are validated upfront. If any filter is invalid, an error is returned immediately without applying any filters.
  2. Application: Valid filters are applied sequentially, reducing the resource set.

An empty filter slice returns the original resources unchanged. A warning is logged if the filtered result is empty.

Filter syntax follows engine.ValidateFilter rules: "key=value" format (e.g., "type=aws:ec2/instance", "tag:env=prod").

func DetectPluginMode

func DetectPluginMode(args []string, lookupEnv func(string) (string, bool)) bool

DetectPluginMode determines if the application should run in Pulumi plugin mode. It checks the binary name and the FINFOCUS_PLUGIN_MODE environment variable. This is a pure function with no side effects and is safe to call multiple times.

args: usually os.Args (nil or empty is handled gracefully). lookupEnv: function to retrieve environment variables (e.g., os.LookupEnv).

If nil, environment variable detection is skipped.

func FormatStatus added in v0.3.0

func FormatStatus(status StepStatus, nonInteractive bool) string

FormatStatus returns a status marker appropriate for the output mode.

func HasStatusAnnotationsForTest added in v0.3.0

func HasStatusAnnotationsForTest(recs []TestableRecommendation) bool

HasStatusAnnotationsForTest is a test export for hasStatusAnnotations.

func InitCache added in v0.3.0

func InitCache(ctx context.Context, cmd *cobra.Command) cache.Cache

InitCache creates a cache.Cache instance based on configuration precedence: CLI flag (--cache-ttl) > env var (FINFOCUS_CACHE_TTL) > config file > default. Returns nil when caching is disabled (TTL<=0) or initialization fails. When --cache-ttl is explicitly set to 0, caching is disabled regardless of config/env.

func IsValidPluginName

func IsValidPluginName(name string) bool

IsValidPluginName reports whether the provided name satisfies the plugin naming rules. The name must be between 2 and 50 characters, contain only lowercase letters (`a`–`z`), digits (`0`–`9`) or hyphens (`-`), and must not start or end with a hyphen. It returns true when all conditions are met, false otherwise.

func NewAnalyzerCheckCmd added in v0.3.2

func NewAnalyzerCheckCmd() *cobra.Command

NewAnalyzerCheckCmd creates the analyzer check command.

func NewAnalyzerCmd

func NewAnalyzerCmd() *cobra.Command

NewAnalyzerCmd creates the analyzer command group for Pulumi Analyzer plugin functionality.

The analyzer command provides subcommands for running FinFocus as a Pulumi Analyzer plugin. This enables zero-click cost estimation during `pulumi preview` operations.

func NewAnalyzerInstallCmd added in v0.3.0

func NewAnalyzerInstallCmd() *cobra.Command

NewAnalyzerInstallCmd creates the analyzer install command.

This command installs the finfocus binary as a Pulumi analyzer plugin by creating a symlink (Unix) or copy (Windows) in the Pulumi plugin directory.

func NewAnalyzerServeCmd

func NewAnalyzerServeCmd() *cobra.Command

NewAnalyzerServeCmd creates the analyzer serve command.

This command starts the gRPC server for the Pulumi Analyzer plugin. It binds to a random TCP port and prints ONLY the port number to stdout (this is the handshake protocol with Pulumi engine).

exclusively for the port handshake.

func NewAnalyzerUninstallCmd added in v0.3.0

func NewAnalyzerUninstallCmd() *cobra.Command

NewAnalyzerUninstallCmd creates the analyzer uninstall command.

This command removes all installed analyzer-finfocus-v* directories from the Pulumi plugin directory.

func NewConfigGetCmd

func NewConfigGetCmd() *cobra.Command

NewConfigGetCmd creates the config get command for retrieving configuration values.

func NewConfigInitCmd

func NewConfigInitCmd() *cobra.Command

NewConfigInitCmd creates the config init command for initializing configuration. When run inside a Pulumi project (without --global), it creates a project-local .finfocus/ directory with config.yaml and .gitignore. Otherwise, it creates the global ~/.finfocus/config.yaml.

func NewConfigListCmd

func NewConfigListCmd() *cobra.Command

NewConfigListCmd creates the config list command for listing all configuration values.

func NewConfigRoutesCmd added in v0.3.3

func NewConfigRoutesCmd() *cobra.Command

NewConfigRoutesCmd returns a Cobra command that groups plugin routing subcommands. It has no RunE of its own — it delegates to the list and test subcommands.

func NewConfigRoutesListCmd added in v0.3.3

func NewConfigRoutesListCmd() *cobra.Command

NewConfigRoutesListCmd returns a Cobra command that displays the effective routing configuration. It supports table (default) and JSON output formats via the --output flag.

func NewConfigRoutesTestCmd added in v0.3.3

func NewConfigRoutesTestCmd() *cobra.Command

NewConfigRoutesTestCmd returns a command that simulates plugin routing for a resource type.

func NewConfigSetCmd

func NewConfigSetCmd() *cobra.Command

NewConfigSetCmd creates the config set command for setting configuration values.

func NewConfigValidateCmd

func NewConfigValidateCmd() *cobra.Command

NewConfigValidateCmd returns a Cobra command that validates the application's configuration. The command checks general configuration syntax and routing semantics, including plugin existence, pattern and feature validation, priority values, and duplicate plugin detection. The returned command accepts a --verbose / -v flag to emit detailed validation information.

func NewCostActualCmd

func NewCostActualCmd() *cobra.Command

NewCostActualCmd creates the "actual" subcommand for fetching actual historical costs.

The command retrieves historical costs from cloud provider billing APIs or estimates costs based on Pulumi preview JSON or Pulumi state timestamps. When neither --pulumi-json nor --pulumi-state is provided the current Pulumi project is auto-detected and `pulumi stack export` is used; in that mode the --from date is auto-detected from the earliest resource Created timestamp. Common flags registered include --pulumi-json, --pulumi-state, --from, --to, --adapter, --output, --group-by, --estimate-confidence, --fallback-estimate, --filter, and --jobs. Validation of flag combinations is performed by executeCostActual.

func NewCostEstimateCmd added in v0.3.0

func NewCostEstimateCmd() *cobra.Command

NewCostEstimateCmd creates the "estimate" subcommand for what-if cost analysis.

The command supports two mutually exclusive modes:

1. Single-resource mode:

  • --provider (required), --resource-type (required), --property (optional, repeatable)
  • Estimates cost impact of property changes on a single resource

2. Plan-based mode:

  • --pulumi-json (required), --modify (optional, repeatable)
  • Estimates cost impact of modifications to resources in an existing Pulumi plan

Common flags:

  • --output: Output format (table, json, ndjson)
  • --interactive: Launch interactive TUI mode
  • --region: Region for cost calculation
  • --adapter: Use specific plugin adapter

Returns:

  • *cobra.Command: The configured estimate subcommand

func NewCostProjectedCmd

func NewCostProjectedCmd() *cobra.Command

NewCostProjectedCmd returns a Cobra command configured to calculate projected costs from a Pulumi preview JSON and render the results in table, JSON, or NDJSON formats. The command accepts either an explicit Pulumi preview JSON file or will auto-detect and run a Pulumi preview in the current project when the --pulumi-json flag is omitted.

The command registers the following flags:

  • --pulumi-json: optional path to a Pulumi preview JSON output (auto-detected if omitted).
  • --spec-dir: directory containing pricing specification files.
  • --adapter: restricts execution to a single adapter plugin.
  • --output: output format ("table", "json", or "ndjson").
  • --filter: repeatable resource filter expressions (e.g., "type=aws:ec2/instance").
  • --utilization: utilization rate for sustainability calculations (0.0 to 1.0).
  • --jobs, -j: number of parallel workers (0 = auto based on CPU count).

The returned command is ready to be added to the application's command tree.

func NewCostRecommendationsCmd

func NewCostRecommendationsCmd() *cobra.Command

NewCostRecommendationsCmd creates the "recommendations" subcommand that fetches cost optimization recommendations for resources described in a Pulumi preview JSON.

The command is configured with flags:

  • --pulumi-json (required): path to Pulumi preview JSON output
  • --adapter: restrict to a specific adapter plugin
  • --output: output format (table, json, ndjson; defaults from configuration)
  • --filter: filter expressions for recommendations (e.g., 'action=MIGRATE')

The returned *cobra.Command is ready to be added to the CLI command tree.

func NewOverviewCmd added in v0.3.0

func NewOverviewCmd() *cobra.Command

NewOverviewCmd constructs the "overview" Cobra command that displays a unified stack cost dashboard combining Pulumi state and preview data with cost information, drift analysis, and recommendations. It supports auto-detection of the Pulumi project/stack or explicit --pulumi-state / --pulumi-json inputs, and is configured with flags for date range, adapter, output format, resource filtering, interactive/plain mode, pagination, confirmation behavior, and budget controls (exit-on-threshold, exit-code, budget-scope).

func NewPluginCertifyCmd

func NewPluginCertifyCmd() *cobra.Command

NewPluginCertifyCmd creates the plugin certify command for running certification NewPluginCertifyCmd returns a Cobra command that runs the conformance suite against a plugin binary and generates a Markdown certification report. The command accepts a single plugin path argument and provides flags to control output and execution:

  • --output, -o: path to write the certification report (default: stdout)
  • --mode: communication mode, either "tcp" or "stdio" (default: "tcp")
  • --timeout: global certification timeout as a duration string (default: "10m")

The command prints progress and a summary; it exits with a non-zero code when certification is not achieved.

func NewPluginConformanceCmd

func NewPluginConformanceCmd() *cobra.Command

NewPluginConformanceCmd creates the plugin conformance command for running NewPluginConformanceCmd returns a Cobra command configured to run conformance tests against a plugin binary. The command verifies a plugin's protocol compliance and supports the following flags: --mode (tcp|stdio), --verbosity (quiet|normal|verbose|debug), --output (table|json|junit), --output-file, --timeout, --category (repeatable: protocol, error, performance, context), and --filter (regex for test names).

func NewPluginInitCmd

func NewPluginInitCmd() *cobra.Command

NewPluginInitCmd builds the Cobra command that scaffolds a plugin project and writes NewPluginInitCmd creates and returns a Cobra command for initializing a plugin development project. The command exposes "init <plugin-name>" and scaffolds a new plugin project including module setup, manifest, boilerplate source, Makefile, README, and example tests. It registers flags for author, providers, output directory, force overwrite, and fixture recording options (`--record-fixtures`, `--fixture-version`, `--offline`, `--strict`) and marks the author and providers flags as required.

func NewPluginInspectCmd

func NewPluginInspectCmd() *cobra.Command

NewPluginInspectCmd creates the plugin inspect command.

func NewPluginInstallCmd

func NewPluginInstallCmd() *cobra.Command

NewPluginInstallCmd creates the install command for installing plugins from registry or URL.

--plugin-dir         Custom plugin directory (default: ~/.finfocus/plugins)
--clean              Remove other versions after successful install
--fallback-to-latest Automatically install latest stable version if requested version lacks assets

NewPluginInstallCmd creates the "install" CLI command that installs a plugin from either the registry or a direct URL.

The returned *cobra.Command parses a single plugin specifier argument and supports options to control installation behavior, including reinstallation, saving to config, cleanup of other versions, custom plugin directory, and controlling fallback behavior when platform-specific assets are missing. It also accepts repeatable metadata key=value pairs that are passed through to the installer.

Notable flags:

  • --force, -f: reinstall even if the requested version already exists.
  • --no-save: do not add the plugin to the user's config file.
  • --clean: remove other installed versions after a successful install.
  • --plugin-dir: specify a custom plugin installation directory.
  • --fallback-to-latest: automatically attempt a compatible latest stable release if the requested version lacks assets.
  • --no-fallback: disable fallback behavior entirely (mutually exclusive with --fallback-to-latest).
  • --metadata: repeatable key=value pairs attached to the plugin install.

The command prints progress, shows a security warning for URL-based installs, and displays a concise install result. NewPluginInstallCmd creates the "install" subcommand for installing plugins from a registry or URL. The command accepts a single plugin specifier argument and configures flags for force reinstall, skipping save, cleaning other versions, custom plugin directory, fallback controls, and repeatable metadata key=value pairs. The command validates the specifier, displays security warnings when appropriate, parses metadata, constructs an installer, attempts installation (with fallback and cleanup behavior controlled by flags), and prints progress and results. It returns the configured *cobra.Command.

func NewPluginListCmd

func NewPluginListCmd() *cobra.Command

NewPluginListCmd creates a Cobra "list" command for displaying plugins. The command lists installed plugins by default and supports an `--verbose` flag for detailed output and an `--available` flag to list plugins from the registry. It returns the configured *cobra.Command.

func NewPluginRemoveCmd

func NewPluginRemoveCmd() *cobra.Command

NewPluginRemoveCmd returns a Cobra command configured to remove an installed plugin. The command accepts a single plugin name argument and provides the flags `--keep-config` to retain the plugin entry in the configuration and `--plugin-dir` to specify a custom plugin directory. On execution it removes the plugin files and, unless `--keep-config` is set, removes the plugin entry from the configuration. The command's execution returns an error if removal fails.

func NewPluginUpdateCmd

func NewPluginUpdateCmd() *cobra.Command

NewPluginUpdateCmd returns a Cobra command that updates an installed plugin to the latest or a specified version. The command requires a single positional argument (plugin name) and provides the following flags:

--dry-run   Show what would be updated without making changes.
--version   Specific version to update to (default: latest).
--plugin-dir Custom plugin directory.

NewPluginUpdateCmd returns a cobra command that updates an installed plugin to the latest version or to a specified version. The command accepts a single plugin name argument and supports the flags --dry-run (show changes without applying), --version (target version), and --plugin-dir (custom plugin directory). It prints progress messages and a summary of the result (including name, old/new versions, and path).

The command's execution returns an error if the underlying installer fails to perform the NewPluginUpdateCmd returns a *cobra.Command configured to update an installed plugin. The command expects a single positional argument (plugin name) and updates that plugin to the latest version or to a specific version supplied via the --version flag. It supports --dry-run to preview changes and --plugin-dir to override the plugin directory. The command prints progress and summary information and returns an error if the update operation fails.

func NewPluginValidateCmd

func NewPluginValidateCmd() *cobra.Command

NewPluginValidateCmd creates the plugin validate command for validating plugin installations.

func NewRootCmd

func NewRootCmd(ver string) *cobra.Command

NewRootCmd creates the root Cobra command for the finfocus CLI. It wires up logging, tracing, audit logging, and subcommands (cost, plugin, config, analyzer, overview, setup). The command dynamically adjusts its Use and Example strings based on whether it's running as a Pulumi tool plugin (detected via binary name or FINFOCUS_PLUGIN_MODE env var).

func NewRootCmdWithArgs

func NewRootCmdWithArgs(
	ver string,
	args []string,
	lookupEnv func(string) (string, bool),
) *cobra.Command

NewRootCmdWithArgs creates the root command with explicit args and env lookup for testability. This allows tests to inject custom args and environment variables.

func NewSetupCmd added in v0.3.0

func NewSetupCmd() *cobra.Command

NewSetupCmd creates the top-level setup command that bootstraps the FinFocus environment.

func NewSetupCmdWithRunner added in v0.3.0

func NewSetupCmdWithRunner(runner *SetupRunner) *cobra.Command

NewSetupCmdWithRunner creates the setup command with the given runner for dependency injection.

func ParseBudgetFilters added in v0.3.0

func ParseBudgetFilters(ctx context.Context, filters []string) (*engine.BudgetFilterOptions, error)

ParseBudgetFilters parses a slice of filter strings into BudgetFilterOptions. Filter syntax:

  • "provider=<name>": Filter by provider (e.g., "provider=kubecost")
  • "tag:<key>=<value>": Filter by metadata tag (e.g., "tag:namespace=production")

Provider filters use OR logic (any provider matches). Tag filters use AND logic (all tags must match). Tag values support glob patterns (e.g., "tag:namespace=prod-*").

Returns an error if any filter has invalid syntax per ValidateBudgetFilter, or if input limits are exceeded (MaxBudgetFilters, MaxBudgetTags).

func ParseModifications added in v0.3.0

func ParseModifications(mods []string) (map[string]map[string]string, error)

ParseModifications parses --modify resource:key=value flags into a map. Exported for testing.

Parameters:

  • mods: Slice of strings in "resource:key=value" format

Returns:

  • map[string]map[string]string: Map of resource name to property overrides
  • error: If any modification has invalid format or exceeds limits

func ParsePropertyOverrides added in v0.3.0

func ParsePropertyOverrides(props []string) (map[string]string, error)

ParsePropertyOverrides parses --property key=value flags into a map. Exported for testing.

Parameters:

  • props: Slice of strings in "key=value" format

Returns:

  • map[string]string: Parsed key-value pairs
  • error: If any property has invalid format or exceeds limits

func ParseTime

func ParseTime(str string) (time.Time, error)

ParseTime parses str as a date in either "YYYY-MM-DD" or RFC3339 format. It validates that the parsed time is not in the future and is not more than maxPastYears years in the past.

func ParseTimeRange

func ParseTimeRange(fromStr, toStr string) (time.Time, time.Time, error)

ParseTimeRange parses the provided from and to date strings into time values and validates that the range is chronological.

ParseTimeRange accepts two date strings, parses each into a time.Time, and ensures the 'to' time is after the 'from' time. It returns the parsed from and to times on success. If either date cannot be parsed or if the 'to' time is not after the 'from' time, an error is returned describing the failure. Additionally validates that the date range does not exceed maximum limits.

func RenderActualCostOutput

func RenderActualCostOutput(
	ctx context.Context,
	cmd *cobra.Command,
	outputFormat string,
	resultWithErrors *engine.CostResultWithErrors,
	groupBy string,
	estimateConfidence bool,
) error

RenderActualCostOutput routes actual cost results to the appropriate rendering function. The context parameter enables trace ID propagation for contextual logging.

func RenderBudgetStatus added in v0.2.4

func RenderBudgetStatus(w io.Writer, status *engine.BudgetStatus) error

RenderBudgetStatus renders the budget status to the writer. It automatically detects if the output is a TTY and renders appropriately: - TTY: Styled output with colors and borders using Lip Gloss. RenderBudgetStatus renders the given budget status to w using a terminal-styled bordered box when w is a TTY or plain text suitable for non-interactive outputs otherwise.

w is the destination for the rendered output. status is the budget status to render; if status is nil, the function performs no output and returns nil.

The function returns any error produced by the chosen rendering implementation.

func RenderCostOutput

func RenderCostOutput(
	ctx context.Context,
	cmd *cobra.Command,
	outputFormat string,
	resultWithErrors *engine.CostResultWithErrors,
) error

RenderCostOutput routes the cost results to the appropriate rendering function based on the detected output mode (Plain, Styled, or Interactive). The context parameter enables trace ID propagation for contextual logging.

func RenderRecommendationsJSONForTest

func RenderRecommendationsJSONForTest(w io.Writer, recs []TestableRecommendation) error

RenderRecommendationsJSONForTest is a test export for renderRecommendationsJSON.

func RenderRecommendationsNDJSONForTest

func RenderRecommendationsNDJSONForTest(w io.Writer, recs []TestableRecommendation) error

RenderRecommendationsNDJSONForTest is a test export for renderRecommendationsNDJSON.

func RenderRecommendationsOutput

func RenderRecommendationsOutput(
	_ context.Context,
	cmd *cobra.Command,
	outputFormat string,
	result *engine.RecommendationsResult,
	verbose bool,
	paginationMeta *pagination.PaginationMeta,
) error

RenderRecommendationsOutput routes the recommendations results to the appropriate rendering function based on the output format and terminal mode. In interactive terminals, it launches the TUI; otherwise, it renders table output. Returns an error if result is nil.

func RenderRecommendationsSummaryForTest

func RenderRecommendationsSummaryForTest(w io.Writer, recs []TestableRecommendation)

RenderRecommendationsSummaryForTest is a test export for renderRecommendationsSummary.

func RenderRecommendationsTableVerboseForTest

func RenderRecommendationsTableVerboseForTest(w io.Writer, recs []TestableRecommendation, verbose bool) error

RenderRecommendationsTableVerboseForTest is a test export for renderRecommendationsTableWithVerbose.

func RenderScopedBudgetStatus added in v0.2.6

func RenderScopedBudgetStatus(w io.Writer, result *engine.ScopedBudgetResult, filter *BudgetScopeFilter) error

RenderScopedBudgetStatus renders the hierarchical scoped budget result to the writer. It automatically detects if the output is a TTY and renders appropriately.

func RunAnalyzerServe

func RunAnalyzerServe(cmd *cobra.Command) error

RunAnalyzerServe starts the Pulumi Analyzer gRPC server, writes the selected listening port to stdout for the Pulumi plugin handshake, and runs until the RunAnalyzerServe starts a Pulumi gRPC analyzer server, prints the assigned port number to stdout for the Pulumi plugin handshake, and blocks until shutdown.

The provided Cobra command's context is used for cancellation. The function installs signal handlers for SIGINT and SIGTERM and performs a graceful shutdown when a termination signal is received or when the command context is canceled. It also sets the analyzer mode environment variable to indicate analyzer-only operation and may load project-specific configuration and plugins as part of server setup.

Parameters:

  • cmd: the Cobra command whose context controls lifecycle and cancellation.

Returns:

  • an error if the server fails to bind to a TCP port, if the listener's address cannot be determined, or if the gRPC server fails while serving; returns nil on normal graceful shutdown.

func RunPluginInit

func RunPluginInit(cmd *cobra.Command, opts *PluginInitOptions) error

RunPluginInit validates the provided PluginInitOptions, creates the target project directory (honoring the force flag), generates the boilerplate project files, and prints progress and next-step instructions to the command output. RunPluginInit initializes a new plugin project on disk and scaffolds all required files.

RunPluginInit validates the plugin name and provider list, creates the project directory, generates project files, and optionally runs a fixture recording workflow to populate testdata. It prints progress and next-step instructions to the provided Cobra command's output.

cmd is the Cobra command used for printing progress and for deriving context. opts provides initialization options such as Name, Author, Providers, OutputDir, Force, and flags controlling fixture recording.

It returns an error if validation fails (invalid name or no providers), if the project directory cannot be created, if file generation fails, or if the optional fixture recording workflow fails when the Strict option is set.

func ValidateBudgetFilter added in v0.3.0

func ValidateBudgetFilter(filter string) error

ValidateBudgetFilter validates a single budget filter string. Valid formats:

  • "provider=<value>": Provider filter (value required)
  • "tag:<key>=<value>": Tag filter (key required, value can be empty, supports glob patterns)

Returns an error for invalid syntax:

  • Missing "=" in tag filter
  • Empty key after "tag:"
  • Invalid glob pattern in tag value
  • Unknown filter prefix

func ValidateDateRange

func ValidateDateRange(from, to time.Time) error

ValidateDateRange validates that the date range is within acceptable limits. Returns an error if the range exceeds maxDateRangeDays (approximately 1 year).

func ValidateEstimateFlags added in v0.3.0

func ValidateEstimateFlags(params *CostEstimateParams) error

ValidateEstimateFlags validates that the estimate command flags are consistent. Exported for testing.

Rules:

  • Single-resource mode requires both --provider and --resource-type
  • Plan-based mode requires --pulumi-json
  • --property is only valid in single-resource mode
  • --modify is only valid in plan-based mode
  • Modes are mutually exclusive

Returns an error describing the validation failure, or nil if valid.

func ValidatePlugin

func ValidatePlugin(_ context.Context, plugin registry.PluginInfo) error

ValidatePlugin validates a plugin's binary and its optional manifest. It ensures the binary exists at plugin.Path, is not a directory, and has the executable bit set. If a manifest file named "plugin.manifest.json" exists in the same directory, it is loaded and its Name and Version fields are compared to plugin.Name and plugin.Version. The function returns nil when all checks pass; otherwise it returns an error describing the first failing check (missing binary, stat error, path is a directory, not executable, invalid manifest, or manifest name/version mismatch).

ctx is reserved for future use and is not inspected. plugin provides the plugin's Path, Name, and Version used for validation.

func WithReleaseTagFetcher added in v0.2.4

func WithReleaseTagFetcher(
	fetcher func(context.Context) (string, error),
) func(*FixtureResolver)

WithReleaseTagFetcher configures a custom release tag fetcher function.

Types

type AnalyzerInstaller added in v0.3.0

type AnalyzerInstaller interface {
	Install(ctx context.Context, opts analyzer.InstallOptions) (*analyzer.InstallResult, error)
}

AnalyzerInstaller is the interface for installing the Pulumi analyzer.

type AnalyzerInstallerFunc added in v0.3.0

type AnalyzerInstallerFunc func(ctx context.Context, opts analyzer.InstallOptions) (*analyzer.InstallResult, error)

AnalyzerInstallerFunc is a function adapter for AnalyzerInstaller.

func (AnalyzerInstallerFunc) Install added in v0.3.0

Install delegates to the underlying function.

type BudgetExitError added in v0.2.5

type BudgetExitError struct {
	ExitCode int
	Reason   string
}

BudgetExitError is a sentinel error that carries an exit code for budget threshold violations. It is used to communicate the exit code from budget evaluation to the CLI layer.

func (*BudgetExitError) Error added in v0.2.5

func (e *BudgetExitError) Error() string

type BudgetRenderResult added in v0.2.6

type BudgetRenderResult struct {
	// LegacyStatus is set when using legacy budget configuration.
	LegacyStatus *engine.BudgetStatus
	// ScopedResult is set when using scoped budget configuration.
	ScopedResult *engine.ScopedBudgetResult
}

BudgetRenderResult holds the result of budget rendering for exit code evaluation. It can contain either a legacy BudgetStatus or a ScopedBudgetResult.

type BudgetScopeFilter added in v0.2.6

type BudgetScopeFilter struct {
	// ShowGlobal displays the global budget section.
	ShowGlobal bool
	// ShowProvider displays the BY PROVIDER section.
	ShowProvider bool
	// ShowTag displays the BY TAG section.
	ShowTag bool
	// ShowType displays the BY TYPE section.
	ShowType bool
	// ProviderFilter limits provider display to specific providers.
	ProviderFilter []string
	// TagFilter limits tag display to specific tag selectors.
	TagFilter []string
	// TypeFilter limits type display to specific resource types.
	TypeFilter []string
}

BudgetScopeFilter defines which budget scopes to render.

func NewBudgetScopeFilter added in v0.2.6

func NewBudgetScopeFilter(scopeFlag string) *BudgetScopeFilter

NewBudgetScopeFilter creates a filter from a --budget-scope flag value. Empty string means show all scopes. Otherwise, accepts comma-separated values: - "global" - show global budget only - "provider" - show BY PROVIDER section - "provider=aws" - show only AWS provider budget - "tag" - show BY TAG section - "tag=team:platform" - show only the specific tag budget - "type" - show BY TYPE section - "type=aws:ec2/instance" - show only the specific resource type budget.

type CostEstimateParams added in v0.3.0

type CostEstimateParams struct {
	// Single-resource mode flags
	Provider     string
	ResourceType string
	Properties   []string // key=value format
	Region       string

	// Plan-based mode flags
	PlanPath string
	Modify   []string // resource:key=value format

	// Common flags
	Interactive bool
	Output      string
	Adapter     string
}

CostEstimateParams holds the parameters for the estimate cost command execution. Exported for testing.

type CostFlags added in v0.2.5

type CostFlags struct {
	ExitOnThreshold bool
	ExitCode        int
	BudgetScope     string // Filter which budget scopes to display (T025)
	Stack           string // Pulumi stack name for auto-detection
}

CostFlags holds the budget exit flags for the cost command group. These are persistent flags that apply to all cost subcommands.

type FixtureResolver added in v0.2.4

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

func NewFixtureResolver added in v0.2.4

func NewFixtureResolver(
	logger zerolog.Logger,
	offline bool,
	version, localBase string,
	opts ...func(*FixtureResolver),
) *FixtureResolver

NewFixtureResolver creates a FixtureResolver configured to resolve fixtures.

logger is used for structured logging. offline toggles local-only resolution when true. version selects the fixture version to resolve (e.g., "latest", a tag, "main", or "local"). localBase sets the base filesystem path to search for local fixtures. opts are optional configuration functions that can customize the resolver behavior.

The returned FixtureResolver is ready to resolve and (when not offline) download fixture sources.

func (*FixtureResolver) DownloadFixture added in v0.2.4

func (r *FixtureResolver) DownloadFixture(ctx context.Context, source *FixtureSource) (string, error)

func (*FixtureResolver) ResolvePlanFixture added in v0.2.4

func (r *FixtureResolver) ResolvePlanFixture(ctx context.Context, provider string) (*FixtureSource, error)

func (*FixtureResolver) ResolveStateFixture added in v0.2.4

func (r *FixtureResolver) ResolveStateFixture(ctx context.Context) (*FixtureSource, error)

type FixtureSource added in v0.2.4

type FixtureSource struct {
	ID       string
	Type     string
	Provider string
	Version  string
	Origin   string
	Checksum string
}

type PluginInitOptions

type PluginInitOptions struct {
	Name           string
	Author         string
	Providers      []string
	OutputDir      string
	Force          bool
	RecordFixtures bool
	FixtureVersion string
	Offline        bool
	Strict         bool
}

PluginInitOptions contains configuration options for plugin initialization.

type PluginInstaller added in v0.3.0

type PluginInstaller interface {
	Install(
		ctx context.Context,
		specifier string,
		opts registry.InstallOptions,
		progress func(string),
	) (*registry.InstallResult, error)
}

PluginInstaller is the interface for installing plugins.

type PluginInstallerFunc added in v0.3.0

type PluginInstallerFunc func(
	ctx context.Context,
	specifier string,
	opts registry.InstallOptions,
	progress func(string),
) (*registry.InstallResult, error)

PluginInstallerFunc is a function adapter for PluginInstaller.

func (PluginInstallerFunc) Install added in v0.3.0

func (f PluginInstallerFunc) Install(
	ctx context.Context,
	specifier string,
	opts registry.InstallOptions,
	progress func(string),
) (*registry.InstallResult, error)

Install delegates to the underlying function.

type PluginJSONEntry added in v0.3.0

type PluginJSONEntry struct {
	Name               string   `json:"name"`
	Version            string   `json:"version"`
	Path               string   `json:"path"`
	SpecVersion        string   `json:"specVersion"`
	RuntimeVersion     string   `json:"runtimeVersion"`
	SupportedProviders []string `json:"supportedProviders"`
	Capabilities       []string `json:"capabilities"`
	Notes              string   `json:"notes,omitempty"`
}

PluginJSONEntry is the JSON-serializable representation of a plugin for the --output json format. It matches the plugin-list-json contract schema.

type PromptResult added in v0.2.3

type PromptResult struct {
	// Accepted is true if the user accepted the prompt (typed "y" or "Y")
	Accepted bool
	// TimedOut is true if the prompt timed out waiting for input (reserved for future use)
	TimedOut bool
	// Cancelled is true if the user explicitly cancelled (e.g., Ctrl+C)
	Cancelled bool
}

PromptResult contains the result of a user prompt interaction.

func ConfirmFallback added in v0.2.3

func ConfirmFallback(
	writer io.Writer,
	reader io.Reader,
	pluginName string,
	requestedVersion string,
	fallbackVersion string,
	platform string,
) PromptResult

ConfirmFallback prompts the user to confirm fallback to an alternative version. It returns immediately with Accepted=false in non-interactive (non-TTY) environments.

Parameters:

  • writer: where to write the prompt message (typically cmd.OutOrStdout())
  • reader: where to read user input from (typically os.Stdin)
  • pluginName: name of the plugin being installed
  • requestedVersion: the version originally requested
  • fallbackVersion: the version being offered as fallback
  • platform: the platform string (e.g., "linux/amd64")

The prompt defaults to "No" (abort) when the user presses Enter without input. Valid inputs: "y", "Y", "yes", "Yes", "YES" for acceptance; anything else declines.

func ConfirmFallbackWithStdin added in v0.2.3

func ConfirmFallbackWithStdin(
	writer io.Writer,
	pluginName string,
	requestedVersion string,
	fallbackVersion string,
	platform string,
) PromptResult

ConfirmFallbackWithStdin is a convenience wrapper that uses os.Stdin as the reader.

type RecordedRequest added in v0.2.4

type RecordedRequest struct {
	Type      string    `json:"type"`
	Path      string    `json:"path"`
	Timestamp time.Time `json:"timestamp"`
}

type RecorderWorkflow added in v0.2.4

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

func NewRecorderWorkflow added in v0.2.4

func NewRecorderWorkflow(logger zerolog.Logger, outputDir string) *RecorderWorkflow

NewRecorderWorkflow creates a RecorderWorkflow configured with the provided logger and output directory. It initializes an internal RecordingSession with a generated session ID, the given output directory, the current start time, and a status of "initialized". logger is used for workflow logging. outputDir is the base directory where recorded request files and session data will be placed. It returns a pointer to the constructed RecorderWorkflow.

func (*RecorderWorkflow) CopyRecordedRequestsToTestdata added in v0.2.4

func (w *RecorderWorkflow) CopyRecordedRequestsToTestdata(targetDir string) error

func (*RecorderWorkflow) PrepareOutputDirectory added in v0.2.4

func (w *RecorderWorkflow) PrepareOutputDirectory() error

func (*RecorderWorkflow) RunWithRecorder added in v0.2.4

func (w *RecorderWorkflow) RunWithRecorder(
	ctx context.Context,
	planPath, statePath string,
	recordFixtures bool,
) error

func (*RecorderWorkflow) Session added in v0.2.4

func (w *RecorderWorkflow) Session() *RecordingSession

func (*RecorderWorkflow) SetFixtureDirectory added in v0.2.4

func (w *RecorderWorkflow) SetFixtureDirectory(path string)

func (*RecorderWorkflow) ValidateRecordings added in v0.2.4

func (w *RecorderWorkflow) ValidateRecordings() error

type RecordingSession added in v0.2.4

type RecordingSession struct {
	ID          string            `json:"id"`
	OutputDir   string            `json:"output_dir"`
	FixtureDir  string            `json:"fixture_dir"`
	StartedAt   time.Time         `json:"started_at"`
	CompletedAt time.Time         `json:"completed_at"`
	Status      string            `json:"status"`
	Errors      []string          `json:"errors,omitempty"`
	Recorded    []RecordedRequest `json:"recorded,omitempty"`
}

type RouteMatchOutput added in v0.3.3

type RouteMatchOutput struct {
	Rank        int    `json:"rank"`
	Plugin      string `json:"plugin"`
	Priority    int    `json:"priority"`
	MatchReason string `json:"match_reason"`
	Source      string `json:"source"`
	Fallback    bool   `json:"fallback"`
}

RouteMatchOutput represents a single plugin match in the test output.

type RouteRuleOutput added in v0.3.3

type RouteRuleOutput struct {
	Plugin   string   `json:"plugin"`
	Priority int      `json:"priority"`
	Features []string `json:"features"`
	Patterns []string `json:"patterns"`
	Fallback bool     `json:"fallback"`
}

RouteRuleOutput represents a single routing rule in the list output.

type RoutesListOutput added in v0.3.3

type RoutesListOutput struct {
	Mode       string            `json:"mode"`
	ConfigPath string            `json:"config_path"`
	Source     string            `json:"source"`
	Rules      []RouteRuleOutput `json:"rules"`
}

RoutesListOutput is the JSON output structure for the config routes list command.

type RoutesTestOutput added in v0.3.3

type RoutesTestOutput struct {
	ResourceType string             `json:"resource_type"`
	Region       string             `json:"region,omitempty"`
	Provider     string             `json:"provider"`
	Mode         string             `json:"mode"`
	Matches      []RouteMatchOutput `json:"matches"`
	Features     map[string]string  `json:"features"`
}

RoutesTestOutput is the JSON output structure for the config routes test command.

type SetupOptions added in v0.3.0

type SetupOptions struct {
	SkipAnalyzer   bool `json:"skipAnalyzer,omitempty"   yaml:"skipAnalyzer,omitempty"`
	SkipPlugins    bool `json:"skipPlugins,omitempty"    yaml:"skipPlugins,omitempty"`
	NonInteractive bool `json:"nonInteractive,omitempty" yaml:"nonInteractive,omitempty"`
}

SetupOptions holds the configuration for the setup command, derived from CLI flags.

type SetupResult added in v0.3.0

type SetupResult struct {
	Steps       []StepResult `json:"steps,omitempty"       yaml:"steps,omitempty"`
	HasErrors   bool         `json:"hasErrors,omitempty"   yaml:"hasErrors,omitempty"`
	HasWarnings bool         `json:"hasWarnings,omitempty" yaml:"hasWarnings,omitempty"`
}

SetupResult is the aggregate outcome of all setup steps.

type SetupRunner added in v0.3.0

type SetupRunner struct {
	AnalyzerInstaller AnalyzerInstaller
	PluginInstaller   PluginInstaller
}

SetupRunner holds injectable dependencies for setup steps that require external services (analyzer installation, plugin installation).

func NewSetupRunner added in v0.3.0

func NewSetupRunner() *SetupRunner

NewSetupRunner returns a SetupRunner wired with production defaults.

func (*SetupRunner) StepInstallAnalyzer added in v0.3.0

func (r *SetupRunner) StepInstallAnalyzer(ctx context.Context) StepResult

StepInstallAnalyzer installs the Pulumi analyzer using the runner's AnalyzerInstaller.

func (*SetupRunner) StepInstallPlugins added in v0.3.0

func (r *SetupRunner) StepInstallPlugins(ctx context.Context, baseDir string) []StepResult

StepInstallPlugins installs the default plugin set. Returns one StepResult per plugin in the default set. baseDir is the resolved FinFocus home directory (e.g., ~/.finfocus).

type StepResult added in v0.3.0

type StepResult struct {
	Name     string     `json:"name"               yaml:"name"`
	Status   StepStatus `json:"status"             yaml:"status"`
	Message  string     `json:"message"            yaml:"message"`
	Critical bool       `json:"critical,omitempty" yaml:"critical,omitempty"`
	Err      error      `json:"-"                  yaml:"-"`
}

StepResult describes the outcome of executing a single setup step.

func StepCreateDirectories added in v0.3.0

func StepCreateDirectories(baseDir string) []StepResult

StepCreateDirectories creates the required FinFocus directories. Returns one StepResult per directory.

func StepDetectPulumi added in v0.3.0

func StepDetectPulumi(ctx context.Context) StepResult

StepDetectPulumi checks if the pulumi CLI is on PATH and reports its version.

func StepDisplayVersion added in v0.3.0

func StepDisplayVersion() StepResult

StepDisplayVersion prints the FinFocus version and Go runtime info.

func StepInitConfig added in v0.3.0

func StepInitConfig(baseDir string) StepResult

StepInitConfig initializes the default config file if one does not exist.

type StepStatus added in v0.3.0

type StepStatus int

StepStatus represents the outcome of a single setup step.

const (
	// StepSuccess indicates the step completed successfully.
	StepSuccess StepStatus = iota
	// StepWarning indicates the step completed with a non-fatal issue.
	StepWarning
	// StepSkipped indicates the step was intentionally skipped via flag.
	StepSkipped
	// StepError indicates the step failed.
	StepError
)

func (StepStatus) MarshalJSON added in v0.3.0

func (s StepStatus) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler to output StepStatus as a string.

func (StepStatus) String added in v0.3.0

func (s StepStatus) String() string

String returns the human-readable label for a StepStatus.

func (*StepStatus) UnmarshalJSON added in v0.3.0

func (s *StepStatus) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler to parse StepStatus from a string.

type TestableRecommendation

type TestableRecommendation struct {
	ResourceID       string
	Type             string
	Description      string
	EstimatedSavings float64
	Currency         string
	Status           string
}

TestableRecommendation is a test-friendly version of engine.Recommendation. It's used to avoid circular imports in tests.

func ApplyActionTypeFilterForTest

func ApplyActionTypeFilterForTest(
	recs []TestableRecommendation,
	filter string,
) ([]TestableRecommendation, error)

ApplyActionTypeFilterForTest is a test export for applyActionTypeFilter.

func MergeDismissedRecommendationsForTest added in v0.3.0

func MergeDismissedRecommendationsForTest(
	recs []TestableRecommendation,
	storePath string,
) ([]TestableRecommendation, error)

MergeDismissedRecommendationsForTest is a test export for mergeDismissedRecommendations.

func SortRecommendationsBySavingsForTest

func SortRecommendationsBySavingsForTest(recs []TestableRecommendation) []TestableRecommendation

SortRecommendationsBySavingsForTest is a test export for sortRecommendationsBySavings.

Directories

Path Synopsis
Package pagination provides utilities for CLI pagination, sorting, and result formatting.
Package pagination provides utilities for CLI pagination, sorting, and result formatting.

Jump to

Keyboard shortcuts

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