cmd

package
v1.197.0 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2025 License: Apache-2.0 Imports: 73 Imported by: 0

Documentation

Index

Constants

View Source
const (
	IdentityFlagName = "identity"
	// IdentityFlagSelectValue is imported from cfg.IdentityFlagSelectValue.
	IdentityFlagSelectValue = cfg.IdentityFlagSelectValue
)
View Source
const (
	ErrFmtWrapErr = "%w: %v" // Format for wrapping errors.
)

Error format strings.

Variables

View Source
var (
	ErrInvalidOutputType = fmt.Errorf("invalid output type specified. Valid values are 'list', 'map', and 'all'")
	ErrInvalidFormat     = fmt.Errorf("invalid format specified. Valid values are 'yaml' and 'json'")
)
View Source
var (
	ErrGettingCommonFlags    = pkgerrors.New("error getting common flags")
	ErrGettingAbstractFlag   = pkgerrors.New("error getting abstract flag")
	ErrGettingVarsFlag       = pkgerrors.New("error getting vars flag")
	ErrInitializingCLIConfig = pkgerrors.New("error initializing CLI config")
	ErrDescribingStacks      = pkgerrors.New("error describing stacks")
	ErrComponentNameRequired = pkgerrors.New("component name is required")
	ErrInvalidArguments      = pkgerrors.New("invalid arguments: the command requires one argument 'component'")
)
View Source
var RootCmd = &cobra.Command{
	Use:                "atmos",
	Short:              "Universal Tool for DevOps and Cloud Automation",
	Long:               `Atmos is a universal tool for DevOps and cloud automation used for provisioning, managing and orchestrating workflows across various toolchains`,
	FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true},
	PersistentPreRun: func(cmd *cobra.Command, args []string) {

		isHelpCommand := cmd.Name() == "help"
		helpFlag := cmd.Flags().Changed("help")

		isHelpRequested := isHelpCommand || helpFlag

		if isHelpRequested {

			cmd.SilenceUsage = false
			cmd.SilenceErrors = false
		} else {
			cmd.SilenceUsage = true
			cmd.SilenceErrors = true
		}

		if err := processChdirFlag(cmd); err != nil {
			errUtils.CheckErrorPrintAndExit(err, "", "")
		}

		configAndStacksInfo := schema.ConfigAndStacksInfo{}

		if bp, _ := cmd.Flags().GetString("base-path"); bp != "" {
			configAndStacksInfo.AtmosBasePath = bp
		}
		if cfgFiles, _ := cmd.Flags().GetStringSlice("config"); len(cfgFiles) > 0 {
			configAndStacksInfo.AtmosConfigFilesFromArg = cfgFiles
		}
		if cfgDirs, _ := cmd.Flags().GetStringSlice("config-path"); len(cfgDirs) > 0 {
			configAndStacksInfo.AtmosConfigDirsFromArg = cfgDirs
		}

		tmpConfig, err := cfg.InitCliConfig(configAndStacksInfo, false)
		if err != nil {
			if errors.Is(err, cfg.NotFound) {

				if !isHelpRequested {
					log.Warn(err.Error())
				}
			} else {
				errUtils.CheckErrorPrintAndExit(err, "", "")
			}
		}

		if !isHelpRequested {
			if setupErr := setupProfiler(cmd, &tmpConfig); setupErr != nil {
				errUtils.CheckErrorPrintAndExit(setupErr, "Failed to setup profiler", "")
			}
		}

		if cmd.Flags().Changed("version") {
			if versionFlag, err := cmd.Flags().GetBool("version"); err == nil && versionFlag {
				versionErr := e.NewVersionExec(&tmpConfig).Execute(false, "")
				if versionErr != nil {
					errUtils.CheckErrorPrintAndExit(versionErr, "", "")
				}
				errUtils.OsExit(0)
				return
			}
		}

		if showHeatmap, _ := cmd.Flags().GetBool("heatmap"); showHeatmap {
			perf.EnableTracking(true)
		}

		if !isCompletionCommand(cmd) && err == nil {
			telemetry.PrintTelemetryDisclosure()
		}
	},
	PersistentPostRun: func(cmd *cobra.Command, args []string) {

		if profilerServer != nil {
			if stopErr := profilerServer.Stop(); stopErr != nil {
				log.Error("Failed to stop profiler", "error", stopErr)
			}
		}

		if perf.IsTrackingEnabled() {
			heatmapMode, _ := cmd.Flags().GetString("heatmap-mode")

			if heatmapMode == "" {
				heatmapMode = "bar"
			}
			if err := displayPerformanceHeatmap(cmd, heatmapMode); err != nil {
				log.Error("Failed to display performance heatmap", "error", err)
			}
		}
	},
	RunE: func(cmd *cobra.Command, args []string) error {

		checkAtmosConfig()

		fmt.Println()
		err := tuiUtils.PrintStyledText("ATMOS")
		if err != nil {
			return err
		}

		err = e.ExecuteAtmosCmd()
		return err
	},
}

RootCmd represents the base command when called without any subcommands.

View Source
var SupportedFormats = []string{"json", "bash", "dotenv"}
View Source
var ValidateSchemaCmd = &cobra.Command{
	Use:   "schema",
	Short: "Validate YAML files against JSON schemas defined in atmos.yaml",
	Long: `The validate schema command reads the ` + "`" + `schemas` + "`" + ` section of the atmos.yaml file
and validates matching YAML files against their corresponding JSON schemas.

Each entry under ` + "`" + `schemas` + "`" + ` should define:
  - ` + "`" + `schema` + "`" + `: The path to the JSON schema file.
  - ` + "`" + `matches` + "`" + `: A glob pattern that specifies which YAML files to validate.

For every schema entry:
  - The JSON schema is loaded from the specified path.
  - All files matching the glob pattern are collected.
  - Each matching YAML file is parsed and converted to JSON.
  - The converted YAML is validated against the schema.

This command helps ensure that configuration files follow a defined structure
and are compliant with expected formats, reducing configuration drift and runtime errors.
`,
	FParseErrWhitelist: struct{ UnknownFlags bool }{UnknownFlags: false},
	Args:               cobra.MaximumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {

		checkAtmosConfig()

		schema := ""
		key := ""
		if len(args) > 0 {
			key = args[0]
		}

		if cmd.Flags().Changed("schemas-atmos-manifest") {
			schema, _ = cmd.Flags().GetString("schemas-atmos-manifest")
		}

		if key == "" && schema != "" {
			log.Error("key not provided for the schema to be used")
			errUtils.OsExit(1)
		}

		if err := exec.NewAtmosValidatorExecutor(&atmosConfig).ExecuteAtmosValidateSchemaCmd(key, schema); err != nil {
			if errors.Is(err, exec.ErrInvalidYAML) {
				errUtils.OsExit(1)
			}
			return err
		}

		return nil
	},
}

ValidateSchemaCmd represents the 'atmos validate schema' command.

This command reads the 'schemas' section from the atmos.yaml configuration file, where each schema entry specifies a JSON schema path and a glob pattern for matching YAML files.

For each entry:

  • The JSON schema is loaded.
  • All YAML files matching the glob pattern are discovered.
  • Each YAML file is converted to JSON and validated against the schema.

This command ensures that configuration files conform to expected structures and helps catch errors early in the development or deployment process.

View Source
var ValidateStacksCmd = &cobra.Command{
	Use:                "stacks",
	Short:              "Validate stack manifest configurations",
	Long:               "This command validates the configuration of stack manifests in Atmos to ensure proper setup and compliance.",
	Example:            "validate stacks",
	FParseErrWhitelist: struct{ UnknownFlags bool }{UnknownFlags: false},
	Args:               cobra.NoArgs,
	RunE: func(cmd *cobra.Command, args []string) error {

		checkAtmosConfig()

		err := exec.ExecuteValidateStacksCmd(cmd, args)
		if err != nil {
			return err
		}

		return nil
	},
}

ValidateStacksCmd validates stacks

Functions

func AddIdentityCompletion added in v1.195.0

func AddIdentityCompletion(cmd *cobra.Command)

AddIdentityCompletion registers shell completion for the identity flag if present on the command.

func AddStackCompletion added in v1.161.0

func AddStackCompletion(cmd *cobra.Command)

func CheckForAtmosUpdateAndPrintMessage added in v1.127.0

func CheckForAtmosUpdateAndPrintMessage(atmosConfig schema.AtmosConfiguration)

CheckForAtmosUpdateAndPrintMessage checks if a version update is needed and prints a message if a newer version is found. It loads the cache, decides if it's time to check for updates, compares the current version to the latest available release, and if newer, prints the update message. It also updates the cache's timestamp after printing.

func Cleanup added in v1.192.0

func Cleanup()

Cleanup performs cleanup operations before the program exits. This should be called by main when the program is terminating.

func ComponentsArgCompletion added in v1.161.0

func ComponentsArgCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective)

func Contains added in v1.137.0

func Contains(slice []string, target string) bool

Contains checks if a slice of strings contains an exact match for the target string.

func CreateAuthManagerFromIdentity added in v1.197.0

func CreateAuthManagerFromIdentity(
	identityName string,
	authConfig *schema.AuthConfig,
) (auth.AuthManager, error)

CreateAuthManagerFromIdentity creates and authenticates an AuthManager from an identity name. Returns nil if identityName is empty (no authentication requested). Returns error if identityName is provided but auth is not configured in atmos.yaml. This helper reduces nested complexity in describe commands.

func Execute

func Execute() error

Execute adds all child commands to the root command and sets flags appropriately. This is called by main.main(). It only needs to happen once to the RootCmd.

func ExecuteListInstancesCmd added in v1.192.0

func ExecuteListInstancesCmd(cmd *cobra.Command, args []string) error

func GetIdentityFromFlags added in v1.197.0

func GetIdentityFromFlags(cmd *cobra.Command, osArgs []string) string

GetIdentityFromFlags retrieves the identity value from command-line flags and environment variables. This function handles the Cobra NoOptDefVal quirk where --identity <value> with positional args can be misinterpreted as --identity (without value).

Returns:

  • identity value if explicitly provided
  • cfg.IdentityFlagSelectValue if --identity was used without a value (interactive selection)
  • value from ATMOS_IDENTITY env var if flag not provided
  • empty string if no identity specified anywhere

Usage:

identity := GetIdentityFromFlags(cmd, os.Args)
if identity == cfg.IdentityFlagSelectValue {
    // Show interactive selector
} else if identity != "" {
    // Use explicit identity
}

Types

type AtmosValidateOption added in v1.97.0

type AtmosValidateOption func(*ValidateConfig)

func WithStackValidation added in v1.97.0

func WithStackValidation(check bool) AtmosValidateOption

type ExampleContent added in v1.162.0

type ExampleContent struct {
	Content    string
	Suggestion string
}

type MetadataParams added in v1.170.0

type MetadataParams struct {
	CommonFlags     *fl.CommonFlags
	ProcessingFlags *fl.ProcessingFlags
	ComponentFilter string
}

MetadataParams contains the parameters needed for listing metadata.

type ProcessingOptions added in v1.170.0

type ProcessingOptions struct {
	Templates bool
	Functions bool
}

ProcessingOptions holds flags for processing templates and YAML functions.

type SeparatedArgs added in v1.197.0

type SeparatedArgs struct {
	// AfterDash contains all arguments after the -- separator.
	// These are typically passed through to a subprocess or external command.
	// Returns nil if no -- separator was found.
	AfterDash []string

	// ArgsLenAtDash is the position where -- was found in the original args.
	// Returns -1 if no -- separator was present.
	// This is useful for validation or error messages.
	ArgsLenAtDash int
}

SeparatedArgs represents parsed arguments split by the -- separator. This follows the kubectl pattern where flags before -- are parsed by Cobra, and arguments after -- are passed through to a subprocess or subcommand.

Example: atmos auth exec --identity admin -- terraform apply -auto-approve

BeforeDash: ["--identity", "admin"]  (parsed by Cobra into flags)
AfterDash:  ["terraform", "apply", "-auto-approve"]  (passed to subprocess)

func ParseSeparatedArgs added in v1.197.0

func ParseSeparatedArgs(cmd *cobra.Command, args []string) *SeparatedArgs

ParseSeparatedArgs extracts arguments after the -- separator using Cobra's built-in ArgsLenAtDash(). This is the standard pattern used by kubectl and other tools that need to separate their own flags from arguments passed to a subprocess.

Usage:

func myCommandRun(cmd *cobra.Command, args []string) error {
    separated := ParseSeparatedArgs(cmd, args)

    // Cobra has already parsed your command's flags
    myFlag, _ := cmd.Flags().GetString("my-flag")

    // Get arguments to pass to subprocess
    if len(separated.AfterDash) == 0 {
        return fmt.Errorf("no command specified after --")
    }

    // Execute subprocess with separated.AfterDash
    return executeCommand(separated.AfterDash)
}

Command setup:

cmd := &cobra.Command{
    Use: "mycommand [flags] -- COMMAND [args...]",
    // NOTE: Do NOT use DisableFlagParsing
    RunE: myCommandRun,
}
cmd.Flags().String("my-flag", "", "My command's flag")

The key insight is that Cobra's normal flag parsing works correctly with --:

  • Flags before -- are parsed by Cobra
  • Arguments after -- are available via ArgsLenAtDash()
  • No custom parsing required

func (*SeparatedArgs) CommandArgs added in v1.197.0

func (s *SeparatedArgs) CommandArgs() []string

CommandArgs returns the arguments after --, or nil if no separator was found. This is a convenience method equivalent to accessing AfterDash directly.

func (*SeparatedArgs) HasSeparator added in v1.197.0

func (s *SeparatedArgs) HasSeparator() bool

HasSeparator returns true if the -- separator was present in the arguments.

type SeparatedCommandArgs added in v1.197.0

type SeparatedCommandArgs struct {
	// BeforeSeparator contains arguments before the -- marker.
	// These are processed by Atmos (stack, component, identity, etc.)
	BeforeSeparator []string

	// AfterSeparator contains arguments after the -- marker.
	// These are passed through to the native command (terraform, helmfile, subprocess, etc.)
	AfterSeparator []string

	// SeparatorIndex is the position of -- in os.Args, or -1 if not found.
	SeparatorIndex int

	// HasSeparator returns true if -- was found in the arguments.
	HasSeparator bool
}

SeparatedCommandArgs represents arguments split by the -- separator. This pattern is used across multiple Atmos commands (terraform, helmfile, packer, custom commands, auth exec/shell) to separate Atmos-specific flags from native command flags.

Pattern:

atmos <command> <atmos-flags> -- <native-flags>

Examples:

atmos terraform plan myapp -s dev -- -var foo=bar
atmos auth exec --identity admin -- terraform apply -auto-approve
atmos helmfile apply -s prod -- --set image.tag=v1.0

func ExtractSeparatedArgs added in v1.197.0

func ExtractSeparatedArgs(cmd *cobra.Command, args []string, osArgs []string) *SeparatedCommandArgs

ExtractSeparatedArgs extracts arguments before and after the -- separator. This is the unified implementation used by all Atmos commands that support the -- end-of-args pattern.

Why we need os.Args:

When DisableFlagParsing=true, Cobra consumes the -- separator and we lose
information about where it was. We need os.Args to find the original position
and extract trailing args correctly.

Parameters:

  • cmd: The Cobra command (may have DisableFlagParsing=true)
  • args: The args passed to RunE (after Cobra processing)
  • osArgs: Usually os.Args - the raw command line arguments

Usage:

func myCommandRun(cmd *cobra.Command, args []string) error {
    separated := ExtractSeparatedArgs(cmd, args, os.Args)

    if separated.HasSeparator {
        // Process Atmos flags from separated.BeforeSeparator
        // Pass native flags from separated.AfterSeparator
    }
}

func (*SeparatedCommandArgs) GetAfterSeparator added in v1.197.0

func (s *SeparatedCommandArgs) GetAfterSeparator() []string

GetAfterSeparator returns arguments after --, or nil if no separator. This is a convenience method for commands that only care about trailing args.

func (*SeparatedCommandArgs) GetAfterSeparatorAsQuotedString added in v1.197.0

func (s *SeparatedCommandArgs) GetAfterSeparatorAsQuotedString() (string, error)

GetAfterSeparatorAsQuotedString returns arguments after -- as a shell-quoted string. Each argument is properly quoted for shell safety, preserving whitespace and special characters. Returns empty string if no separator or no trailing args.

This is the CORRECT method to use for custom commands that pass trailing args to shell execution, as it ensures argument boundaries and whitespace are preserved when the shell re-parses the string.

Example:

args after --: ["echo", "hello  world"]  (note: two spaces)
GetAfterSeparatorAsString():       "echo hello  world"  (when shell re-parses: loses boundary!)
GetAfterSeparatorAsQuotedString(): "echo 'hello  world'" (shell correctly preserves!)

func (*SeparatedCommandArgs) GetAfterSeparatorAsString added in v1.197.0

func (s *SeparatedCommandArgs) GetAfterSeparatorAsString() string

GetAfterSeparatorAsString returns arguments after -- joined as a space-separated string. Returns empty string if no separator or no trailing args.

WARNING: This method uses plain strings.Join() which does NOT preserve argument boundaries or whitespace when the result is later parsed by a shell. For shell-safe quoting that preserves whitespace and special characters, use GetAfterSeparatorAsQuotedString() instead.

This method exists for backwards compatibility and non-shell use cases.

func (*SeparatedCommandArgs) GetBeforeSeparator added in v1.197.0

func (s *SeparatedCommandArgs) GetBeforeSeparator() []string

GetBeforeSeparator returns arguments before --, or all args if no separator.

type SettingsParams added in v1.170.0

type SettingsParams struct {
	CommonFlags     *fl.CommonFlags
	ProcessingFlags *fl.ProcessingFlags
	ComponentFilter string
}

SettingsParams contains all parameters needed for the list settings command.

type ValidateConfig added in v1.97.0

type ValidateConfig struct {
	CheckStack bool
}

ValidateConfig holds configuration options for Atmos validation. CheckStack determines whether stack configuration validation should be performed.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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