Skip to content

refactor: Migrate terraform commands to registry pattern#1813

Merged
aknysh merged 80 commits intomainfrom
osterman/terraform-cmd-registry
Dec 16, 2025
Merged

refactor: Migrate terraform commands to registry pattern#1813
aknysh merged 80 commits intomainfrom
osterman/terraform-cmd-registry

Conversation

@osterman
Copy link
Member

@osterman osterman commented Nov 23, 2025

what

  • Migrate all terraform commands from monolithic cmd files to registry-based modular structure
  • Restructure terraform command handling into individual command providers under cmd/terraform/
  • Update flag handling to use StandardFlagParser pattern for consistent CLI argument processing
  • Fix I/O handling in terraform plan-diff to use data.Writeln() for proper output layering
  • Add comprehensive terraform registry migration PRD documentation

why

Improves code maintainability and extensibility by following the CommandProvider registry pattern established in the codebase. Breaks down monolithic terraform command files into focused, single-responsibility modules. Ensures proper I/O separation between data output and UI messages as per CLAUDE.md standards.

references

  • Implements docs/prd/command-registry-pattern.md
  • Follows I/O/UI standards in CLAUDE.md
  • Adds docs/prd/terraform-registry-migration.md with detailed migration architecture

Summary by CodeRabbit

  • New Features

    • Full Terraform command suite added (many terraform subcommands) and interactive component/stack prompts in TTY.
  • Improvements

    • Terraform compatibility/pass‑through flags exposed and shown in help; help output simplified.
    • Tab completion: stack suggestions filtered by selected component.
    • terraform clean: new --everything, --force (-f), --skip-lock-file and improved dry-run output.
    • plan/apply: enhanced from‑plan/planfile handling and upload-status behavior.
  • Chores

    • Telemetry notice, docs/blog updates, and test/snapshot maintenance.

✏️ Tip: You can customize this high-level summary in your review settings.

@osterman osterman requested a review from a team as a code owner November 23, 2025 00:57
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 23, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Split Terraform into per-subcommand Cobra modules and typed executors, add pre-parsing to extract passthrough Terraform flags, introduce a compat-flag registry and separated storage, expose small cmd wrappers (CreateAuthManager, GetConfigAndStacksInfo), enhance flag/completion plumbing, and update help, prompts, tests, and snapshots.

Changes

Cohort / File(s) Summary
Root & preprocessing
\cmd/root.go`, `pkg/flags/compat/separated.go``
Add preprocessCompatibilityFlags to pre-scan args, store/retrieve separated passthrough args via compat.SetSeparated/GetSeparated/ResetSeparated, and adjust RootCmd args before Cobra parsing.
Compat registry
cmd/internal/registry.go, \cmd/internal/registry_test.go``
Add in-memory compat flags registry with RegisterCommandCompatFlags, GetSubcommandCompatFlags, GetCompatFlagsForCommand and concurrency tests.
Terraform command provider & core
\cmd/terraform/terraform.go`, `cmd/terraform/flags.go`, `cmd/terraform/terraform_test.go``
Introduce TerraformCommandProvider, terraformParser, Terraform flag registries/builders, compat flag wiring, and early heatmap/perf detection.
Per-subcommand Cobra modules
\cmd/terraform/.go`, `cmd/terraform/generate/`, (deleted) `cmd/terraform_commands.go``
Replace monolithic command wiring with many per-subcommand files (plan, apply, deploy, clean, plan-diff, shell, generate/, varfile, etc.), each registering flags, completions, Viper binding, and delegating to typed Execute flows; remove legacy aggregate module.
Typed executors & internal reorg
\internal/exec/`, `pkg/terraform/`, `internal/exec/options.go``
Add typed option structs and Execute* functions (Clean, Shell, Varfile, Planfile, GenerateBackend, etc.), TF_DATA_DIR handling, helpers, deprecation wrappers, and compatibility re-exports.
Flag system & parser enhancements
\pkg/flags/{options.go,registry.go,standard.go,standard_parser.go,types.go,flag_parser.go}``
Remove old WithTerraformFlags, add WithFlagRegistry, expose Registry() on parsers, add SetCompletionFunc/GetCompletionFunc, propagate completions recursively, and refine Cobra parsing heuristics.
Completions, cmd utils & auth wrappers
\cmd/cmd_utils.go`, `cmd/auth_login.go`, `cmd/cmd_utils_test.go`, `cmd/terraform/shared/prompt.go``
Export FlagStack, add GetConfigAndStacksInfo and CreateAuthManager wrappers, expose StackFlagCompletion, update tests, and add shared prompt/completion helpers for component/stack selection.
Help rendering & snapshots
\cmd/help_template.go`, `tests/snapshots/*``
Add COMPATIBILITY FLAGS section to help (queries compat registry) and update many golden snapshots to reflect new help layout and passthrough flags.
Validation, errors & utilities
\cmd/internal/validation.go`, `errors/errors.go`, `pkg/utils/*`**
Add ValidateAtmosConfig, new sentinel errors (ErrUnknownSubcommand, ErrInteractiveNotAvailable, ErrDeprecatedCmdNotCallable, backend-related errors), and small message/format tweaks.
Interactive prompts & UI
\pkg/flags/interactive.go`, `cmd/terraform/shared/prompt.go`, `cmd/terraform/shared/prompt.go``
Replace selector UI with form selector (ESC/Ctrl+C abort), add PromptForComponent/PromptForStack and prompt error handling, and wire interactive flows for missing args.
Tests, harness & sanitization
\tests/`, `internal/exec/_test.go`, `cmd/terraform/*_test.go`**
Add/adjust tests for compat flags, completions, clean/shell/generate APIs, improve sanitizeOutput logic, and update numerous snapshots and fixtures.
Docs & guidance
\website/blog/`, `website/docs/cli/commands/terraform/.mdx`, `CLAUDE.md``
Add blog posts and CLI docs documenting the registry migration, interactive prompts, new flags (--everything, --force), and developer guidance updates.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor User
    participant CLI as atmos (Cobra)
    participant Preproc as Compat Preprocessor
    participant Registry as Compat Registry
    participant Cmd as Terraform Cobra Cmd
    participant Exec as Typed Executor (pkg/terraform / internal/exec)
    participant TF as Terraform/OpenTofu

    User->>CLI: atmos terraform ...flags...
    CLI->>Preproc: preprocessCompatibilityFlags(os.Args)
    Preproc-->>Registry: SetSeparated(separatedArgs)
    Preproc-->>CLI: atmosArgs (filtered)
    CLI->>Cmd: dispatch terraform command (RunE)
    Cmd->>Exec: build typed options, call ExecuteX(opts, atmosConfig)
    Exec->>Registry: GetSubcommandCompatFlags(provider, subcmd)
    Exec->>Preproc: GetSeparated() → separatedArgs
    Exec->>TF: invoke Terraform/OpenTofu with separatedArgs + generated files
    TF-->>Exec: output / exit
    Exec-->>Cmd: return result
    Cmd-->>User: stdout/stderr / exit
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Areas needing extra attention:
    • cmd/root.go — preprocessCompatibilityFlags interactions with Cobra arg parsing and lifecycle of compat separated values.
    • cmd/internal/registry.go & tests — concurrency, overwrite semantics, provider/subcommand isolation.
    • cmd/terraform/* — Viper binding, completion registration, and correct handoff to typed Execute* APIs.
    • internal/exec/* and pkg/terraform/* — correctness of typed Execute* implementations (Clean, Shell, Varfile, Planfile, GenerateBackend), TF_DATA_DIR handling, and deprecated wrappers.
    • pkg/flags changes — completion plumbing (SetCompletionFunc/GetCompletionFunc), Registry() accessors and parse adjustments.
    • cmd/help_template.go & snapshots — formatting and accuracy of COMPATIBILITY FLAGS output; many updated golden files.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.55% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title clearly describes the main change: migrating Terraform commands to a registry pattern, which aligns with the substantial refactoring work across cmd/terraform/.

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 399f135 and 75d0be2.

📒 Files selected for processing (10)
  • cmd/terraform/terraform.go (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_terraform_-help_passthrough.stdout.golden (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_terraform_-version_passthrough.stdout.golden (1 hunks)
  • tests/test-cases/help-and-usage.yaml (2 hunks)
  • website/docs/cli/commands/terraform/terraform-clean.mdx (2 hunks)
  • website/docs/cli/commands/terraform/terraform-deploy.mdx (1 hunks)
  • website/docs/cli/commands/terraform/terraform-destroy.mdx (1 hunks)
  • website/docs/cli/commands/terraform/terraform-output.mdx (1 hunks)
  • website/docs/cli/commands/terraform/terraform-shell.mdx (1 hunks)
  • website/docs/cli/commands/terraform/terraform-workspace.mdx (1 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

Warning

CLAUDE.md Too Large

The modified CLAUDE.md exceeds the 40000 byte size limit:

  • CLAUDE.md: 40792 bytes (over by 792 bytes, ~1%)

Action needed: Please refactor the oversized CLAUDE.md file. Consider:

  • Removing verbose explanations
  • Consolidating redundant examples
  • Keeping only essential requirements
  • Moving detailed guides to separate docs in docs/ or docs/prd/

All MANDATORY requirements must be preserved.

@github-actions github-actions bot added the size/xl Extra large size PR label Nov 23, 2025
@mergify
Copy link

mergify bot commented Nov 23, 2025

Warning

This PR exceeds the recommended limit of 1,000 lines.

Large PRs are difficult to review and may be rejected due to their size.

Please verify that this PR does not address multiple issues.
Consider refactoring it into smaller, more focused PRs to facilitate a smoother review process.

@github-actions
Copy link

github-actions bot commented Nov 23, 2025

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@osterman osterman force-pushed the osterman/terraform-cmd-registry branch from e81df0a to d0dddec Compare November 23, 2025 03:27
@osterman osterman added the minor New features that do not break anything label Nov 24, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
cmd/terraform/utils_test.go (1)

119-119: Replace placeholder issue number.

The comment references a placeholder issue number "XXXX". Please update with the actual GitHub issue number or remove the reference if not applicable.

Apply this diff:

-// Regression test for: https://github.com/cloudposse/atmos/issues/XXXX
+// Regression test for: https://github.com/cloudposse/atmos/issues/1813

Or if there's a specific issue this addresses:

-// Regression test for: https://github.com/cloudposse/atmos/issues/XXXX
+// Regression test for identity flag handling in non-TTY environments
internal/exec/terraform.go (1)

549-557: os.Stdin == nil doesn’t reliably detect non‑TTY runs; prefer the existing TTY helper.

This guard:

if os.Stdin == nil && !u.SliceContainsString(info.AdditionalArgsAndFlags, autoApproveFlag) {
    if info.SubCommand == "apply" {
        return fmt.Errorf("%w: 'terraform apply' requires a user interaction, but no TTY is attached. Use 'terraform apply -auto-approve' or 'terraform deploy' instead",
            errUtils.ErrNoTty,
        )
    }
}

will almost never trigger in real processes, since os.Stdin is typically a non‑nil *os.File even when it isn’t a TTY (e.g., in CI or when piped).

Given the prior guidance to use stdin TTY detection helpers for apply interactivity checks, it would be more robust to use the existing helper instead, e.g.:

- if os.Stdin == nil && !u.SliceContainsString(info.AdditionalArgsAndFlags, autoApproveFlag) {
+ if !u.IsTTYSupportForStdin() && !u.SliceContainsString(info.AdditionalArgsAndFlags, autoApproveFlag) {

That way, scripted/non‑TTY runs without -auto-approve will reliably get the intended ErrNoTty instead of hanging on an impossible prompt.
Based on learnings.

internal/exec/terraform_clean.go (1)

471-605: Ensure ExecuteClean populates fields needed for stack‑specific tfstate cleanup

HandleCleanSubCommand decides whether to collect stack‑scoped state folders via:

if info.Component != "" && info.Stack != "" {
    stackFolders, err := getStackTerraformStateFolder(cleanPath, info.Stack)
    ...
}

However, ExecuteClean only sets ComponentFromArg and never sets info.Component, so for calls like:

ExecuteClean("my-component", "my-stack", force, everything, skipLockFile, atmosConfig)

this condition will be false and terraform.tfstate.d contents won’t be included in the cleanup, even though a stack was provided.

A minimal fix that keeps existing behavior for older callers is to set Component alongside ComponentFromArg when building info:

info := schema.ConfigAndStacksInfo{
-    ComponentFromArg: component,
+    ComponentFromArg: component,
+    Component:        component,
     Stack:            stack,
     StackFromArg:     stack,
     SubCommand:       "clean",
}

That will:

  • Allow the info.Component != "" && info.Stack != "" branch to execute for the new typed path, and
  • Preserve behavior for any existing caller that already populates Component before calling HandleCleanSubCommand.

Might be worth adding/adjusting a test around terraform clean <component> --stack <stack> to lock this in.

🧹 Nitpick comments (18)
cmd/terraform/terraform_test.go (1)

15-33: Test serves its immediate purpose but could be more assertive.

The test correctly verifies that enableHeatmapIfRequested() doesn't panic with the --heatmap flag present. However, the assertion assert.True(t, true, ...) is a no-op. If there's a way to verify that heatmap tracking was actually enabled (e.g., checking a package-level flag or calling a getter), that would strengthen the test. If not feasible due to the current implementation, the comment correctly notes that comprehensive testing will happen at the integration level.

cmd/terraform/deploy.go (1)

33-40: Remove orphaned and duplicate comments.

Line 33 has an incomplete comment about disabling flag parsing with no following code. Lines 35-36 repeat the comment from line 39 about attaching to the parent command. Clean up these comments for clarity.

Apply this diff:

-	// Disable flag parsing to allow pass-through of Terraform native flags
-
-	// Attach to parent terraform command
 	// Register completions for deployCmd.
 	RegisterTerraformCompletions(deployCmd)
 
 	// Attach to parent terraform command.
 	terraformCmd.AddCommand(deployCmd)
cmd/terraform/generate/varfiles.go (1)

36-63: Consider aligning format validation and CSV parsing with the underlying helper

The main flow here looks good, but there are a couple of small polish points you might want to consider:

  • ExecuteTerraformGenerateVarfiles supports yaml/json/hcl per the internal exec helper, while the CLI validation only allows json or hcl. Either exposing yaml here or updating the helper to match would avoid a silent capability mismatch.
  • When splitting stacksCsv/componentsCsv you currently do a plain strings.Split, so inputs like "stack1, stack2" will include a leading space. Trimming each entry after split would make the flags more forgiving.

Both are non-blocking, but would smooth UX and keep the CLI surface in sync with the underlying implementation.

docs/prd/terraform-registry-migration.md (1)

47-59: Optional: align PRD with markdownlint and polish punctuation

The PRD reads clearly, but if you want it completely clean against tooling:

  • Code blocks currently use hard tabs, which triggers markdownlint MD010; replacing them with spaces or adding a local exemption would silence those warnings.
  • A few list items/sentences (e.g., lines describing exported functions and some bullet points under the phase summaries) don’t end with punctuation, which LanguageTool flags.

These are purely cosmetic and can be deferred if they conflict with existing doc style.

Also applies to: 308-353

cmd/terraform/clean.go (1)

18-69: Align Use string with optional component argument

The implementation correctly treats the component as optional (MaximumNArgs(1) and the comment “if empty, cleans all components”), but Use: "clean <component>" reads as if the argument is required.

To avoid confusion in --help, consider switching to something like:

Use: "clean [component]",

so it’s clear that calling atmos terraform clean without a component is supported. The rest of the flag parsing and delegation to ExecuteClean looks solid.

Also applies to: 72-96

cmd/terraform/generate/varfile.go (1)

44-45: Double‑check --stack required semantics vs ATMOS_STACK

You both (a) mark stack as required on the Cobra command and (b) bind it to ATMOS_STACK via WithEnvVars and then validate stack == "" from Viper.

With Cobra’s required‑flag behavior, a missing --stack will fail before RunE executes, even if ATMOS_STACK is set. If you intend to support “env‑only” usage (stack from ATMOS_STACK without explicitly passing --stack), consider relying solely on the Viper‑based stack == "" check and dropping MarkFlagRequired, or clarifying that the CLI flag is mandatory and env is just a default source.

Also applies to: 81-84

cmd/terraform/generate/backends.go (1)

20-67: Backends command wiring is solid (optional CSV trimming)

The command cleanly binds flags/env via backendsParser, validates --format, and delegates to ExecuteTerraformGenerateBackends with the expected arguments. If you ever see users passing spaces in CSV lists ("stack1, stack2"), you might later consider trimming entries after strings.Split, but that’s a nicety, not a blocker.

cmd/terraform/terraform.go (1)

16-51: Base terraform command + registry provider look consistent

Using StandardParser with WithTerraformFlags and WithTerraformAffectedFlags, registering persistent flags once, and binding them to Viper in init is in line with the shared pattern. Attaching generate.GenerateCmd, wiring completions, and registering TerraformCommandProvider all look correct.

Minor nit: GetAliases returns nil while the Cobra command has Aliases: []string{"tf"}; if the registry layer ever surfaces aliases in help, you may want to mirror "tf" there or adjust the comment so it’s clear aliases live only on the Cobra command.

Also applies to: 71-74

cmd/terraform/plan_diff.go (1)

89-107: Clarify whether --orig must be a flag or can come from env

You bind orig to ATMOS_TERRAFORM_PLAN_DIFF_ORIG via WithEnvVars, but also:

  • Register it as a persistent flag, and
  • Call MarkPersistentFlagRequired("orig"), and
  • Later check if orig == "" { return fmt.Errorf("original plan file is required (use --orig)") }.

In practice, Cobra’s required‑flag check will fire before RunE if --orig isn’t present, even when the env var is set, so ATMOS_TERRAFORM_PLAN_DIFF_ORIG alone won’t satisfy the requirement.

If you want env‑only usage to work, you can rely on the Viper‑based orig == "" check and drop MarkPersistentFlagRequired. If you want to force the explicit --orig flag and treat the env var as a secondary input, then the env binding may not be needed and could be removed to avoid confusion.

pkg/flags/registry.go (1)

235-299: New TerraformAffectedFlags registry is straightforward; watch for flag-role overlap

TerraformAffectedFlags cleanly encapsulates the affected‑component detection flags and keeps them separate from the core Terraform flag set, which works well with the combined WithTerraformFlags + WithTerraformAffectedFlags pattern.

One thing to keep an eye on long‑term: comments earlier in this file note that identity already exists in GlobalFlagsRegistry(), and you now also define a Terraform‑specific identity flag in TerraformFlags. If both global and Terraform‑specific identities are registered on parent/child commands, ensure the intended one is consistently the one bound to Viper and used by downstream exec logic, or consider consolidating them later to avoid confusion.

internal/exec/terraform_shell.go (1)

10-33: Align perf/log naming and optionally populate CliArgs for telemetry.

Function behavior looks solid, but a couple of small consistency nits:

  • perf.Track label and the debug message still use "ExecuteShell" while the function is ExecuteTerraformShell. For perf dashboards and log grepability, it’s clearer if these match the function name.
  • Other new exec entrypoints (e.g., planfile) set info.CliArgs before calling ProcessStacks; doing the same here would keep telemetry and diagnostics consistent.

Something like this would align everything:

-	defer perf.Track(atmosConfig, "exec.ExecuteShell")()
+	defer perf.Track(atmosConfig, "exec.ExecuteTerraformShell")()

-	log.Debug("ExecuteShell called",
+	log.Debug("ExecuteTerraformShell called",
 		"component", component,
 		"stack", stack,
 		"processTemplates", processTemplates,
 		"processFunctions", processFunctions,
 		"skip", skip,
 	)

-	info := schema.ConfigAndStacksInfo{
+	info := schema.ConfigAndStacksInfo{
 		ComponentFromArg: component,
 		Stack:            stack,
 		StackFromArg:     stack,
 		ComponentType:    "terraform",
 		SubCommand:       "shell",
+		CliArgs:          []string{"terraform", "shell"},
 	}
internal/exec/terraform_generate_planfile.go (1)

39-77: Consider either threading atmosConfig through or dropping it from this API.

ExecuteGeneratePlanfile currently accepts atmosConfig but only uses it for perf.Track, while ExecuteTerraformGeneratePlanfile still calls cfg.InitCliConfig internally and ignores the caller’s config.

That’s functionally safe, but slightly confusing for callers who might expect their pre-initialized atmosConfig to be honored. Two possible cleanups:

  • Either change ExecuteTerraformGeneratePlanfile to accept an *schema.AtmosConfiguration and reuse the passed-in config instead of reinitializing, or
  • If you want ExecuteTerraformGeneratePlanfile to remain self-contained, drop the atmosConfig parameter from ExecuteGeneratePlanfile and call perf.Track(nil, ...) here.

Not urgent, but tightening this will make the exec API easier to reason about.

internal/exec/terraform.go (1)

69-145: Auth‑first ProcessStacks flow looks good; explicit empty‑stack check is probably redundant.

Routing through ExecuteDescribeComponent first, then creating authManager and passing it into ProcessStacks is a nice improvement for YAML functions that need authenticated context.

Given you now call:

info, err = ProcessStacks(&atmosConfig, info, true, info.ProcessTemplates, info.ProcessFunctions, info.Skip, authManager)

with checkStack hard‑coded to true, ProcessStacks itself will already return ErrMissingStack when no stack is provided (see its behavior summary). The subsequent:

if len(info.Stack) < 1 {
    return errUtils.ErrMissingStack
}

ends up as a safety net that should never actually trigger.

Totally safe to keep, but if you’d like to reduce duplication and keep all the stack‑required logic centralized in ProcessStacks, you can drop the explicit len(info.Stack) check.

cmd/terraform/varfile.go (1)

72-85: Confirm Cobra Use string matches the intended terraform write varfile CLI

With Use: "write varfile <component>", Cobra will treat the command name as write, and varfile becomes part of the usage text, not a separate subcommand token. If the legacy UX truly expects atmos terraform write varfile <component>, that path may not exist as a distinct subcommand anymore and varfile would instead be parsed as an argument.

Consider either:

  • Modeling write as a parent command with a varfile subcommand, or
  • Adjusting docs/deprecation text if the actual supported path is atmos terraform write <component>.

Worth a quick manual check of atmos terraform write varfile --help to ensure behavior matches expectations.

cmd/cmd_utils.go (1)

785-871: Stack completion behavior is sensible; consider minor polish only

The new StackFlagCompletion + listStacksForComponent / listStacks helpers give:

  • Component-aware stack suggestions when a first positional arg is present, and
  • A full stack list otherwise,

which is a nice UX improvement over unfiltered completion.

Two optional refinements you might consider later:

  • Use toComplete to trim the suggestion set when shells don’t pre-filter aggressively.
  • DRY up listStacksForComponent/listStacks by sharing the common InitCliConfig + ExecuteDescribeStacks block.

Functionally, this looks good as-is.

cmd/terraform/utils.go (2)

295-306: Use Cobra’s output writer instead of fmt.Print in setCustomHelp

Right now the custom help appends compat flag docs using fmt.Print, which bypasses Cobra’s configured output writer. That can make it harder to capture help output in tests and in docs generators that redirect cmd.OutOrStdout().

Consider writing through the command’s writer instead:

-	cmd.SetHelpFunc(func(c *cobra.Command, args []string) {
-		// Call original help first.
-		originalHelp(c, args)
-
-		// Append compatibility flags section.
-		if len(descriptions) > 0 {
-			fmt.Print(FormatCompatFlagsHelp(descriptions))
-		}
-	})
+	cmd.SetHelpFunc(func(c *cobra.Command, args []string) {
+		// Call original help first.
+		originalHelp(c, args)
+
+		// Append compatibility flags section.
+		if len(descriptions) > 0 {
+			fmt.Fprint(c.OutOrStdout(), FormatCompatFlagsHelp(descriptions))
+		}
+	})

This will play nicer with the existing I/O conventions and any tooling that captures help output.


310-340: Completions work but ignore the toComplete prefix

Both componentsArgCompletion and stackFlagCompletion return full lists without filtering on toComplete. That’s functionally correct but can be noisy in large deployments.

If you want to tighten UX later, you could filter candidates by strings.HasPrefix(candidate, toComplete) before returning.

cmd/terraform/compat_help.go (1)

17-147: Keep compat descriptions in sync with compat flag maps

A few of the description sets don’t currently cover all flags declared in cmd/terraform/compat_flags.go:

  • ValidateCompatFlagDescriptions omits -no-tests and -test-directory, which are present in ValidateCompatFlags.
  • RefreshCompatFlagDescriptions returns only TerraformCompatFlagDescriptions, so it never documents -backup, -state, or -state-out from RefreshCompatFlags.
  • StateCompatFlagDescriptions doesn’t mention -state-out from StateCompatFlags.
  • ImportCompatFlagDescriptions doesn’t include -state / -state-out, which are in ImportCompatFlags.
  • GetCompatFlagDescriptions omits -test-directory from GetCompatFlags.
  • TestCompatFlagDescriptions omits -var and -var-file from TestCompatFlags.

For a future pass, it’d be good to align these so the help output fully reflects what the compatibility layer actually passes through.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (16)
cmd/terraform/utils_test.go (1)

147-153: Consider clarifying the comment for better context.

The test case is correct, but the comment could more explicitly distinguish between "env var is set to __SELECT__" versus "user explicitly provided --identity flag without value." The key distinction is that interactive selection should only trigger when the user explicitly uses the flag, not when an env var happens to have that value.

Optional rewording:

 		{
-			name:             "ATMOS_IDENTITY set to __SELECT__, should NOT trigger TTY check (flag not explicitly provided)",
+			name:             "ATMOS_IDENTITY env var set to __SELECT__, should NOT trigger TTY check because flag not explicitly provided by user",
 			args:             []string{},
 			envVar:           "ATMOS_IDENTITY",
 			envValue:         "__SELECT__",
 			expectedIdentity: "__SELECT__", // ProcessCommandLineArgs sets this, but terraformRun doesn't override
-			expectTTYError:   false,        // Key fix: TTY check only happens when flag is explicitly provided
+			expectTTYError:   false,        // Key fix: TTY check only happens when user explicitly provides --identity flag
 		},
CLAUDE.md (1)

135-141: Clarify viper.BindEnv guidance vs StandardParser to avoid conflicting rules.

Flag Handling says to never call viper.BindEnv()/viper.BindPFlag() directly (StandardParser owns that), but the Environment Variables section then recommends “Use viper.BindEnv("ATMOS_VAR", …)”.

To keep this consistent with the current patterns (StandardParser for flags, centralized env binding helpers in config, plus documented exceptions like NO_PAGER), consider tightening the wording, for example:

  • In Flag Handling: explicitly scope the prohibition to CLI flag handling (commands using flags.NewStandardParser()).
  • In Environment Variables: steer people toward the existing helper (e.g., setEnv / bindEnv in pkg/config/load.go) instead of direct viper.BindEnv in random call sites.

That should make it clearer where direct BindEnv is allowed and where it is not.

Also applies to: 272-274

cmd/terraform/utils.go (4)

36-60: Confirm which command is passed into runHooks so ProcessCommandLineArgs sees the right argv

finalArgs is built as []string{cmd_.Name()} + args and then handed to ProcessCommandLineArgs("terraform", cmd_, finalArgs, argsAfterDoubleDash). That’s correct only if cmd_ represents the terraform parent command and args start with the subcommand name; if cmd_ is already the subcommand, you’ll end up with the first positional being the subcommand name of that subcommand (or even "terraform"), which may not be what the arg parser expects.

Might be worth double‑checking call sites and, if needed, threading in the actual subcommand name (e.g. actualCmd.Name()) instead of cmd_.Name() here.


63-93: Ensure pass‑through (Terraform/OpenTofu) flags wired via parsedConfig.SeparatedArgs

terraformRun correctly uses AtmosFlagParser to separate Atmos flags from Terraform/OpenTofu native flags, but the result of that separation (parsedConfig.SeparatedArgs) is currently discarded:

parsedConfig, err := parser.Parse(args)
// ...
argsWithSubCommand := append([]string{subCommand}, parsedConfig.PositionalArgs...)
info, err := e.ProcessCommandLineArgs(cfg.TerraformComponentType, parentCmd, argsWithSubCommand, nil)

If ProcessCommandLineArgs relies on its additionalArgsAndFlags parameter to populate info.AdditionalArgsAndFlags (as in the older terraform flow), pass‑through flags like -var, -target, etc. may never reach ExecuteTerraform*.

Consider threading SeparatedArgs through:

-	info, err := e.ProcessCommandLineArgs(cfg.TerraformComponentType, parentCmd, argsWithSubCommand, nil)
+	info, err := e.ProcessCommandLineArgs(
+		cfg.TerraformComponentType,
+		parentCmd,
+		argsWithSubCommand,
+		parsedConfig.SeparatedArgs,
+	)

If AtmosFlagParser.Parse already injects these into the info path internally, then this is fine as‑is—but it’s worth verifying to avoid regressions on native terraform flags.


293-307: Custom help extension is fine; consider using Cobra output instead of fmt.Print

Hooking cmd.SetHelpFunc and appending the compatibility flags block via FormatCompatFlagsHelp is a clean way to extend help without replacing it.

If you want to align more strictly with Cobra’s I/O layering, you could switch to writing through the command’s output:

-			fmt.Print(FormatCompatFlagsHelp(descriptions))
+			fmt.Fprint(c.OutOrStdout(), FormatCompatFlagsHelp(descriptions))

Not required, but keeps all help text going through Cobra’s configured writer.


342-426: Stack/component discovery helpers are correct; duplication with cmd package is acceptable

listTerraformComponents, listStacksForComponent, and listAllStacks:

  • Reuse InitCliConfig and ExecuteDescribeStacks.
  • Gracefully return wrapped errors when config or stacks can’t be loaded.
  • Return sorted results, which is nice for shell completion.

There’s some overlap with similar helpers in cmd/cmd_utils.go, but given different package boundaries and existing learnings around not over‑refactoring stack listing, keeping these local is reasonable.

internal/exec/terraform_generate_varfile.go (1)

12-70: New ExecuteGenerateVarfile API looks correct and side‑effect free

The new entrypoint:

  • Constructs ConfigAndStacksInfo with ComponentFromArg, Stack, StackFromArg, ComponentType: "terraform", and CliArgs: []string{"terraform", "generate", "varfile"}.
  • Runs ProcessStacks with the passed AtmosConfiguration, honoring processTemplates, processFunctions, and skip.
  • Derives the output path from file if provided, otherwise from constructTerraformComponentVarfilePath.
  • Respects info.DryRun before writing JSON via u.WriteToFileAsJSON.

Behavior matches expectations for a non‑CLI, typed API.

If you want to avoid magic strings, you could reuse the Terraform component constant:

-import (
+import (
 	"errors"
+	cfg "github.com/cloudposse/atmos/pkg/config"
 	// ...
 )
 // ...
-		ComponentType:    "terraform",
+		ComponentType:    cfg.TerraformComponentType,

Purely optional.

cmd/terraform/compat_help.go (1)

240-272: FormatCompatFlagsHelp produces clean, aligned help blocks

The formatter:

  • Early‑returns on empty input.
  • Sorts flags by name for deterministic output.
  • Computes max flag width and then aligns descriptions with padding.
  • Adds a clear heading explaining these are native Terraform/OpenTofu flags passed through.

This should render nicely in --help output. Coupled with the optional tweak in setCustomHelp to write via OutOrStdout, the UX is solid.

cmd/auth_login.go (1)

82-86: CreateAuthManager export looks fine; just ensure it’s the single source

The exported CreateAuthManager wrapper cleanly exposes the existing initialization logic for reuse by other command packages without changing behavior, which is nice.

Given the broader PR mentions CreateAuthManager in cmd/cmd_utils.go as well, please double‑check that this function only exists in one place in package cmd to avoid duplicate definitions and to keep the public entrypoint obvious.

pkg/flags/registry.go (1)

125-233: Align TerraformFlags with existing identity/from-plan usage

Nice to see Terraform‑specific flags centralized here; this should simplify future command wiring. A couple of things to sanity‑check:

  1. Identity flag scope

    • TerraformFlags() now registers an identity StringFlag with shorthand -i and NoOptDefVal="__SELECT__".
    • Earlier comments on CommonFlags() mention that identity comes from GlobalFlagsRegistry() and is not duplicated there.

    If a global identity flag still exists (e.g., via a global registry on the root command), registering identity again here could cause duplicate registration or at least confusion about which registry “owns” it. It’d be good to confirm that identity is now meant to be Terraform‑scoped only, or that the global definition has been removed.

  2. from-plan consistency with deploy

    • Here, from-plan is a string flag intended to hold a plan file path.
    • In cmd/terraform/deploy.go, deployCmd currently defines a bool from-plan flag.

    If both registries end up applying to terraform deploy, that’s either a duplicate flag definition or two different semantics for the same flag name. I’d recommend consolidating on a single type/meaning for from-plan across Terraform commands (string path vs. simple toggle) and making the deploy command reuse that shared definition.

Everything else in this block (init-pass-vars, append-user-agent, process-templates/functions, skip, query, components) looks coherent and uses distinct env vars.

cmd/terraform/plan_diff.go (1)

100-108: Standardize init-time error handling.

The init function uses panic() for BindToViper errors (line 101) but CheckErrorPrintAndExit() for MarkPersistentFlagRequired errors (line 107). Since both are static init-time configurations, consider using panic() consistently for both.

-	err := planDiffCmd.MarkPersistentFlagRequired("orig")
-	if err != nil {
-		errUtils.CheckErrorPrintAndExit(err, "Error marking 'orig' flag as required", "")
-	}
+	if err := planDiffCmd.MarkPersistentFlagRequired("orig"); err != nil {
+		panic(err)
+	}
cmd/terraform/generate/planfile.go (1)

45-47: Confirm stack required semantics with env vars + StandardParser

You’re wiring stack both as a flag (and marking it required) and as an env-bound value via ATMOS_STACK, then validating stack == "" via Viper. Depending on how StandardParser and Cobra interact, MarkFlagRequired("stack") may still reject invocations that rely solely on ATMOS_STACK before your Viper-based check ever runs, even though the comment and env-var wiring suggest that should be a valid path.

Might be worth double-checking the behavior and either:

  • Rely only on the Viper-based stack == "" validation (dropping MarkFlagRequired), or
  • Keep MarkFlagRequired but explicitly treat env-var-only usage as unsupported and adjust help/error text accordingly.

Also applies to: 61-74, 80-87

cmd/terraform/generate/backends.go (1)

41-51: Consider trimming CSV values and revisiting ATMOS_FORMAT reuse for this command

Two small points:

  • The stacks and components CSVs are split with strings.Split only. Inputs like --stacks foo, bar will include a leading space in " bar". Trimming would make the CLI a bit more forgiving.

  • The format flag is wired to ATMOS_FORMAT via flags.WithEnvVars("format", "ATMOS_FORMAT") but only accepts hcl, json, and backend-config. If users already set ATMOS_FORMAT=yaml for other commands, this new command will now fail with an "invalid '--format'" error. If that’s not desired, a more specific env var (e.g. ATMOS_TERRAFORM_GENERATE_BACKENDS_FORMAT) or a different flag key might avoid surprising cross-command coupling.

Example tweak for trimming (optional):

-		var stacks []string
-		if stacksCsv != "" {
-			stacks = strings.Split(stacksCsv, ",")
-		}
+		var stacks []string
+		if stacksCsv != "" {
+			for _, s := range strings.Split(stacksCsv, ",") {
+				s = strings.TrimSpace(s)
+				if s != "" {
+					stacks = append(stacks, s)
+				}
+			}
+		}

(and similarly for componentsCsv).

Also applies to: 72-81

cmd/terraform/clean.go (1)

18-21: Align Use string with optional component argument

The implementation treats component as optional (cobra.MaximumNArgs(1) and comment “if empty, cleans all components”), but the usage string is clean <component>, which typically implies a required argument. Consider changing it to something like:

-var cleanCmd = &cobra.Command{
-	Use:   "clean <component>",
+var cleanCmd = &cobra.Command{
+	Use:   "clean [component]",

to better reflect the actual behavior in --help.

Also applies to: 30-36

cmd/cmd_utils.go (1)

785-871: StackFlagCompletion changes assume first positional arg is always a component

The new completion path looks solid overall and the error handling is appropriately conservative, but there are two things worth double‑checking:

  1. Assumption about args[0]
    StackFlagCompletion treats args[0] as a component selector for every command that calls AddStackCompletion. If any caller uses AddStackCompletion where the first positional argument is not a component, stack completion will silently return an empty or misleading set. Either:

    • Confirm AddStackCompletion is only used for commands where args[0] is indeed the component, or
    • Narrow this behavior (or document it) so callers understand the contract.
  2. Optional: filter using toComplete
    Right now the completion returns the full list of stacks (or component‑filtered stacks) and relies on Cobra’s own filtering. If the list of stacks is large, you might consider filtering by toComplete in listStacksForComponent/listStacks to reduce payload and improve UX, but this is purely a nicety.

No changes are strictly required, but verifying the args[0] assumption will help avoid subtle completion regressions on non‑terraform commands that reuse AddStackCompletion.

docs/prd/terraform-registry-migration.md (1)

1-353: PRD is clear and matches the staged implementation

The phased plan reads well and aligns with the Phase‑1 changes in this PR (extracted executor/validator/identity logic, exported helpers, no behavior change). Any remaining wording/markdown nits (e.g., trailing punctuation in bullet paragraphs, “hard to add” phrasing) are minor and can be cleaned up opportunistically later.

@mergify
Copy link

mergify bot commented Nov 24, 2025

💥 This pull request now has conflicts. Could you fix it @osterman? 🙏

@mergify mergify bot added the conflict This PR has conflicts label Nov 24, 2025
@github-actions
Copy link

github-actions bot commented Nov 25, 2025

Warning

Changelog Entry Required

This PR is labeled minor or major but doesn't include a changelog entry.

Action needed: Add a new blog post in website/blog/ to announce this change.

Example filename: website/blog/2025-12-16-feature-name.mdx

Alternatively: If this change doesn't require a changelog entry, remove the minor or major label.

@mergify mergify bot removed the conflict This PR has conflicts label Nov 25, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
cmd/terraform/utils.go (1)

30-33: Critical: Fix double-dash slicing order to avoid losing pass-through args.

The code truncates finalArgs before extracting argsAfterDoubleDash, so the tail after -- is never captured. This breaks hook processing when users pass -- and pass-through args.

Extract argsAfterDoubleDash before truncating finalArgs:

 	doubleDashIndex := lo.IndexOf(finalArgs, "--")
 	if doubleDashIndex > 0 {
+		argsAfterDoubleDash = lo.Slice(finalArgs, doubleDashIndex+1, len(finalArgs))
 		finalArgs = lo.Slice(finalArgs, 0, doubleDashIndex)
-		argsAfterDoubleDash = lo.Slice(finalArgs, doubleDashIndex+1, len(finalArgs))
 	}
🧹 Nitpick comments (4)
tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden (1)

4-11: Clarify the “Explanation” block content

The new header + error line look consistent, but the ## Explanation section currently shows only two raw path/glob expressions. That may be a bit opaque to users skimming stderr; consider having the upstream error message include a short natural-language sentence (e.g. “These are example stack glob patterns Atmos tried to use:”) or explicit labels so the purpose of the two lines is obvious.

Also, please double‑check whether '/absolute/path/to/repo/stacks/orgs/**/*****.yaml' is the exact glob you intend to surface versus something like **/*.yaml. If this is exactly what the CLI now emits and is correct for your globbing semantics, then the snapshot is fine as‑is and shouldn’t be hand‑tweaked here.

Based on learnings, snapshots should mirror the exact CLI output, so only adjust this after confirming the upstream message is what you want.

cmd/terraform/generate/varfile/varfile.go (3)

3-9: Organize imports per guidelines.

Add a blank line between the 3rd-party import (cobra) and Atmos packages to follow the project's import organization standard.

Apply this diff:

 import (
 	"github.com/spf13/cobra"
+
 	e "github.com/cloudposse/atmos/internal/exec"
 	cfg "github.com/cloudposse/atmos/pkg/config"
 	"github.com/cloudposse/atmos/pkg/schema"
 )

33-34: Handle flag parsing errors explicitly.

While the stack flag is marked required and errors are unlikely, explicitly handling these errors improves code robustness.

Consider this approach:

-	stack, _ := cmd.Flags().GetString("stack")
-	file, _ := cmd.Flags().GetString("file")
+	stack, err := cmd.Flags().GetString("stack")
+	if err != nil {
+		return err
+	}
+	file, _ := cmd.Flags().GetString("file")

31-50: Consider using StandardFlagParser per PR objectives.

The PR objectives mention "Updates flag handling to use the StandardFlagParser pattern," but this implementation still uses direct cmd.Flags() access. Consider migrating to flags.NewStandardParser() for consistency with the broader refactoring effort.

Is the StandardFlagParser migration intended for this command, or is it being deferred to a follow-up?

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bb1bb97 and 71a7bc6.

📒 Files selected for processing (19)
  • cmd/auth_login.go (1 hunks)
  • cmd/cmd_utils.go (3 hunks)
  • cmd/root.go (2 hunks)
  • cmd/terraform/generate/varfile/varfile.go (3 hunks)
  • cmd/terraform/terraform.go (1 hunks)
  • cmd/terraform/utils.go (1 hunks)
  • internal/exec/cli_utils.go (0 hunks)
  • internal/exec/terraform_utils.go (1 hunks)
  • pkg/flags/flag_parser.go (2 hunks)
  • tests/snapshots/TestCLICommands_atmos_terraform_apply_--help.stderr.golden (0 hunks)
  • tests/snapshots/TestCLICommands_atmos_terraform_apply_help.stderr.golden (0 hunks)
  • tests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.golden (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stdout.golden (0 hunks)
  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden (1 hunks)
  • tests/snapshots/TestCLICommands_completion_for_stacks_should_be_filtered_by_component.stdout.golden (0 hunks)
  • tests/snapshots/TestCLICommands_completion_for_stacks_should_be_suggested.stdout.golden (0 hunks)
💤 Files with no reviewable changes (6)
  • tests/snapshots/TestCLICommands_atmos_terraform_apply_help.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_apply_--help.stderr.golden
  • internal/exec/cli_utils.go
  • tests/snapshots/TestCLICommands_completion_for_stacks_should_be_suggested.stdout.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stdout.golden
  • tests/snapshots/TestCLICommands_completion_for_stacks_should_be_filtered_by_component.stdout.golden
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/root.go
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: Use functional options pattern to avoid functions with many parameters. Define Option functions that modify a Config struct and pass variadic options to New functions.
Use context.Context for cancellation signals, deadlines/timeouts, and request-scoped values (trace IDs). Context should be first parameter in functions that accept it. DO NOT use context for configuration, dependencies, or avoiding proper function parameters.
All comments must end with periods. This is enforced by the godot linter.
NEVER delete existing comments without a very strong reason. Preserve helpful comments, update them to match code changes, refactor for clarity, and add context when modifying code. Only remove factually incorrect, duplicated, or outdated comments.
Organize imports in three groups separated by blank lines (Go stdlib, 3rd-party excluding cloudposse/atmos, Atmos packages), sorted alphabetically. Maintain aliases: cfg, log, u, errUtils.
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig parameter.
All errors MUST be wrapped using static errors defined in errors/errors.go. Use errors.Join for combining multiple errors, fmt.Errorf with %w for adding string context, error builder for complex errors, and errors.Is() for error checking. NEVER use dynamic errors directly.
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation. Never create manual mocks.
Use viper.BindEnv with ATMOS_ prefix for environment variables.
Use colors from pkg/ui/theme/colors.go for theme consistency.
Ensure Linux/macOS/Windows compatibility. Use SDKs over binaries. Use filepath.Join(), not hardcoded path separators.
Small focused files (<600 lines). One cmd/impl per file. Co-locate tests. Never use //revive:disable:file-length-limit.

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider us...

Files:

  • cmd/auth_login.go
  • cmd/terraform/generate/varfile/varfile.go
  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
  • cmd/terraform/terraform.go
  • cmd/cmd_utils.go
  • internal/exec/terraform_utils.go
cmd/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

cmd/**/*.go: Use unified flag parsing infrastructure in pkg/flags/. Commands MUST use flags.NewStandardParser() for command-specific flags. NEVER call viper.BindEnv() or viper.BindPFlag() directly outside pkg/flags/ (Forbidigo enforces this).
Telemetry is auto-enabled via RootCmd.ExecuteC(). Non-standard paths use telemetry.CaptureCmd(). Never capture user data.

cmd/**/*.go: Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under cmd/ directory
Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands

Files:

  • cmd/auth_login.go
  • cmd/terraform/generate/varfile/varfile.go
  • cmd/terraform/utils.go
  • cmd/terraform/terraform.go
  • cmd/cmd_utils.go
🧠 Learnings (71)
📓 Common learnings
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.181Z
Learning: Applies to cmd/**/*.go : Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under `cmd/` directory
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: cmd/terraform.go:111-117
Timestamp: 2025-06-23T02:14:30.937Z
Learning: In cmd/terraform.go, flags for the DescribeAffected function are added dynamically at runtime when info.Affected is true. This is intentional to avoid exposing internal flags like "file", "format", "verbose", "include-spacelift-admin-stacks", "include-settings", and "upload" in the terraform command interface, while still providing them for the shared DescribeAffected function used by both `atmos describe affected` and `atmos terraform apply --affected`.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.181Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.287Z
Learning: When adding new CLI commands: 1) Create cmd/[command]/ with CommandProvider interface, 2) Add blank import to cmd/root.go, 3) Implement in internal/exec/mycommand.go, 4) Add tests in cmd/mycommand/mycommand_test.go, 5) Create Docusaurus docs, 6) Build website.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 759
File: internal/exec/terraform.go:366-368
Timestamp: 2024-11-02T15:35:09.958Z
Learning: In `internal/exec/terraform.go`, the workspace cleaning code under both the general execution path and within the `case "init":` block is intentionally duplicated because the code execution paths are different. The `.terraform/environment` file should be deleted before executing `terraform init` in both scenarios to ensure a clean state.
📚 Learning: 2025-09-25T01:02:48.697Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/manager.go:304-312
Timestamp: 2025-09-25T01:02:48.697Z
Learning: The auth manager in pkg/auth/manager.go should remain cloud-agnostic and not contain AWS-specific logic or references to specific cloud providers. Keep the manager generic and extensible.

Applied to files:

  • cmd/auth_login.go
📚 Learning: 2024-12-07T16:16:13.038Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.

Applied to files:

  • cmd/terraform/generate/varfile/varfile.go
  • cmd/terraform/utils.go
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden
  • pkg/flags/flag_parser.go
  • cmd/terraform/terraform.go
  • cmd/cmd_utils.go
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden
  • internal/exec/terraform_utils.go
📚 Learning: 2025-10-10T23:51:36.597Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.

Applied to files:

  • cmd/terraform/generate/varfile/varfile.go
  • cmd/terraform/utils.go
  • tests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.golden
  • cmd/terraform/terraform.go
  • cmd/cmd_utils.go
  • internal/exec/terraform_utils.go
📚 Learning: 2025-06-23T02:14:30.937Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: cmd/terraform.go:111-117
Timestamp: 2025-06-23T02:14:30.937Z
Learning: In cmd/terraform.go, flags for the DescribeAffected function are added dynamically at runtime when info.Affected is true. This is intentional to avoid exposing internal flags like "file", "format", "verbose", "include-spacelift-admin-stacks", "include-settings", and "upload" in the terraform command interface, while still providing them for the shared DescribeAffected function used by both `atmos describe affected` and `atmos terraform apply --affected`.

Applied to files:

  • cmd/terraform/generate/varfile/varfile.go
  • cmd/terraform/utils.go
  • cmd/terraform/terraform.go
  • cmd/cmd_utils.go
📚 Learning: 2025-01-09T22:37:01.004Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.

Applied to files:

  • cmd/terraform/generate/varfile/varfile.go
  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
  • cmd/terraform/terraform.go
  • cmd/cmd_utils.go
  • internal/exec/terraform_utils.go
📚 Learning: 2025-11-24T17:35:37.181Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.181Z
Learning: Applies to **/*.go : Use Viper for managing configuration, environment variables, and flags in CLI commands

Applied to files:

  • cmd/terraform/generate/varfile/varfile.go
  • pkg/flags/flag_parser.go
📚 Learning: 2025-04-11T22:06:46.999Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1147
File: internal/exec/validate_schema.go:42-57
Timestamp: 2025-04-11T22:06:46.999Z
Learning: The "ExecuteAtmosValidateSchemaCmd" function in internal/exec/validate_schema.go has been reviewed and confirmed to have acceptable cognitive complexity despite static analysis warnings. The function uses a clean structure with only three if statements for error handling and delegates complex operations to helper methods.

Applied to files:

  • cmd/terraform/generate/varfile/varfile.go
📚 Learning: 2025-11-24T17:35:20.287Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.287Z
Learning: Applies to internal/exec/template_funcs.go : New configs support Go templating with FuncMap() from internal/exec/template_funcs.go. Implement template functions in internal/exec/template_funcs.go, register them, add tests, and update documentation.

Applied to files:

  • cmd/terraform/generate/varfile/varfile.go
📚 Learning: 2025-11-08T19:56:18.660Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1697
File: internal/exec/oci_utils.go:0-0
Timestamp: 2025-11-08T19:56:18.660Z
Learning: In the Atmos codebase, when a function receives an `*schema.AtmosConfiguration` parameter, it should read configuration values from `atmosConfig.Settings` fields rather than using direct `os.Getenv()` or `viper.GetString()` calls. The Atmos pattern is: viper.BindEnv in cmd/root.go binds environment variables → Viper unmarshals into atmosConfig.Settings via mapstructure → business logic reads from the Settings struct. This provides centralized config management, respects precedence, and enables testability. Example: `atmosConfig.Settings.AtmosGithubToken` instead of `os.Getenv("ATMOS_GITHUB_TOKEN")` in functions like `getGHCRAuth` in internal/exec/oci_utils.go.

Applied to files:

  • cmd/terraform/generate/varfile/varfile.go
  • internal/exec/terraform_utils.go
📚 Learning: 2025-11-24T17:35:37.181Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.181Z
Learning: Applies to cmd/**/*.go : Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under `cmd/` directory

Applied to files:

  • cmd/terraform/generate/varfile/varfile.go
  • pkg/flags/flag_parser.go
  • cmd/terraform/terraform.go
  • cmd/cmd_utils.go
📚 Learning: 2025-10-07T00:25:16.333Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.

Applied to files:

  • cmd/terraform/utils.go
  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.golden
  • pkg/flags/flag_parser.go
  • cmd/terraform/terraform.go
  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden
📚 Learning: 2025-11-24T17:35:37.181Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.181Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions

Applied to files:

  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
  • cmd/terraform/terraform.go
  • cmd/cmd_utils.go
📚 Learning: 2024-10-31T19:25:41.298Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:233-235
Timestamp: 2024-10-31T19:25:41.298Z
Learning: When specifying color values in functions like `confirmDeleteTerraformLocal` in `internal/exec/terraform_clean.go`, avoid hardcoding color values. Instead, use predefined color constants or allow customization through configuration settings to improve accessibility and user experience across different terminals and themes.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-09-13T18:06:07.674Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/list.go:39-42
Timestamp: 2025-09-13T18:06:07.674Z
Learning: In the cloudposse/atmos repository, for UI messages in the toolchain package, use utils.PrintfMessageToTUI instead of log.Error or fmt.Fprintln(os.Stderr, ...). Import pkg/utils with alias "u" to follow the established pattern.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2024-11-16T17:30:52.893Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 786
File: internal/exec/shell_utils.go:159-162
Timestamp: 2024-11-16T17:30:52.893Z
Learning: For the `atmos terraform shell` command in `internal/exec/shell_utils.go`, input validation for the custom shell prompt is not required, as users will use this as a CLI tool and any issues will impact themselves.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
  • internal/exec/terraform_utils.go
📚 Learning: 2025-01-07T20:38:09.618Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 896
File: cmd/editor_config.go:37-40
Timestamp: 2025-01-07T20:38:09.618Z
Learning: Error handling suggestion for `cmd.Help()` in `cmd/editor_config.go` was deferred as the code is planned for future modifications.

Applied to files:

  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
📚 Learning: 2025-09-30T19:03:50.738Z
Learnt from: Cerebrovinny
Repo: cloudposse/atmos PR: 1560
File: pkg/utils/string_utils.go:43-64
Timestamp: 2025-09-30T19:03:50.738Z
Learning: In the Atmos codebase, YAML tags like !terraform.output rely on positional arguments, so the SplitStringByDelimiter function in pkg/utils/string_utils.go must preserve empty strings (even after trimming quotes) to maintain the correct number of positional arguments. Filtering out empty values after trimming would collapse the array and break these function calls.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2024-12-07T16:19:01.683Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.

Applied to files:

  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
  • internal/exec/terraform_utils.go
📚 Learning: 2025-05-22T15:42:10.906Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1261
File: internal/exec/utils.go:639-640
Timestamp: 2025-05-22T15:42:10.906Z
Learning: In the Atmos codebase, when appending slices with `args := append(configAndStacksInfo.CliArgs, configAndStacksInfo.AdditionalArgsAndFlags...)`, it's intentional that the result is not stored back in the original slice. This pattern is used when the merged result serves a different purpose than the original slices, such as when creating a filtered version for component section assignments.

Applied to files:

  • cmd/terraform/utils.go
  • cmd/cmd_utils.go
📚 Learning: 2025-09-05T14:57:37.360Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 1448
File: cmd/ansible.go:26-28
Timestamp: 2025-09-05T14:57:37.360Z
Learning: The Atmos codebase uses a consistent pattern for commands that delegate to external tools: `PersistentFlags().Bool("", false, doubleDashHint)` where doubleDashHint provides help text about using double dashes to separate Atmos options from native command arguments. This pattern is used across terraform, packer, helmfile, atlantis, aws, and ansible commands.

Applied to files:

  • cmd/terraform/utils.go
  • tests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.golden
  • pkg/flags/flag_parser.go
  • cmd/terraform/terraform.go
📚 Learning: 2025-10-03T18:02:08.535Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: internal/exec/terraform.go:269-272
Timestamp: 2025-10-03T18:02:08.535Z
Learning: In internal/exec/terraform.go, when auth.TerraformPreHook fails, the error is logged but execution continues. This is a deliberate design choice to allow Terraform commands to proceed even if authentication setup fails, rather than failing fast.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2024-11-30T22:07:08.610Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: internal/exec/yaml_func_terraform_output.go:35-40
Timestamp: 2024-11-30T22:07:08.610Z
Learning: In the Go function `processTagTerraformOutput` in `internal/exec/yaml_func_terraform_output.go`, parameters cannot contain spaces. The code splits the input by spaces, and if the parameters contain spaces, `len(parts) != 3` will fail and show an error to the user.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-01-09T22:27:25.538Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/validate_stacks.go:20-23
Timestamp: 2025-01-09T22:27:25.538Z
Learning: The validate commands in Atmos can have different help handling implementations. Specifically, validate_component.go and validate_stacks.go are designed to handle help requests differently, with validate_stacks.go including positional argument checks while validate_component.go does not.

Applied to files:

  • cmd/terraform/utils.go
  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden
  • internal/exec/terraform_utils.go
📚 Learning: 2025-02-09T14:38:53.443Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 992
File: cmd/cmd_utils.go:0-0
Timestamp: 2025-02-09T14:38:53.443Z
Learning: Error handling for RegisterFlagCompletionFunc in AddStackCompletion is not required as the errors are non-critical for tab completion functionality.

Applied to files:

  • cmd/terraform/utils.go
  • cmd/cmd_utils.go
📚 Learning: 2025-10-11T19:12:38.832Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: tests/snapshots/TestCLICommands_atmos_workflow_invalid_step_type.stderr.golden:0-0
Timestamp: 2025-10-11T19:12:38.832Z
Learning: Usage Examples sections in error output are appropriate for command usage errors (incorrect syntax, missing arguments, invalid flags) but not for configuration validation errors (malformed workflow files, invalid settings in atmos.yaml). Configuration errors should focus on explaining what's wrong with the config, not command usage patterns.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden
📚 Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden
📚 Learning: 2025-01-19T15:49:15.593Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 955
File: tests/snapshots/TestCLICommands_atmos_validate_editorconfig_--help.stdout.golden:0-0
Timestamp: 2025-01-19T15:49:15.593Z
Learning: In future commits, the help text for Atmos CLI commands should be limited to only show component and stack parameters for commands that actually use them. This applies to the example usage section in command help text.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden
📚 Learning: 2025-02-18T13:13:11.497Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: tests/snapshots/TestCLICommands_atmos_terraform_help.stdout.golden:59-64
Timestamp: 2025-02-18T13:13:11.497Z
Learning: For Atmos CLI help text, angle brackets in command examples and flag descriptions should be escaped using HTML entities (e.g., `&lt;component&gt;`) rather than converted to backticks or other markdown formatting.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.golden
📚 Learning: 2025-01-30T19:30:59.120Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/workflow.go:74-74
Timestamp: 2025-01-30T19:30:59.120Z
Learning: Error handling for `cmd.Usage()` is not required in the Atmos CLI codebase, as confirmed by the maintainer.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.golden
  • pkg/flags/flag_parser.go
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning the error instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden
📚 Learning: 2024-12-01T00:33:20.298Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml:28-32
Timestamp: 2024-12-01T00:33:20.298Z
Learning: In `examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml`, `!exec atmos terraform output` is used in examples to demonstrate its usage, even though `!terraform.output` is the recommended approach according to the documentation.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden
📚 Learning: 2024-10-21T17:51:53.976Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform.go:114-118
Timestamp: 2024-10-21T17:51:53.976Z
Learning: When `atmos terraform clean --everything` is used without specifying a component and without the `--force` flag, prompt the user for confirmation before deleting all components. Use the `--force` flag to skip the confirmation prompt.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden
📚 Learning: 2024-12-03T05:29:07.718Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: internal/exec/terraform_utils.go:145-146
Timestamp: 2024-12-03T05:29:07.718Z
Learning: In the Atmos project, a 5-minute timeout in the `execTerraformOutput` function is acceptable for retrieving `terraform output` for a component in a stack.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.golden
  • tests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.golden
📚 Learning: 2025-11-24T17:35:20.287Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.287Z
Learning: Applies to cmd/**/*.go : Use unified flag parsing infrastructure in pkg/flags/. Commands MUST use flags.NewStandardParser() for command-specific flags. NEVER call viper.BindEnv() or viper.BindPFlag() directly outside pkg/flags/ (Forbidigo enforces this).

Applied to files:

  • pkg/flags/flag_parser.go
  • cmd/terraform/terraform.go
📚 Learning: 2025-11-10T03:03:31.505Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-11-10T03:03:31.505Z
Learning: In the Atmos codebase, commands using the `StandardParser` flag pattern (from pkg/flags) do NOT need explicit `viper.BindPFlag()` calls in their code. The StandardParser encapsulates flag binding internally: flags are registered via `parser.RegisterFlags(cmd)` in init(), and bound via `parser.BindFlagsToViper(cmd, v)` in RunE, which internally calls viper.BindPFlag for each flag. This pattern is used throughout Atmos (e.g., cmd/toolchain/get.go, cmd/toolchain/info.go, cmd/toolchain/install.go, cmd/toolchain/path.go). Do not flag missing viper.BindPFlag calls when StandardParser is used.

Applied to files:

  • pkg/flags/flag_parser.go
  • cmd/terraform/terraform.go
📚 Learning: 2025-11-24T17:35:37.181Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.181Z
Learning: Applies to **/*.go : Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2025-02-18T13:18:53.146Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-18T13:18:53.146Z
Learning: Error checking is not required for cobra.Command.RegisterFlagCompletionFunc calls as these are static configurations done at init time.

Applied to files:

  • pkg/flags/flag_parser.go
  • cmd/cmd_utils.go
📚 Learning: 2025-02-07T19:21:38.028Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 992
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-07T19:21:38.028Z
Learning: The cobra.Command.RegisterFlagCompletionFunc method (as of cobra v1.8.1) never returns an error. It only initializes an internal map and stores the completion function, always returning nil. Error handling for this method call is unnecessary.

Applied to files:

  • pkg/flags/flag_parser.go
  • cmd/cmd_utils.go
📚 Learning: 2025-11-24T17:35:20.287Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.287Z
Learning: Applies to **/*.go : All errors MUST be wrapped using static errors defined in errors/errors.go. Use errors.Join for combining multiple errors, fmt.Errorf with %w for adding string context, error builder for complex errors, and errors.Is() for error checking. NEVER use dynamic errors directly.

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2025-02-03T06:00:11.419Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/describe_config.go:20-20
Timestamp: 2025-02-03T06:00:11.419Z
Learning: Commands should use `PrintErrorMarkdownAndExit` with empty title and suggestion (`"", err, ""`) for general error handling. Specific titles like "Invalid Usage" or "File Not Found" should only be used for validation or specific error scenarios.

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2025-01-18T15:15:41.645Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform.go:37-46
Timestamp: 2025-01-18T15:15:41.645Z
Learning: In the atmos CLI, error handling is intentionally structured to use LogErrorAndExit for consistent error display, avoiding Cobra's default error handling to prevent duplicate error messages.

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2024-12-05T22:33:54.807Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 820
File: cmd/list_stacks.go:55-56
Timestamp: 2024-12-05T22:33:54.807Z
Learning: In the atmos project, the `u.LogErrorAndExit` function logs the error and exits the command execution appropriately within flag completion functions.

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2024-12-11T18:40:12.808Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/helmfile.go:37-37
Timestamp: 2024-12-11T18:40:12.808Z
Learning: In the atmos project, `cliConfig` is initialized within the `cmd` package in `root.go` and can be used in other command files.

Applied to files:

  • pkg/flags/flag_parser.go
  • cmd/terraform/terraform.go
  • cmd/cmd_utils.go
  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
📚 Learning: 2025-09-07T18:07:00.549Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1452
File: cmd/auth_login.go:43-44
Timestamp: 2025-09-07T18:07:00.549Z
Learning: In the atmos project, the identity flag is defined as a persistent flag on the auth root command (cmd/auth.go), making it available to all auth subcommands without needing to be redefined in each individual subcommand.

Applied to files:

  • cmd/terraform/terraform.go
  • cmd/cmd_utils.go
📚 Learning: 2024-10-20T13:12:46.499Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 736
File: pkg/config/const.go:6-6
Timestamp: 2024-10-20T13:12:46.499Z
Learning: In `cmd/cmd_utils.go`, it's acceptable to have hardcoded references to `atmos.yaml` in logs, and it's not necessary to update them to use the `CliConfigFileName` constant.

Applied to files:

  • cmd/cmd_utils.go
📚 Learning: 2024-12-13T15:28:13.630Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/version.go:34-44
Timestamp: 2024-12-13T15:28:13.630Z
Learning: In `cmd/version.go`, when handling the `--check` flag in the `versionCmd`, avoid using `CheckForAtmosUpdateAndPrintMessage(cliConfig)` as it updates the cache timestamp, which may not be desired in this context.

Applied to files:

  • cmd/cmd_utils.go
  • internal/exec/terraform_utils.go
📚 Learning: 2025-02-07T19:21:38.028Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 992
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-07T19:21:38.028Z
Learning: The cobra.Command.RegisterFlagCompletionFunc method never returns an error as it simply stores the completion function in an internal map. Error handling for this method call is unnecessary.

Applied to files:

  • cmd/cmd_utils.go
📚 Learning: 2025-09-24T20:45:40.401Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: tests/fixtures/scenarios/atmos-auth/stacks/deploy/nonprod.yaml:3-4
Timestamp: 2025-09-24T20:45:40.401Z
Learning: In Atmos stack files, the correct syntax for importing other stack files is `import:` (singular), not `imports:` (plural). All stack files in the Atmos codebase consistently use `import:` followed by a list of paths to import.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
📚 Learning: 2025-09-10T21:17:55.273Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/http_client_test.go:3-10
Timestamp: 2025-09-10T21:17:55.273Z
Learning: In the cloudposse/atmos repository, imports should never be changed as per samtholiya's coding guidelines.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
📚 Learning: 2025-02-03T05:57:18.407Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/cmd_utils.go:121-148
Timestamp: 2025-02-03T05:57:18.407Z
Learning: The Atmos CLI should fail fast (exit) when encountering configuration errors, including command alias configuration issues, to prevent undefined behavior. Use LogErrorAndExit instead of returning errors in such cases.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
📚 Learning: 2025-02-24T22:46:39.744Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/load.go:219-221
Timestamp: 2025-02-24T22:46:39.744Z
Learning: In the Atmos configuration system, imports from atmos.d are optional. When import errors occur, they should be logged at debug level and the process should continue, rather than failing completely.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
📚 Learning: 2025-03-17T18:41:08.831Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/imports.go:68-75
Timestamp: 2025-03-17T18:41:08.831Z
Learning: In the Atmos configuration import system, errors during config file merging are logged at debug level and the process continues with other imports rather than failing completely, prioritizing resilience over strict correctness.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
📚 Learning: 2025-01-25T15:21:40.413Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:8-8
Timestamp: 2025-01-25T15:21:40.413Z
Learning: In Atmos, when a directory is specified for configuration loading (e.g., in the `import` section of atmos.yaml), all files within that directory should be treated as Atmos configurations. Do not suggest restricting file extensions in directory-based glob patterns.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
📚 Learning: 2024-11-25T17:17:15.703Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 797
File: pkg/list/atmos.yaml:213-214
Timestamp: 2024-11-25T17:17:15.703Z
Learning: The file `pkg/list/atmos.yaml` is primarily intended for testing purposes.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
📚 Learning: 2024-12-12T15:15:46.457Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:7-7
Timestamp: 2024-12-12T15:15:46.457Z
Learning: In example configuration files, such as `examples/demo-atmos-cli-imports/atmos.yaml`, it's acceptable to use `refs/heads/main` in remote URLs.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.golden
📚 Learning: 2024-10-27T04:41:49.199Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:215-223
Timestamp: 2024-10-27T04:41:49.199Z
Learning: In `internal/exec/terraform_clean.go`, the function `determineCleanPath` is necessary and should not be removed.

Applied to files:

  • internal/exec/terraform_utils.go
📚 Learning: 2024-10-31T19:23:45.538Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform.go:65-66
Timestamp: 2024-10-31T19:23:45.538Z
Learning: The variable `shouldCheckStack` in `ExecuteTerraform` controls whether validation is performed.

Applied to files:

  • internal/exec/terraform_utils.go
📚 Learning: 2024-11-13T21:37:07.852Z
Learnt from: Cerebrovinny
Repo: cloudposse/atmos PR: 764
File: internal/exec/describe_stacks.go:289-295
Timestamp: 2024-11-13T21:37:07.852Z
Learning: In the `internal/exec/describe_stacks.go` file of the `atmos` project written in Go, avoid extracting the stack name handling logic into a helper function within the `ExecuteDescribeStacks` method, even if the logic appears duplicated.

Applied to files:

  • internal/exec/terraform_utils.go
📚 Learning: 2024-11-24T19:13:10.287Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:407-416
Timestamp: 2024-11-24T19:13:10.287Z
Learning: In `internal/exec/terraform_clean.go`, when `getStackTerraformStateFolder` returns an error in the `handleCleanSubCommand` function, the error is logged, and the process continues without returning the error.

Applied to files:

  • internal/exec/terraform_utils.go
📚 Learning: 2024-11-12T03:16:02.910Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 775
File: internal/exec/template_funcs_component.go:157-159
Timestamp: 2024-11-12T03:16:02.910Z
Learning: In the Go code for `componentFunc` in `internal/exec/template_funcs_component.go`, the function `cleanTerraformWorkspace` does not return errors, and it's acceptable if the file does not exist. Therefore, error handling for `cleanTerraformWorkspace` is not needed.

Applied to files:

  • internal/exec/terraform_utils.go
📚 Learning: 2024-10-30T13:25:45.965Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:405-412
Timestamp: 2024-10-30T13:25:45.965Z
Learning: In `internal/exec/terraform_clean.go`, when appending `stackFolders` to `folders` in the `handleCleanSubCommand` function, it's unnecessary to check if `stackFolders` is nil before appending, because in Go, appending a nil slice is safe and does not cause a panic.

Applied to files:

  • internal/exec/terraform_utils.go
📚 Learning: 2025-10-08T06:48:07.499Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1602
File: internal/exec/stack_processor_utils.go:968-1003
Timestamp: 2025-10-08T06:48:07.499Z
Learning: The `FindComponentDependenciesLegacy` function in `internal/exec/stack_processor_utils.go` is legacy code that is not actively used and is kept only for backward compatibility purposes.

Applied to files:

  • internal/exec/terraform_utils.go
📚 Learning: 2024-11-02T15:35:09.958Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 759
File: internal/exec/terraform.go:366-368
Timestamp: 2024-11-02T15:35:09.958Z
Learning: In `internal/exec/terraform.go`, the workspace cleaning code under both the general execution path and within the `case "init":` block is intentionally duplicated because the code execution paths are different. The `.terraform/environment` file should be deleted before executing `terraform init` in both scenarios to ensure a clean state.

Applied to files:

  • internal/exec/terraform_utils.go
📚 Learning: 2025-10-11T19:11:58.965Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:0-0
Timestamp: 2025-10-11T19:11:58.965Z
Learning: For terraform apply interactivity checks in Atmos (internal/exec/terraform.go), use stdin TTY detection (e.g., `IsTTYSupportForStdin()` or checking `os.Stdin`) to determine if user prompts are possible. This is distinct from stdout/stderr TTY checks used for output display (like TUI rendering). User input requires stdin to be a TTY; output display requires stdout/stderr to be a TTY.

Applied to files:

  • internal/exec/terraform_utils.go
📚 Learning: 2024-10-20T00:57:53.500Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 731
File: internal/exec/validate_stacks.go:0-0
Timestamp: 2024-10-20T00:57:53.500Z
Learning: In `internal/exec/validate_stacks.go`, when downloading the Atmos JSON Schema file to the temp directory, the temporary file is overwritten each time, so explicit removal is not necessary.

Applied to files:

  • internal/exec/terraform_utils.go
📚 Learning: 2024-11-19T23:00:45.899Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 795
File: internal/exec/stack_processor_utils.go:378-386
Timestamp: 2024-11-19T23:00:45.899Z
Learning: In the `ProcessYAMLConfigFile` function within `internal/exec/stack_processor_utils.go`, directory traversal in stack imports is acceptable and should not be restricted.

Applied to files:

  • internal/exec/terraform_utils.go
📚 Learning: 2024-12-02T21:26:32.337Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: pkg/config/config.go:478-483
Timestamp: 2024-12-02T21:26:32.337Z
Learning: In the 'atmos' project, when reviewing Go code like `pkg/config/config.go`, avoid suggesting file size checks after downloading remote configs if such checks aren't implemented elsewhere in the codebase.

Applied to files:

  • internal/exec/terraform_utils.go
🧬 Code graph analysis (3)
cmd/auth_login.go (3)
pkg/schema/schema_auth.go (1)
  • AuthConfig (4-12)
pkg/auth/types/interfaces.go (1)
  • AuthManager (128-237)
pkg/auth/hooks.go (1)
  • AuthManager (24-24)
cmd/cmd_utils.go (1)
pkg/schema/schema.go (1)
  • ConfigAndStacksInfo (621-715)
internal/exec/terraform_utils.go (1)
pkg/schema/schema.go (1)
  • ConfigAndStacksInfo (621-715)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 71a7bc6 and fb8173c.

📒 Files selected for processing (10)
  • cmd/terraform/completion.go (1 hunks)
  • cmd/terraform/terraform.go (1 hunks)
  • pkg/flags/registry.go (6 hunks)
  • pkg/flags/standard.go (3 hunks)
  • pkg/flags/standard_parser.go (1 hunks)
  • pkg/flags/types.go (5 hunks)
  • tests/snapshots/TestCLICommands_completion_for_stacks_should_be_filtered_by_component.stdout.golden (0 hunks)
  • tests/snapshots/TestCLICommands_completion_for_stacks_should_be_suggested.stdout.golden (0 hunks)
  • tests/test-cases/tab-completions.yaml (2 hunks)
  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx (1 hunks)
💤 Files with no reviewable changes (2)
  • tests/snapshots/TestCLICommands_completion_for_stacks_should_be_suggested.stdout.golden
  • tests/snapshots/TestCLICommands_completion_for_stacks_should_be_filtered_by_component.stdout.golden
🚧 Files skipped from review as they are similar to previous changes (2)
  • cmd/terraform/terraform.go
  • cmd/terraform/completion.go
🧰 Additional context used
📓 Path-based instructions (4)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: Use functional options pattern to avoid functions with many parameters. Define Option functions that modify a Config struct and pass variadic options to New functions.
Use context.Context for cancellation signals, deadlines/timeouts, and request-scoped values (trace IDs). Context should be first parameter in functions that accept it. DO NOT use context for configuration, dependencies, or avoiding proper function parameters.
All comments must end with periods. This is enforced by the godot linter.
NEVER delete existing comments without a very strong reason. Preserve helpful comments, update them to match code changes, refactor for clarity, and add context when modifying code. Only remove factually incorrect, duplicated, or outdated comments.
Organize imports in three groups separated by blank lines (Go stdlib, 3rd-party excluding cloudposse/atmos, Atmos packages), sorted alphabetically. Maintain aliases: cfg, log, u, errUtils.
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig parameter.
All errors MUST be wrapped using static errors defined in errors/errors.go. Use errors.Join for combining multiple errors, fmt.Errorf with %w for adding string context, error builder for complex errors, and errors.Is() for error checking. NEVER use dynamic errors directly.
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation. Never create manual mocks.
Use viper.BindEnv with ATMOS_ prefix for environment variables.
Use colors from pkg/ui/theme/colors.go for theme consistency.
Ensure Linux/macOS/Windows compatibility. Use SDKs over binaries. Use filepath.Join(), not hardcoded path separators.
Small focused files (<600 lines). One cmd/impl per file. Co-locate tests. Never use //revive:disable:file-length-limit.

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider us...

Files:

  • pkg/flags/standard.go
  • pkg/flags/standard_parser.go
  • pkg/flags/types.go
  • pkg/flags/registry.go
website/blog/**/*.mdx

📄 CodeRabbit inference engine (CLAUDE.md)

PRs labeled minor/major MUST include blog post at website/blog/YYYY-MM-DD-feature-name.mdx with YAML front matter, after intro, tags (feature/enhancement/bugfix/contributors), and author (committer's GitHub username).

Files:

  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx
website/**

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

website/**: Update website documentation in the website/ directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in the website/ directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Files:

  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx
tests/test-cases/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER modify tests/test-cases/ or tests/testdata/ unless explicitly instructed. Golden snapshots are sensitive to minor changes.

Files:

  • tests/test-cases/tab-completions.yaml
🧠 Learnings (23)
📓 Common learnings
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under `cmd/` directory
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: cmd/terraform.go:111-117
Timestamp: 2025-06-23T02:14:30.937Z
Learning: In cmd/terraform.go, flags for the DescribeAffected function are added dynamically at runtime when info.Affected is true. This is intentional to avoid exposing internal flags like "file", "format", "verbose", "include-spacelift-admin-stacks", "include-settings", and "upload" in the terraform command interface, while still providing them for the shared DescribeAffected function used by both `atmos describe affected` and `atmos terraform apply --affected`.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: When adding new CLI commands: 1) Create cmd/[command]/ with CommandProvider interface, 2) Add blank import to cmd/root.go, 3) Implement in internal/exec/mycommand.go, 4) Add tests in cmd/mycommand/mycommand_test.go, 5) Create Docusaurus docs, 6) Build website.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:233-235
Timestamp: 2024-10-31T19:25:41.298Z
Learning: When specifying color values in functions like `confirmDeleteTerraformLocal` in `internal/exec/terraform_clean.go`, avoid hardcoding color values. Instead, use predefined color constants or allow customization through configuration settings to improve accessibility and user experience across different terminals and themes.
📚 Learning: 2025-11-10T03:03:31.505Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-11-10T03:03:31.505Z
Learning: In the Atmos codebase, commands using the `StandardParser` flag pattern (from pkg/flags) do NOT need explicit `viper.BindPFlag()` calls in their code. The StandardParser encapsulates flag binding internally: flags are registered via `parser.RegisterFlags(cmd)` in init(), and bound via `parser.BindFlagsToViper(cmd, v)` in RunE, which internally calls viper.BindPFlag for each flag. This pattern is used throughout Atmos (e.g., cmd/toolchain/get.go, cmd/toolchain/info.go, cmd/toolchain/install.go, cmd/toolchain/path.go). Do not flag missing viper.BindPFlag calls when StandardParser is used.

Applied to files:

  • pkg/flags/standard.go
  • pkg/flags/standard_parser.go
📚 Learning: 2025-02-07T19:21:38.028Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 992
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-07T19:21:38.028Z
Learning: The cobra.Command.RegisterFlagCompletionFunc method (as of cobra v1.8.1) never returns an error. It only initializes an internal map and stores the completion function, always returning nil. Error handling for this method call is unnecessary.

Applied to files:

  • pkg/flags/standard.go
  • pkg/flags/types.go
  • pkg/flags/registry.go
📚 Learning: 2025-02-18T13:18:53.146Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-18T13:18:53.146Z
Learning: Error checking is not required for cobra.Command.RegisterFlagCompletionFunc calls as these are static configurations done at init time.

Applied to files:

  • pkg/flags/standard.go
  • pkg/flags/types.go
  • pkg/flags/registry.go
📚 Learning: 2025-02-07T19:21:38.028Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 992
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-07T19:21:38.028Z
Learning: The cobra.Command.RegisterFlagCompletionFunc method never returns an error as it simply stores the completion function in an internal map. Error handling for this method call is unnecessary.

Applied to files:

  • pkg/flags/standard.go
  • pkg/flags/types.go
  • pkg/flags/registry.go
📚 Learning: 2025-02-09T14:38:53.443Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 992
File: cmd/cmd_utils.go:0-0
Timestamp: 2025-02-09T14:38:53.443Z
Learning: Error handling for RegisterFlagCompletionFunc in AddStackCompletion is not required as the errors are non-critical for tab completion functionality.

Applied to files:

  • pkg/flags/standard.go
  • pkg/flags/types.go
  • pkg/flags/registry.go
  • tests/test-cases/tab-completions.yaml
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to cmd/**/*.go : Use unified flag parsing infrastructure in pkg/flags/. Commands MUST use flags.NewStandardParser() for command-specific flags. NEVER call viper.BindEnv() or viper.BindPFlag() directly outside pkg/flags/ (Forbidigo enforces this).

Applied to files:

  • pkg/flags/standard.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Use Viper for managing configuration, environment variables, and flags in CLI commands

Applied to files:

  • pkg/flags/standard.go
📚 Learning: 2025-09-29T15:47:10.908Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1540
File: internal/exec/terraform_cli_args_utils.go:64-73
Timestamp: 2025-09-29T15:47:10.908Z
Learning: In the Atmos codebase, viper.BindEnv is required for CLI commands in the cmd/ package, but internal utilities can use os.Getenv directly when parsing environment variables for business logic purposes. The requirement to use viper is specific to the CLI interface layer, not all environment variable access throughout the codebase.

Applied to files:

  • pkg/flags/standard.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions

Applied to files:

  • pkg/flags/types.go
📚 Learning: 2025-06-23T02:14:30.937Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: cmd/terraform.go:111-117
Timestamp: 2025-06-23T02:14:30.937Z
Learning: In cmd/terraform.go, flags for the DescribeAffected function are added dynamically at runtime when info.Affected is true. This is intentional to avoid exposing internal flags like "file", "format", "verbose", "include-spacelift-admin-stacks", "include-settings", and "upload" in the terraform command interface, while still providing them for the shared DescribeAffected function used by both `atmos describe affected` and `atmos terraform apply --affected`.

Applied to files:

  • pkg/flags/registry.go
  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx
📚 Learning: 2025-10-10T23:51:36.597Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.

Applied to files:

  • pkg/flags/registry.go
  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx
📚 Learning: 2025-10-07T00:25:16.333Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.

Applied to files:

  • pkg/flags/registry.go
  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx
📚 Learning: 2024-10-31T19:25:41.298Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:233-235
Timestamp: 2024-10-31T19:25:41.298Z
Learning: When specifying color values in functions like `confirmDeleteTerraformLocal` in `internal/exec/terraform_clean.go`, avoid hardcoding color values. Instead, use predefined color constants or allow customization through configuration settings to improve accessibility and user experience across different terminals and themes.

Applied to files:

  • pkg/flags/registry.go
📚 Learning: 2024-12-07T16:19:01.683Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.

Applied to files:

  • pkg/flags/registry.go
📚 Learning: 2025-09-05T14:57:37.360Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 1448
File: cmd/ansible.go:26-28
Timestamp: 2025-09-05T14:57:37.360Z
Learning: The Atmos codebase uses a consistent pattern for commands that delegate to external tools: `PersistentFlags().Bool("", false, doubleDashHint)` where doubleDashHint provides help text about using double dashes to separate Atmos options from native command arguments. This pattern is used across terraform, packer, helmfile, atlantis, aws, and ansible commands.

Applied to files:

  • pkg/flags/registry.go
  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to website/docs/cli/commands/**/*.mdx : Use Docusaurus conventions with frontmatter, purpose note, screengrab, usage/examples/arguments/flags sections for CLI command documentation.

Applied to files:

  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx
📚 Learning: 2025-01-09T22:37:01.004Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.

Applied to files:

  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx
📚 Learning: 2025-09-27T20:50:20.564Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.

Applied to files:

  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx
📚 Learning: 2025-01-19T15:49:15.593Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 955
File: tests/snapshots/TestCLICommands_atmos_validate_editorconfig_--help.stdout.golden:0-0
Timestamp: 2025-01-19T15:49:15.593Z
Learning: In future commits, the help text for Atmos CLI commands should be limited to only show component and stack parameters for commands that actually use them. This applies to the example usage section in command help text.

Applied to files:

  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx
📚 Learning: 2025-01-09T22:27:25.538Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/validate_stacks.go:20-23
Timestamp: 2025-01-09T22:27:25.538Z
Learning: The validate commands in Atmos can have different help handling implementations. Specifically, validate_component.go and validate_stacks.go are designed to handle help requests differently, with validate_stacks.go including positional argument checks while validate_component.go does not.

Applied to files:

  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx
📚 Learning: 2024-12-07T16:16:13.038Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.

Applied to files:

  • website/blog/2025-11-26-terraform-command-registry-pattern.mdx
  • tests/test-cases/tab-completions.yaml
🧬 Code graph analysis (2)
pkg/flags/standard_parser.go (2)
pkg/flags/registry.go (1)
  • FlagRegistry (17-19)
pkg/perf/perf.go (1)
  • Track (121-138)
pkg/flags/types.go (1)
pkg/perf/perf.go (1)
  • Track (121-138)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
🔇 Additional comments (15)
tests/test-cases/tab-completions.yaml (1)

29-29: Verify test-cases file modification aligns with refactoring scope.

The coding guidelines strictly state: "NEVER modify tests/test-cases/ or tests/testdata/ unless explicitly instructed" due to golden snapshot sensitivity. The flag format change from --stack to --stack= appears intentional for the completion subsystem improvements, but I need confirmation.

  • Is this change necessary for the StandardFlagParser pattern migration?
  • Do the corresponding golden snapshots in the snapshot files validate this new --stack= format?
  • What drives the format change to include the equals sign rather than a space?

Also applies to: 46-46

pkg/flags/standard_parser.go (1)

42-49: LGTM!

Clean delegation to the underlying parser's registry. This enables external callers to wire up completion functions after parser creation without import cycles.

pkg/flags/registry.go (4)

81-98: LGTM!

Good approach to avoid import cycles. The silent return on missing flag aligns with Cobra's completion registration pattern.

One minor note: Line 96 reassigns the pointer back to the map, which is technically redundant since stringFlag is already a pointer and modifications apply to the stored value. Harmless, but could be simplified if desired.


122-131: LGTM!

Helpful comment clarifying where completion wiring happens.


189-196: Good documentation on the OpenTofu-specific flag.

The description correctly notes this is an OpenTofu feature. Per existing learnings, this aligns with the approach of documenting requirements rather than gating on command names.


255-319: LGTM!

Centralizing affected-detection flags in a dedicated registry function is a solid pattern. Keeps flag definitions DRY across commands that support --affected mode.

website/blog/2025-11-26-terraform-command-registry-pattern.mdx (1)

1-10: Well-structured blog post.

Follows the required format with frontmatter, truncate marker, and appropriate tags. Good balance of user-facing benefits and technical details.

pkg/flags/standard.go (2)

77-84: LGTM!

Clean accessor with proper perf tracking.


329-352: Solid approach for custom completion propagation.

The recursive registration handles Cobra's limitation of not propagating completions to children. Worth noting this runs at registration time, so child commands must already exist. Given Atmos's init() pattern, this should work correctly.

pkg/flags/types.go (6)

36-41: LGTM!

Clean interface extension. Comment clearly explains the purpose of custom completions.


43-54: LGTM!

CompletionFunc field cleanly extends StringFlag for dynamic completion support.


113-118: LGTM!

Simple accessor with perf tracking.


178-183: LGTM!

Correct that bool flags don't need custom completion - Cobra handles true/false implicitly.


244-249: LGTM!


317-322: LGTM!

Reasonable default. If slice flags need completion support later, the pattern is established.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
cmd/terraform/utils.go (1)

25-36: Fix double-dash splitting in runHooks (lost tail args / potential slice bug).

Right now finalArgs is truncated before you slice out argsAfterDoubleDash, so anything after -- is never captured and lo.Slice(finalArgs, doubleDashIndex+1, len(finalArgs)) can index past the end of the (already-shortened) slice.

A safer pattern is to keep an originalArgs copy, compute head/tail from that, then assign finalArgs from the head:

-func runHooks(event h.HookEvent, cmd_ *cobra.Command, args []string) error {
-	// Process args (split on --) and get config
-	var argsAfterDoubleDash []string
-	finalArgs := append([]string{cmd_.Name()}, args...)
-
-	doubleDashIndex := lo.IndexOf(finalArgs, "--")
-	if doubleDashIndex > 0 {
-		finalArgs = lo.Slice(finalArgs, 0, doubleDashIndex)
-		argsAfterDoubleDash = lo.Slice(finalArgs, doubleDashIndex+1, len(finalArgs))
-	}
-
-	info, err := e.ProcessCommandLineArgs("terraform", cmd_, finalArgs, argsAfterDoubleDash)
+func runHooks(event h.HookEvent, cmd_ *cobra.Command, args []string) error {
+	// Process args (split on --) and get config.
+	var argsAfterDoubleDash []string
+	originalArgs := append([]string{cmd_.Name()}, args...)
+	finalArgs := originalArgs
+
+	doubleDashIndex := lo.IndexOf(originalArgs, "--")
+	if doubleDashIndex >= 0 {
+		argsAfterDoubleDash = lo.Slice(originalArgs, doubleDashIndex+1, len(originalArgs))
+		finalArgs = lo.Slice(originalArgs, 0, doubleDashIndex)
+	}
+
+	info, err := e.ProcessCommandLineArgs(cfg.TerraformComponentType, cmd_, finalArgs, argsAfterDoubleDash)

This keeps the semantics consistent with the rest of the CLI parsing and avoids panics when -- appears early in the arg list.

🧹 Nitpick comments (5)
tests/snapshots/TestCLICommands_atmos_terraform_--help.stdout.golden (1)

62-107: Flags section reads well; tiny optional nit for --query

The new/updated flags (--append-user-agent, --clone-target-ref, --from-plan, --init-pass-vars, --process-functions, --process-templates, --skip, --upload-status, etc.) are described clearly and match the intended features, including calling out --init-pass-vars as an OpenTofu feature instead of gating it in code, which aligns with the existing pattern. Based on learnings, this is the right approach.

One small wording nit you might consider (totally optional, especially since this is a snapshot of actual CLI output):

  • Line 87: Execute atmos terraform on components filtered by a YQ expression
    • There’s a double space, and it reads a bit truncated. Something like “Execute atmos terraform commands on components filtered by a YQ expression” would be a bit clearer if you ever touch the underlying help string and regenerate snapshots.

Given the prior guidance that snapshot typos can be intentional and are driven by real output, I’d treat this as a nice‑to‑have only.

internal/exec/cli_utils.go (1)

221-221: Consider simplifying the condition.

The info.SubCommand == "" check is redundant since info is initialized empty on line 209. At this point in execution, SubCommand will always be an empty string.

Apply this diff to simplify:

-	if len(inputArgsAndFlags) == 1 && !standaloneCommands[inputArgsAndFlags[0]] && info.SubCommand == "" {
+	if len(inputArgsAndFlags) == 1 && !standaloneCommands[inputArgsAndFlags[0]] {
internal/exec/terraform_clean_test.go (1)

38-46: Prefer t.Setenv over os.Unsetenv for test isolation.

Using os.Unsetenv doesn't restore the original value after the test. Per project conventions, use t.Setenv("") for automatic cleanup.

-	err := os.Unsetenv("ATMOS_CLI_CONFIG_PATH")
-	if err != nil {
-		t.Fatalf("Failed to unset 'ATMOS_CLI_CONFIG_PATH': %v", err)
-	}
-
-	err = os.Unsetenv("ATMOS_BASE_PATH")
-	if err != nil {
-		t.Fatalf("Failed to unset 'ATMOS_BASE_PATH': %v", err)
-	}
+	t.Setenv("ATMOS_CLI_CONFIG_PATH", "")
+	t.Setenv("ATMOS_BASE_PATH", "")

Based on learnings, tests should prefer t.Setenv for environment variable setup/teardown.

tests/cli_terraform_test.go (1)

29-32: Prefer t.Setenv for environment variable manipulation.

Per project conventions, use t.Setenv("") instead of os.Unsetenv for automatic cleanup after test completion.

-	err := os.Unsetenv("ATMOS_CLI_CONFIG_PATH")
-	assert.NoError(t, err, "Unset 'ATMOS_CLI_CONFIG_PATH' environment variable should execute without error")
-	err = os.Unsetenv("ATMOS_BASE_PATH")
-	assert.NoError(t, err, "Unset 'ATMOS_BASE_PATH' environment variable should execute without error")
+	t.Setenv("ATMOS_CLI_CONFIG_PATH", "")
+	t.Setenv("ATMOS_BASE_PATH", "")

Based on learnings, tests should prefer t.Setenv for environment variable setup/teardown.

cmd/terraform/utils.go (1)

313-430: Shell completion helpers are correct; consider future perf/error-wrapping polish.

Functionally these helpers do the right thing: they fall back to NoFileComp on errors and derive components/stacks from ExecuteDescribeStacks, which is nice for UX.

Two small follow-ups you might consider (not blocking):

  • listTerraformComponents, listStacksForComponent, and listAllStacks currently wrap errors with generic fmt.Errorf("error ...: %w", err). If we have matching sentinels in errors/ (e.g., for CLI config init or describe-stacks failures), using those would keep error typing consistent with the rest of the codebase.
  • Each completion call re-runs InitCliConfig + ExecuteDescribeStacks. For very large deployments, that could make tab completion feel sluggish. If this becomes an issue, a lightweight cache for the stacks map (scoped to the current process) would help, reusing the same data across multiple completion invocations.

Given how completion is used, I’d treat both as future optimization, not mandatory changes for this PR.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tests/snapshots/TestCLICommands_atmos_terraform_apply_help.stdout.golden (1)

34-35: Align --from-plan flag semantics between root terraform and apply

Here --from-plan looks like a boolean (“If set atmos will use the previously generated plan file”), but in the terraform root help snapshot it’s rendered as --from-plan string with a value. It’d be good to make the type and wording consistent across commands (either clearly a path/string everywhere, or clearly a boolean everywhere), so users aren’t guessing how to use it.

internal/exec/terraform_clean.go (1)

493-575: Potential cleanPath double‑join for component‑only cleans impacts TF_DATA_DIR handling.

With the new ExecuteClean:

  • When component != "" and stack == "", componentPath is already set to filepath.Join(atmosConfig.TerraformDirAbsolutePath, terraformComponent) (where terraformComponent is derived from info.Context.BaseComponent or component).
  • In HandleCleanSubCommand, the branch
cleanPath := componentPath
if info.ComponentFromArg != "" && info.StackFromArg == "" {
	if info.Context.BaseComponent == "" {
		return fmt.Errorf("could not find the component '%s'", info.ComponentFromArg)
	}
	cleanPath = filepath.Join(componentPath, info.Context.BaseComponent)
}

will then produce cleanPath like <terraform-dir>/<component>/<base-component>. For valid components where Context.BaseComponent matches the resolved component path, that effectively double‑joins the component.

This only shows up when TF_DATA_DIR is set:

tfDataDirFolders, err = CollectDirectoryObjects(cleanPath, []string{tfDataDir})
...
if len(tfDataDirFolders) > 0 {
	tfDataDirFolder := tfDataDirFolders[0]
	handleTFDataDir(tfDataDirFolder.FullPath, relativePath)
}

Because cleanPath points at the nested path, CollectDirectoryObjects will not find the actual TF_DATA_DIR under the real component root, so TF_DATA_DIR cleanup becomes a silent no‑op for component‑only cleans. Regular .terraform and terraform.tfstate.d cleanup is unaffected because those use CollectComponentsDirectoryObjects with TerraformDirAbsolutePath.

A small conditional tweak keeps the old behavior for callers that pass the terraform root, while avoiding the double‑join when ExecuteClean has already resolved a component path:

-	cleanPath := componentPath
-	if info.ComponentFromArg != "" && info.StackFromArg == "" {
-		if info.Context.BaseComponent == "" {
-			return fmt.Errorf("could not find the component '%s'", info.ComponentFromArg)
-		}
-		cleanPath = filepath.Join(componentPath, info.Context.BaseComponent)
-	}
+	cleanPath := componentPath
+	if info.ComponentFromArg != "" && info.StackFromArg == "" {
+		if info.Context.BaseComponent == "" {
+			return fmt.Errorf("could not find the component '%s'", info.ComponentFromArg)
+		}
+		// If the caller passed the Terraform root, append the resolved component.
+		// If the caller already passed a component path (ExecuteClean), avoid double‑joining.
+		if componentPath == atmosConfig.TerraformDirAbsolutePath {
+			cleanPath = filepath.Join(componentPath, info.Context.BaseComponent)
+		}
+	}

Also, inside the else branch starting at Line 532, FilterComponents is initialized and only populated under if info.ComponentFromArg != "", but that condition can never be true there (we are already in the else of if info.ComponentFromArg != ""). You can safely drop that inner if and just pass nil for FilterComponents to ExecuteDescribeStacks to reduce dead code.

♻️ Duplicate comments (2)
cmd/terraform/utils.go (1)

30-34: Critical: Fix double-dash slicing bug (previously flagged).

This bug has been flagged twice in previous reviews but remains unfixed. Line 32 truncates finalArgs before line 33 extracts argsAfterDoubleDash, causing the slice to read from the wrong array (the already-truncated one). This loses all arguments after -- and can panic on out-of-bounds access.

Apply the fix from previous review:

 	doubleDashIndex := lo.IndexOf(finalArgs, "--")
 	if doubleDashIndex > 0 {
+		argsAfterDoubleDash = lo.Slice(finalArgs, doubleDashIndex+1, len(finalArgs))
 		finalArgs = lo.Slice(finalArgs, 0, doubleDashIndex)
-		argsAfterDoubleDash = lo.Slice(finalArgs, doubleDashIndex+1, len(finalArgs))
 	}
tests/snapshots/TestCLICommands_atmos_terraform_--help.stdout.golden (1)

4-107: Same terraform root help surface as atmos terraform help

This snapshot matches the terraform root help reviewed in TestCLICommands_atmos_terraform_help.stdout.golden; the commands and flag descriptions (including --from-plan, --upload-status, compat flags) look consistent. See that file’s comments for the only small nit (double space in the --query description).

🧹 Nitpick comments (4)
internal/exec/cli_utils.go (1)

214-230: Single-argument handling for version/clean looks solid

The standaloneCommands map cleanly extends the previous clean special-case to include version, while preserving the existing behavior for other single-argument commands (still setting SubCommand + NeedHelp). Early returns keep the flow straightforward, and there’s no change to multi-arg handling.

If you ever touch this again, you could micro-simplify by computing arg := inputArgsAndFlags[0] once and reusing it in both conditionals, but that’s purely cosmetic.

tests/cli_terraform_test.go (1)

40-43: Deduplicate identical terraform clean invocations and fix comment punctuation.

Lines 41 and 43 both run terraform clean mycomponent -s nonprod --force, so the second call doesn’t add coverage and can be confusing given the slightly different comments. You can simplify and fix the comment style at the same time:

-	// Clean specific component with force (requires --stack after refactor)
-	runTerraformCleanCommand(t, "mycomponent", "-s", "nonprod", "--force")
-	// Clean component with stack with force (no TTY available in CI)
-	runTerraformCleanCommand(t, "mycomponent", "-s", "nonprod", "--force")
+	// Clean specific component with stack and force (no TTY available in CI).
+	runTerraformCleanCommand(t, "mycomponent", "-s", "nonprod", "--force")

This keeps a single clear scenario and matches the “comments must end with a period.” guideline.

tests/snapshots/TestCLICommands_atmos_terraform_help.stdout.golden (1)

87-88: Nit: double space in --query description

Execute atmos terraform on components... has a double space before on. If you care about polish, consider tightening the source help string so this snapshot reflows as terraform on.

internal/exec/terraform_clean_test.go (1)

38-45: Optional: use t.Setenv for ATMOS env setup/teardown.

You can simplify the ATMOS env handling and avoid manual unset error checks by using test‑scoped env overrides:

-	err := os.Unsetenv("ATMOS_CLI_CONFIG_PATH")
-	if err != nil {
-		t.Fatalf("Failed to unset 'ATMOS_CLI_CONFIG_PATH': %v", err)
-	}
-
-	err = os.Unsetenv("ATMOS_BASE_PATH")
-	if err != nil {
-		t.Fatalf("Failed to unset 'ATMOS_BASE_PATH': %v", err)
-	}
+	t.Setenv("ATMOS_CLI_CONFIG_PATH", "")
+	t.Setenv("ATMOS_BASE_PATH", "")

This matches the current testing patterns in the repo and keeps tests isolated. Based on learnings, tests here are moving toward t.Setenv over direct os.Unsetenv.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (5)
internal/exec/terraform_generate_planfile.go (1)

39-77: The atmosConfig parameter doesn't control execution behavior.

This matches a previously flagged issue: ExecuteGeneratePlanfile accepts atmosConfig but constructs a fresh ConfigAndStacksInfo at lines 68-74 and delegates to ExecuteTerraformGeneratePlanfile, which initializes its own config via InitCliConfig(*info, true) at line 175. Your caller's atmosConfig is only used for perf tracking, then discarded.

Consider either:

  1. Plumbing atmosConfig into the core implementation so callers can supply pre-initialized configs, or
  2. Removing the parameter to clarify the API contract.
cmd/terraform/deploy.go (1)

32-41: Re‑check --from-plan flag type/semantics against TerraformFlags registry.

Here deploy defines --from-plan as a bool with its own env var, while the shared Terraform flag registry previously exposed from-plan as a string plan‑file path on the parent terraform command. If that registry entry still exists, you end up with the same flag name having different types/semantics between parent and subcommands, which is both confusing and error‑prone.

Might be worth either:

  • Consolidating on a single string --from-plan flag used across terraform commands, or
  • Renaming this bool (e.g. --use-from-plan) if it really is a separate toggle.
cmd/terraform/utils.go (1)

197-239: Guard against nil auth manager before calling GetDefaultIdentity.

CreateAndAuthenticateManager can return (nil, nil) when auth is globally disabled; in that case authManager.GetDefaultIdentity(true) will panic. That can happen even when the user explicitly passes --identity but auth is turned off.

A simple guard right after the manager is created would make this robust:

 	authManager, err := auth.CreateAndAuthenticateManager(
 		cfg.IdentityFlagSelectValue,
 		&atmosConfig.Auth,
 		cfg.IdentityFlagSelectValue,
 	)
 	if err != nil {
 		errUtils.CheckErrorPrintAndExit(fmt.Errorf("%w: %w", errUtils.ErrFailedToInitializeAuthManager, err), "", "")
 	}
+
+	if authManager == nil {
+		// Auth is disabled but user explicitly requested identity selection.
+		errUtils.CheckErrorPrintAndExit(
+			fmt.Errorf("%w: authentication is disabled", errUtils.ErrNoIdentitiesAvailable),
+			"",
+			"",
+		)
+	}
cmd/terraform/apply.go (1)

36-43: Resolve --from-plan bool vs string mismatch across Terraform commands.

Apply is also defining --from-plan as a bool plus its own env var. If the shared Terraform flag registry still defines from-plan as a string (plan file path) on the parent terraform command, you end up with the same flag name behaving differently depending on context, which is pretty confusing.

Worth considering:

  • Use a single string --from-plan flag everywhere (and treat “set but empty” as “use default plan file”), or
  • Rename this toggle (e.g. --use-from-plan) and reserve --from-plan for the path‑style flag.
internal/exec/terraform_clean.go (1)

532-548: Remove dead code: ComponentFromArg check inside else block.

Lines 535-538 check if info.ComponentFromArg != "" inside an else block (line 532) that only executes when info.ComponentFromArg == "". This condition can never be true, making it dead code.

Apply this diff to remove the dead code:

 	} else {
 		log.Debug("Clean: No component from arg, calling ExecuteDescribeStacks", "StackFromArg", info.StackFromArg)
 		// When cleaning all components, we need to call ExecuteDescribeStacks
-		var FilterComponents []string
-		if info.ComponentFromArg != "" {
-			FilterComponents = append(FilterComponents, info.ComponentFromArg)
-		}
 		stacksMap, err := ExecuteDescribeStacks(
 			atmosConfig,
 			info.StackFromArg,
-			FilterComponents,
+			nil,
 			nil, nil, false, false, false, false, nil, nil)
🧹 Nitpick comments (6)
internal/exec/terraform_generate_planfile.go (1)

91-91: Update perf tracking name to match the renamed function.

The function was renamed to ExecuteTerraformGeneratePlanfileOld, but the perf tracker still references the old name.

-	defer perf.Track(nil, "exec.ExecuteTerraformGeneratePlanfileCmd")()
+	defer perf.Track(nil, "exec.ExecuteTerraformGeneratePlanfileOld")()
internal/exec/terraform_generate_planfile_test.go (1)

75-177: Consider adding test coverage for the new ExecuteGeneratePlanfile entry point.

TestExecuteTerraformGeneratePlanfile tests the core implementation directly, but the new public wrapper ExecuteGeneratePlanfile (lines 39-77 in main file) lacks dedicated tests. While the core logic is covered, testing the new API surface would verify parameter mapping and the call path.

Example test structure:

func TestExecuteGeneratePlanfile(t *testing.T) {
	tests.RequireTerraform(t)
	stacksPath := "../../tests/fixtures/scenarios/terraform-generate-planfile"
	componentPath := filepath.Join(stacksPath, "..", "..", "components", "terraform", "mock")
	component := "component-1"
	stack := "nonprod"

	t.Setenv("ATMOS_CLI_CONFIG_PATH", stacksPath)
	t.Setenv("ATMOS_BASE_PATH", stacksPath)

	// Initialize atmosConfig (even though it won't affect execution)
	info := schema.ConfigAndStacksInfo{}
	atmosConfig, err := cfg.InitCliConfig(info, true)
	require.NoError(t, err)

	err = ExecuteGeneratePlanfile(
		component,
		stack,
		"",
		"json",
		true,
		true,
		nil,
		&atmosConfig,
	)
	assert.NoError(t, err)

	// Verify planfile was generated
	filePath := fmt.Sprintf("%s/%s-%s.planfile.json", componentPath, stack, component)
	_, statErr := os.Stat(filePath)
	assert.NoError(t, statErr)
}
internal/exec/terraform_shell.go (1)

18-27: Align perf/log labels with function name for easier tracing.

You’re tracking and logging this as "exec.ExecuteShell" / "ExecuteShell called" even though the function is ExecuteTerraformShell. Renaming these strings to match the function would make perf traces and logs much easier to search and correlate.

For example:

-	defer perf.Track(atmosConfig, "exec.ExecuteShell")()
+	defer perf.Track(atmosConfig, "exec.ExecuteTerraformShell")()

-	log.Debug("ExecuteShell called",
+	log.Debug("ExecuteTerraformShell called",
cmd/terraform/shell.go (1)

57-63: Avoid redundant stack processing in shell path.

Here you call InitCliConfig with processStacks=true but pass an empty ConfigAndStacksInfo; ExecuteTerraformShell then does its own ProcessStacks based on component and stack. You can likely set processStacks to false here (only auth/log config is needed) to avoid duplicate stack processing and keep this path aligned with other helpers that just need config.

For example:

-		atmosConfig, err := cfg.InitCliConfig(schema.ConfigAndStacksInfo{}, true)
+		atmosConfig, err := cfg.InitCliConfig(schema.ConfigAndStacksInfo{}, false)
internal/exec/terraform_clean_test.go (1)

3-10: Reorder imports to follow Atmos convention (stdlib → third‑party → Atmos).

Current import block has Atmos packages before testify. To match the repo’s standard:

 import (
 	"os"
 	"testing"
 
-	cfg "github.com/cloudposse/atmos/pkg/config"
-	"github.com/cloudposse/atmos/pkg/schema"
-	"github.com/stretchr/testify/require"
+	"github.com/stretchr/testify/require"
+
+	cfg "github.com/cloudposse/atmos/pkg/config"
+	"github.com/cloudposse/atmos/pkg/schema"
 )

This keeps goimports happy and aligns with the documented grouping.

cmd/terraform/clean.go (1)

3-11: Import organization: Add blank lines between import groups.

Per coding guidelines, imports should be organized in three groups separated by blank lines: Go stdlib, 3rd-party (excluding cloudposse/atmos), and Atmos packages. Currently missing the separators.

Apply this diff:

 import (
 	"github.com/spf13/cobra"
 	"github.com/spf13/viper"
+
 	e "github.com/cloudposse/atmos/internal/exec"
 	cfg "github.com/cloudposse/atmos/pkg/config"
 	"github.com/cloudposse/atmos/pkg/flags"
 	"github.com/cloudposse/atmos/pkg/schema"
 )

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
cmd/terraform/utils.go (1)

204-247: Guard against nil auth manager.

CreateAndAuthenticateManager can return (nil, nil) when authentication is globally disabled, which would cause a panic at line 233 when calling authManager.GetDefaultIdentity(true). The existing check at lines 214-218 only validates configuration presence but doesn't prevent a nil manager.

Add a nil check immediately after line 229:

 	authManager, err := auth.CreateAndAuthenticateManager(
 		cfg.IdentityFlagSelectValue,
 		&atmosConfig.Auth,
 		cfg.IdentityFlagSelectValue,
 	)
 	if err != nil {
 		errUtils.CheckErrorPrintAndExit(fmt.Errorf("%w: %w", errUtils.ErrFailedToInitializeAuthManager, err), "", "")
 	}
 
+	if authManager == nil {
+		// Auth is disabled but user explicitly requested identity selection.
+		errUtils.CheckErrorPrintAndExit(
+			fmt.Errorf("%w: authentication is disabled", errUtils.ErrNoIdentitiesAvailable),
+			"",
+			"",
+		)
+	}
+
 	// Get default identity with forced interactive selection.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d24015d and d8cf3a9.

📒 Files selected for processing (2)
  • cmd/terraform/utils.go (1 hunks)
  • pkg/flags/flag_parser.go (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: Use functional options pattern to avoid functions with many parameters. Define Option functions that modify a Config struct and pass variadic options to New functions.
Use context.Context for cancellation signals, deadlines/timeouts, and request-scoped values (trace IDs). Context should be first parameter in functions that accept it. DO NOT use context for configuration, dependencies, or avoiding proper function parameters.
All comments must end with periods. This is enforced by the godot linter.
NEVER delete existing comments without a very strong reason. Preserve helpful comments, update them to match code changes, refactor for clarity, and add context when modifying code. Only remove factually incorrect, duplicated, or outdated comments.
Organize imports in three groups separated by blank lines (Go stdlib, 3rd-party excluding cloudposse/atmos, Atmos packages), sorted alphabetically. Maintain aliases: cfg, log, u, errUtils.
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig parameter.
All errors MUST be wrapped using static errors defined in errors/errors.go. Use errors.Join for combining multiple errors, fmt.Errorf with %w for adding string context, error builder for complex errors, and errors.Is() for error checking. NEVER use dynamic errors directly.
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation. Never create manual mocks.
Use viper.BindEnv with ATMOS_ prefix for environment variables.
Use colors from pkg/ui/theme/colors.go for theme consistency.
Ensure Linux/macOS/Windows compatibility. Use SDKs over binaries. Use filepath.Join(), not hardcoded path separators.
Small focused files (<600 lines). One cmd/impl per file. Co-locate tests. Never use //revive:disable:file-length-limit.

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider us...

Files:

  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
cmd/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

cmd/**/*.go: Use unified flag parsing infrastructure in pkg/flags/. Commands MUST use flags.NewStandardParser() for command-specific flags. NEVER call viper.BindEnv() or viper.BindPFlag() directly outside pkg/flags/ (Forbidigo enforces this).
Telemetry is auto-enabled via RootCmd.ExecuteC(). Non-standard paths use telemetry.CaptureCmd(). Never capture user data.

cmd/**/*.go: Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under cmd/ directory
Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands

Files:

  • cmd/terraform/utils.go
🧠 Learnings (36)
📓 Common learnings
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under `cmd/` directory
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:233-235
Timestamp: 2024-10-31T19:25:41.298Z
Learning: When specifying color values in functions like `confirmDeleteTerraformLocal` in `internal/exec/terraform_clean.go`, avoid hardcoding color values. Instead, use predefined color constants or allow customization through configuration settings to improve accessibility and user experience across different terminals and themes.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.
📚 Learning: 2025-10-10T23:51:36.597Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-06-23T02:14:30.937Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: cmd/terraform.go:111-117
Timestamp: 2025-06-23T02:14:30.937Z
Learning: In cmd/terraform.go, flags for the DescribeAffected function are added dynamically at runtime when info.Affected is true. This is intentional to avoid exposing internal flags like "file", "format", "verbose", "include-spacelift-admin-stacks", "include-settings", and "upload" in the terraform command interface, while still providing them for the shared DescribeAffected function used by both `atmos describe affected` and `atmos terraform apply --affected`.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-01-09T22:37:01.004Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.

Applied to files:

  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
📚 Learning: 2025-10-07T00:25:16.333Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.

Applied to files:

  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to **/*.go : Organize imports in three groups separated by blank lines (Go stdlib, 3rd-party excluding cloudposse/atmos, Atmos packages), sorted alphabetically. Maintain aliases: cfg, log, u, errUtils.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2024-10-28T01:51:30.811Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:329-332
Timestamp: 2024-10-28T01:51:30.811Z
Learning: In the Atmos Go code, when deleting directories or handling file paths (e.g., in `terraform_clean.go`), always resolve the absolute path using `filepath.Abs` and use the logger `u.LogWarning` for logging messages instead of using `fmt.Printf`.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2024-10-31T19:25:41.298Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:233-235
Timestamp: 2024-10-31T19:25:41.298Z
Learning: When specifying color values in functions like `confirmDeleteTerraformLocal` in `internal/exec/terraform_clean.go`, avoid hardcoding color values. Instead, use predefined color constants or allow customization through configuration settings to improve accessibility and user experience across different terminals and themes.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2024-12-07T16:16:13.038Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.

Applied to files:

  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
📚 Learning: 2025-09-05T14:57:37.360Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 1448
File: cmd/ansible.go:26-28
Timestamp: 2025-09-05T14:57:37.360Z
Learning: The Atmos codebase uses a consistent pattern for commands that delegate to external tools: `PersistentFlags().Bool("", false, doubleDashHint)` where doubleDashHint provides help text about using double dashes to separate Atmos options from native command arguments. This pattern is used across terraform, packer, helmfile, atlantis, aws, and ansible commands.

Applied to files:

  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
📚 Learning: 2025-01-07T20:38:09.618Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 896
File: cmd/editor_config.go:37-40
Timestamp: 2025-01-07T20:38:09.618Z
Learning: Error handling suggestion for `cmd.Help()` in `cmd/editor_config.go` was deferred as the code is planned for future modifications.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-09-30T19:03:50.738Z
Learnt from: Cerebrovinny
Repo: cloudposse/atmos PR: 1560
File: pkg/utils/string_utils.go:43-64
Timestamp: 2025-09-30T19:03:50.738Z
Learning: In the Atmos codebase, YAML tags like !terraform.output rely on positional arguments, so the SplitStringByDelimiter function in pkg/utils/string_utils.go must preserve empty strings (even after trimming quotes) to maintain the correct number of positional arguments. Filtering out empty values after trimming would collapse the array and break these function calls.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2024-12-07T16:19:01.683Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-05-22T15:42:10.906Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1261
File: internal/exec/utils.go:639-640
Timestamp: 2025-05-22T15:42:10.906Z
Learning: In the Atmos codebase, when appending slices with `args := append(configAndStacksInfo.CliArgs, configAndStacksInfo.AdditionalArgsAndFlags...)`, it's intentional that the result is not stored back in the original slice. This pattern is used when the merged result serves a different purpose than the original slices, such as when creating a filtered version for component section assignments.

Applied to files:

  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
📚 Learning: 2025-10-03T18:02:08.535Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: internal/exec/terraform.go:269-272
Timestamp: 2025-10-03T18:02:08.535Z
Learning: In internal/exec/terraform.go, when auth.TerraformPreHook fails, the error is logged but execution continues. This is a deliberate design choice to allow Terraform commands to proceed even if authentication setup fails, rather than failing fast.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2024-11-30T22:07:08.610Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: internal/exec/yaml_func_terraform_output.go:35-40
Timestamp: 2024-11-30T22:07:08.610Z
Learning: In the Go function `processTagTerraformOutput` in `internal/exec/yaml_func_terraform_output.go`, parameters cannot contain spaces. The code splits the input by spaces, and if the parameters contain spaces, `len(parts) != 3` will fail and show an error to the user.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-09-25T01:02:48.697Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/manager.go:304-312
Timestamp: 2025-09-25T01:02:48.697Z
Learning: The auth manager in pkg/auth/manager.go should remain cloud-agnostic and not contain AWS-specific logic or references to specific cloud providers. Keep the manager generic and extensible.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-10-11T19:11:58.965Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:0-0
Timestamp: 2025-10-11T19:11:58.965Z
Learning: For terraform apply interactivity checks in Atmos (internal/exec/terraform.go), use stdin TTY detection (e.g., `IsTTYSupportForStdin()` or checking `os.Stdin`) to determine if user prompts are possible. This is distinct from stdout/stderr TTY checks used for output display (like TUI rendering). User input requires stdin to be a TTY; output display requires stdout/stderr to be a TTY.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-09-09T02:14:36.708Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1452
File: internal/auth/types/whoami.go:14-15
Timestamp: 2025-09-09T02:14:36.708Z
Learning: The WhoamiInfo struct in internal/auth/types/whoami.go requires the Credentials field to be JSON-serializable for keystore unmarshaling operations, despite security concerns about credential exposure.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-01-09T22:27:25.538Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/validate_stacks.go:20-23
Timestamp: 2025-01-09T22:27:25.538Z
Learning: The validate commands in Atmos can have different help handling implementations. Specifically, validate_component.go and validate_stacks.go are designed to handle help requests differently, with validate_stacks.go including positional argument checks while validate_component.go does not.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions

Applied to files:

  • cmd/terraform/utils.go
  • pkg/flags/flag_parser.go
📚 Learning: 2025-02-09T14:38:53.443Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 992
File: cmd/cmd_utils.go:0-0
Timestamp: 2025-02-09T14:38:53.443Z
Learning: Error handling for RegisterFlagCompletionFunc in AddStackCompletion is not required as the errors are non-critical for tab completion functionality.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to cmd/**/*.go : Use unified flag parsing infrastructure in pkg/flags/. Commands MUST use flags.NewStandardParser() for command-specific flags. NEVER call viper.BindEnv() or viper.BindPFlag() directly outside pkg/flags/ (Forbidigo enforces this).

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2025-11-10T03:03:31.505Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-11-10T03:03:31.505Z
Learning: In the Atmos codebase, commands using the `StandardParser` flag pattern (from pkg/flags) do NOT need explicit `viper.BindPFlag()` calls in their code. The StandardParser encapsulates flag binding internally: flags are registered via `parser.RegisterFlags(cmd)` in init(), and bound via `parser.BindFlagsToViper(cmd, v)` in RunE, which internally calls viper.BindPFlag for each flag. This pattern is used throughout Atmos (e.g., cmd/toolchain/get.go, cmd/toolchain/info.go, cmd/toolchain/install.go, cmd/toolchain/path.go). Do not flag missing viper.BindPFlag calls when StandardParser is used.

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Use Viper for managing configuration, environment variables, and flags in CLI commands

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2025-02-18T13:18:53.146Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-18T13:18:53.146Z
Learning: Error checking is not required for cobra.Command.RegisterFlagCompletionFunc calls as these are static configurations done at init time.

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under `cmd/` directory

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2025-02-07T19:21:38.028Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 992
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-07T19:21:38.028Z
Learning: The cobra.Command.RegisterFlagCompletionFunc method (as of cobra v1.8.1) never returns an error. It only initializes an internal map and stores the completion function, always returning nil. Error handling for this method call is unnecessary.

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to **/*.go : All errors MUST be wrapped using static errors defined in errors/errors.go. Use errors.Join for combining multiple errors, fmt.Errorf with %w for adding string context, error builder for complex errors, and errors.Is() for error checking. NEVER use dynamic errors directly.

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2025-02-03T06:00:11.419Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/describe_config.go:20-20
Timestamp: 2025-02-03T06:00:11.419Z
Learning: Commands should use `PrintErrorMarkdownAndExit` with empty title and suggestion (`"", err, ""`) for general error handling. Specific titles like "Invalid Usage" or "File Not Found" should only be used for validation or specific error scenarios.

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2025-01-30T19:30:59.120Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/workflow.go:74-74
Timestamp: 2025-01-30T19:30:59.120Z
Learning: Error handling for `cmd.Usage()` is not required in the Atmos CLI codebase, as confirmed by the maintainer.

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2025-01-18T15:15:41.645Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform.go:37-46
Timestamp: 2025-01-18T15:15:41.645Z
Learning: In the atmos CLI, error handling is intentionally structured to use LogErrorAndExit for consistent error display, avoiding Cobra's default error handling to prevent duplicate error messages.

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2024-12-11T18:40:12.808Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/helmfile.go:37-37
Timestamp: 2024-12-11T18:40:12.808Z
Learning: In the atmos project, `cliConfig` is initialized within the `cmd` package in `root.go` and can be used in other command files.

Applied to files:

  • pkg/flags/flag_parser.go
📚 Learning: 2024-12-05T22:33:54.807Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 820
File: cmd/list_stacks.go:55-56
Timestamp: 2024-12-05T22:33:54.807Z
Learning: In the atmos project, the `u.LogErrorAndExit` function logs the error and exits the command execution appropriately within flag completion functions.

Applied to files:

  • pkg/flags/flag_parser.go
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
🔇 Additional comments (10)
pkg/flags/flag_parser.go (3)

4-4: LGTM!

The standard library errors import supports the idiomatic errors.Is() check added for help flag handling.


322-324: LGTM!

Ignoring pflag.ErrHelp allows the --help flag to be processed by Cobra's help system in the normal execution flow, which is the correct approach. The use of errors.Is() for error checking follows the coding guidelines.


256-268: The comment in adjustForCobraParsing (lines 249-259) is misleading about how terraform commands work.

The comment states that terraform subcommands with UnknownFlags=true "preserve the -- separator in args," but this misrepresents the actual flow:

  1. What actually happens: Terraform commands call extractSubcommandArgs() which parses os.Args directly (bypassing Cobra entirely), capturing all arguments including the -- separator from the user's original command.

  2. Why the check is correct: The adjustForCobraParsing check correctly skips adjustment for UnknownFlags=true because:

    • These commands receive args sourced from os.Args[subcommand+1:] (preserving --)
    • Other commands receive args from Cobra's parsing (which may have removed -- and all unknown flags)
    • The adjustment logic only applies to Cobra-parsed args, not os.Args-sourced args
  3. Fix the comment: Rewrite lines 255-259 to clarify that UnknownFlags=true commands are handled differently because they extract args directly from os.Args rather than receiving Cobra-parsed args, and therefore don't need the adjustForCobraParsing logic.

The logic itself is sound, but the comment needs correction to accurately explain the distinction between arg sources (os.Args vs. Cobra parsing).

cmd/terraform/utils.go (7)

182-202: LGTM!

The flag validation logic correctly enforces mutual exclusivity between single-component and multi-component flags, with clear error messages.


252-259: LGTM!

Simple and effective early detection of the --heatmap flag before flag parsing.


261-285: LGTM!

Well-documented utility function with proper edge case handling for extracting terraform pass-through arguments.


287-320: LGTM!

Completion functions properly handle both local and inherited flags and gracefully degrade on errors.


324-338: LGTM!

Properly extends parent help with compatibility flags documentation.


340-371: LGTM!

Smart completion logic that filters stacks by component when available, improving user experience.


373-457: LGTM!

Consistent pattern across all list functions with proper error handling and sorting for predictable output.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

♻️ Duplicate comments (2)
cmd/terraform/version_cmd.go (1)

22-27: Skip component completions for terraform version.

RegisterTerraformCompletions unconditionally wires componentsArgCompletion as ValidArgsFunction, so terraform version ends up suggesting component names even though the command doesn’t take a component positional at all. That’s confusing and doesn’t match how the version path is handled in ProcessCommandLineArgs.

I’d either:

  • stop calling RegisterTerraformCompletions(versionCmd_) here, or
  • teach RegisterTerraformCompletions to skip component completion for non-component commands like version (and similarly for login/logout/metadata).

A minimal local fix:

func init() {
-	// Register completions for versionCmd_.
-	RegisterTerraformCompletions(versionCmd_)
-
-	// Attach to parent terraform command.
+	// Attach to parent terraform command.
 	terraformCmd.AddCommand(versionCmd_)
}
cmd/terraform/utils.go (1)

199-225: Guard against nil auth manager in interactive identity selection.

CreateAndAuthenticateManager is allowed to return (nil, nil) when auth is globally disabled; in that case authManager.GetDefaultIdentity(true) will panic. The earlier “no auth configured” check does not cover this case (e.g. providers/identities present but auth globally disabled).

Add a nil check immediately after manager creation and fail fast with a clear error instead of dereferencing:

 	authManager, err := auth.CreateAndAuthenticateManager(
 		cfg.IdentityFlagSelectValue,
 		&atmosConfig.Auth,
 		cfg.IdentityFlagSelectValue,
 	)
 	if err != nil {
 		errUtils.CheckErrorPrintAndExit(fmt.Errorf("%w: %w", errUtils.ErrFailedToInitializeAuthManager, err), "", "")
 	}
+
+	if authManager == nil {
+		// Auth is disabled but user explicitly requested identity selection.
+		errUtils.CheckErrorPrintAndExit(
+			fmt.Errorf("%w: authentication is disabled", errUtils.ErrNoIdentitiesAvailable),
+			"",
+			"",
+		)
+	}
 
 	// Get default identity with forced interactive selection.
 	// GetDefaultIdentity() handles TTY and CI detection via isInteractive().
 	selectedIdentity, err := authManager.GetDefaultIdentity(true)

Based on learnings, CreateAndAuthenticateManager may intentionally return a nil manager when auth is disabled.

🧹 Nitpick comments (8)
cmd/terraform/output.go (1)

7-19: Command structure and help wiring look solid; consider adding Examples.

The output command wiring and help text look consistent with the other terraform subcommands and the new registry pattern. To fully align with the CLI docs guidance, consider adding an Example field showing at least one typical invocation (e.g., atmos terraform output <component> -s <stack> and a --help usage) so users see concrete usage right in --help.

As per coding guidelines, help text should include examples.

cmd/internal/registry.go (1)

242-253: Add perf tracking to new exported registry helper.

GetCompatFlagsForCommand is a new public API used on the CLI hot path, but it doesn’t include the standard perf.Track call that other exported functions use.

For consistency with the repo’s profiling policy, consider:

-import (
-	"fmt"
-	"sync"
-
-	"github.com/spf13/cobra"
-	"github.com/spf13/pflag"
-
-	errUtils "github.com/cloudposse/atmos/errors"
-	"github.com/cloudposse/atmos/pkg/flags/compat"
-)
+import (
+	"fmt"
+	"sync"
+
+	"github.com/spf13/cobra"
+	"github.com/spf13/pflag"
+
+	errUtils "github.com/cloudposse/atmos/errors"
+	"github.com/cloudposse/atmos/pkg/flags/compat"
+	"github.com/cloudposse/atmos/pkg/perf"
+)
@@
 func GetCompatFlagsForCommand(providerName string) map[string]compat.CompatibilityFlag {
+	defer perf.Track(nil, "internal.GetCompatFlagsForCommand")()
+
 	provider, ok := GetProvider(providerName)
 	if !ok {
 		return nil
 	}
 	return provider.GetCompatibilityFlags()
 }

As per coding guidelines, exported functions are expected to wrap their body with defer perf.Track(... )().

cmd/terraform/destroy.go (1)

21-29: Comments missing trailing periods.

Per coding guidelines, all comments must end with periods (godot linter requirement).

 func init() {
-	// Set custom help to show terraform native flags.
+	// Set custom help to show terraform native flags.
 	setCustomHelp(destroyCmd, DestroyCompatFlagDescriptions())

-	// Register completions for destroy command.
+	// Register completions for destroy command.
 	RegisterTerraformCompletions(destroyCmd)

-	// Attach to parent terraform command.
+	// Attach to parent terraform command.
 	terraformCmd.AddCommand(destroyCmd)
 }

Actually, looking again—the comments already have periods. LGTM.

cmd/terraform/init.go (1)

24-26: Comment missing trailing period.

Line 25 is missing a period at the end, which will trigger the godot linter.

 func init() {
-	// Set custom help to show terraform native flags
+	// Set custom help to show terraform native flags.
 	setCustomHelp(initCmd, InitCompatFlagDescriptions())
cmd/terraform/plan_diff.go (2)

56-62: Use static errors from errors/errors.go.

Per coding guidelines, errors should be wrapped using static errors defined in errors/errors.go. These dynamic fmt.Errorf calls should use predefined error types.

Consider defining static errors in errors/errors.go:

var (
    ErrStackRequired = errors.New("stack is required (use --stack or -s)")
    ErrOrigPlanRequired = errors.New("original plan file is required (use --orig)")
)

Then use them here:

-		if stack == "" {
-			return fmt.Errorf("stack is required (use --stack or -s)")
-		}
-		if orig == "" {
-			return fmt.Errorf("original plan file is required (use --orig)")
-		}
+		if stack == "" {
+			return errors.ErrStackRequired
+		}
+		if orig == "" {
+			return errors.ErrOrigPlanRequired
+		}

100-103: Consider logging instead of panic for init() binding errors.

While panicking in init() is a common Go pattern for unrecoverable setup errors, the errUtils.CheckErrorPrintAndExit pattern used on line 108 is more user-friendly. Consider consistency here.

 	// Bind flags to Viper for environment variable support.
-	if err := planDiffParser.BindToViper(viper.GetViper()); err != nil {
-		panic(err)
-	}
+	if err := planDiffParser.BindToViper(viper.GetViper()); err != nil {
+		errUtils.CheckErrorPrintAndExit(err, "Error binding plan-diff flags to Viper", "")
+	}
cmd/terraform/apply.go (1)

35-42: Consider adding environment variable bindings for --affected and --all.

The --from-plan and --planfile flags have WithEnvVars bindings, but --affected and --all don't. For consistency and CI/CD flexibility, consider adding them.

 	applyParser = flags.NewStandardParser(
 		flags.WithBoolFlag("from-plan", "", false, "If set atmos will use the previously generated plan file"),
 		flags.WithStringFlag("planfile", "", "", "Set the plan file to use"),
 		flags.WithBoolFlag("affected", "", false, "Apply the affected components in dependency order"),
 		flags.WithBoolFlag("all", "", false, "Apply all components in all stacks"),
 		flags.WithEnvVars("from-plan", "ATMOS_TERRAFORM_APPLY_FROM_PLAN"),
 		flags.WithEnvVars("planfile", "ATMOS_TERRAFORM_APPLY_PLANFILE"),
+		flags.WithEnvVars("affected", "ATMOS_TERRAFORM_APPLY_AFFECTED"),
+		flags.WithEnvVars("all", "ATMOS_TERRAFORM_APPLY_ALL"),
 	)
cmd/terraform/compat_flags.go (1)

200-211: Consider adding newer terraform test flags to TestCompatFlags.

Current TestCompatFlags covers the core options (-filter, -json, -no-color, -test-directory, -var, -var-file, -verbose), but recent Terraform versions also expose additional test options like -cloud-run, -junit-xml, and -parallelism. (developer.hashicorp.com)

If AllTerraformCompatFlags is used to decide which args are pass‑through vs. Atmos flags, omitting these means atmos terraform test users can’t cleanly use the full upstream CLI.

If you intend to support the current terraform test surface, consider extending the map, for example:

 func TestCompatFlags() map[string]compat.CompatibilityFlag {
 	return map[string]compat.CompatibilityFlag{
-		"-filter":         {Behavior: compat.AppendToSeparated},
-		"-json":           {Behavior: compat.AppendToSeparated},
-		"-no-color":       {Behavior: compat.AppendToSeparated},
-		"-test-directory": {Behavior: compat.AppendToSeparated},
-		"-var":            {Behavior: compat.AppendToSeparated},
-		"-var-file":       {Behavior: compat.AppendToSeparated},
-		"-verbose":        {Behavior: compat.AppendToSeparated},
+		"-cloud-run":      {Behavior: compat.AppendToSeparated},
+		"-filter":         {Behavior: compat.AppendToSeparated},
+		"-json":           {Behavior: compat.AppendToSeparated},
+		"-junit-xml":      {Behavior: compat.AppendToSeparated},
+		"-no-color":       {Behavior: compat.AppendToSeparated},
+		"-parallelism":    {Behavior: compat.AppendToSeparated},
+		"-test-directory": {Behavior: compat.AppendToSeparated},
+		"-var":            {Behavior: compat.AppendToSeparated},
+		"-var-file":       {Behavior: compat.AppendToSeparated},
+		"-verbose":        {Behavior: compat.AppendToSeparated},
 	}
 }

(Adjust the exact behavior/coverage if you’re targeting a specific Terraform version.)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
cmd/terraform/compat_flags.go (1)

10-274: Previous review comments remain unaddressed.

Three issues from earlier reviews are still present:

  1. All exported functions (TerraformCompatFlags, PlanCompatFlags, etc.) are missing defer perf.Track(nil, "terraform.FuncName")() calls required by repo guidelines.

  2. GetCompatFlags() at line 196 incorrectly includes -test-directory, which is not a valid flag for terraform get (only -update and -no-color are supported).

  3. AllTerraformCompatFlags() at lines 238-242 has comment sentences not ending with periods, and line 272 is missing mergeFlags(ProvidersCompatFlags()) for future-proofing.

🧹 Nitpick comments (3)
cmd/terraform/output.go (1)

7-19: Add an Example section to the Cobra command help.

The Use, Short, and Long fields are solid, but there is no Example string. To align with the repo’s CLI docs pattern and make atmos terraform output --help more actionable, consider adding at least one usage example (mirroring the style used by other terraform subcommands in this PR).

As per coding guidelines, help text should include examples.

cmd/terraform/apply.go (1)

38-41: Consider adding environment variable bindings for --affected and --all flags.

The from-plan and planfile flags have corresponding ATMOS_TERRAFORM_APPLY_* env vars, but affected and all don't. If this is intentional (e.g., these flags should only be set explicitly), that's fine. Otherwise, consistency might be worth adding.

 		flags.WithBoolFlag("affected", "", false, "Apply the affected components in dependency order"),
 		flags.WithBoolFlag("all", "", false, "Apply all components in all stacks"),
 		flags.WithEnvVars("from-plan", "ATMOS_TERRAFORM_APPLY_FROM_PLAN"),
 		flags.WithEnvVars("planfile", "ATMOS_TERRAFORM_APPLY_PLANFILE"),
+		flags.WithEnvVars("affected", "ATMOS_TERRAFORM_APPLY_AFFECTED"),
+		flags.WithEnvVars("all", "ATMOS_TERRAFORM_APPLY_ALL"),
cmd/terraform/init.go (1)

8-18: Consider adding a concrete usage example to the help text.

To align with the CLI help-text guidelines, you might add a brief example section (e.g., atmos terraform init tenant/platform/whatever) so users immediately see the typical invocation pattern.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5068f0d and 7ae7339.

📒 Files selected for processing (25)
  • cmd/terraform/apply.go (1 hunks)
  • cmd/terraform/compat_flags.go (1 hunks)
  • cmd/terraform/compat_help.go (1 hunks)
  • cmd/terraform/console.go (1 hunks)
  • cmd/terraform/deploy.go (1 hunks)
  • cmd/terraform/destroy.go (1 hunks)
  • cmd/terraform/fmt.go (1 hunks)
  • cmd/terraform/force_unlock.go (1 hunks)
  • cmd/terraform/get.go (1 hunks)
  • cmd/terraform/graph.go (1 hunks)
  • cmd/terraform/import.go (1 hunks)
  • cmd/terraform/init.go (1 hunks)
  • cmd/terraform/output.go (1 hunks)
  • cmd/terraform/plan.go (1 hunks)
  • cmd/terraform/providers.go (1 hunks)
  • cmd/terraform/refresh.go (1 hunks)
  • cmd/terraform/show.go (1 hunks)
  • cmd/terraform/state.go (1 hunks)
  • cmd/terraform/taint.go (1 hunks)
  • cmd/terraform/test.go (1 hunks)
  • cmd/terraform/untaint.go (1 hunks)
  • cmd/terraform/utils.go (1 hunks)
  • cmd/terraform/validate.go (1 hunks)
  • cmd/terraform/workspace.go (1 hunks)
  • pkg/flags/compat/compatibility_flags.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (11)
  • cmd/terraform/console.go
  • cmd/terraform/providers.go
  • cmd/terraform/fmt.go
  • cmd/terraform/deploy.go
  • cmd/terraform/force_unlock.go
  • cmd/terraform/destroy.go
  • cmd/terraform/state.go
  • cmd/terraform/import.go
  • cmd/terraform/workspace.go
  • cmd/terraform/plan.go
  • cmd/terraform/compat_help.go
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: Use functional options pattern to avoid functions with many parameters. Define Option functions that modify a Config struct and pass variadic options to New functions.
Use context.Context for cancellation signals, deadlines/timeouts, and request-scoped values (trace IDs). Context should be first parameter in functions that accept it. DO NOT use context for configuration, dependencies, or avoiding proper function parameters.
All comments must end with periods. This is enforced by the godot linter.
NEVER delete existing comments without a very strong reason. Preserve helpful comments, update them to match code changes, refactor for clarity, and add context when modifying code. Only remove factually incorrect, duplicated, or outdated comments.
Organize imports in three groups separated by blank lines (Go stdlib, 3rd-party excluding cloudposse/atmos, Atmos packages), sorted alphabetically. Maintain aliases: cfg, log, u, errUtils.
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig parameter.
All errors MUST be wrapped using static errors defined in errors/errors.go. Use errors.Join for combining multiple errors, fmt.Errorf with %w for adding string context, error builder for complex errors, and errors.Is() for error checking. NEVER use dynamic errors directly.
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation. Never create manual mocks.
Use viper.BindEnv with ATMOS_ prefix for environment variables.
Use colors from pkg/ui/theme/colors.go for theme consistency.
Ensure Linux/macOS/Windows compatibility. Use SDKs over binaries. Use filepath.Join(), not hardcoded path separators.
Small focused files (<600 lines). One cmd/impl per file. Co-locate tests. Never use //revive:disable:file-length-limit.

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider us...

Files:

  • cmd/terraform/untaint.go
  • cmd/terraform/validate.go
  • pkg/flags/compat/compatibility_flags.go
  • cmd/terraform/test.go
  • cmd/terraform/taint.go
  • cmd/terraform/apply.go
  • cmd/terraform/graph.go
  • cmd/terraform/output.go
  • cmd/terraform/show.go
  • cmd/terraform/refresh.go
  • cmd/terraform/compat_flags.go
  • cmd/terraform/init.go
  • cmd/terraform/get.go
  • cmd/terraform/utils.go
cmd/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

cmd/**/*.go: Use unified flag parsing infrastructure in pkg/flags/. Commands MUST use flags.NewStandardParser() for command-specific flags. NEVER call viper.BindEnv() or viper.BindPFlag() directly outside pkg/flags/ (Forbidigo enforces this).
Telemetry is auto-enabled via RootCmd.ExecuteC(). Non-standard paths use telemetry.CaptureCmd(). Never capture user data.

cmd/**/*.go: Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under cmd/ directory
Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands

Files:

  • cmd/terraform/untaint.go
  • cmd/terraform/validate.go
  • cmd/terraform/test.go
  • cmd/terraform/taint.go
  • cmd/terraform/apply.go
  • cmd/terraform/graph.go
  • cmd/terraform/output.go
  • cmd/terraform/show.go
  • cmd/terraform/refresh.go
  • cmd/terraform/compat_flags.go
  • cmd/terraform/init.go
  • cmd/terraform/get.go
  • cmd/terraform/utils.go
🧠 Learnings (59)
📓 Common learnings
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: internal/exec/terraform_utils.go:40-213
Timestamp: 2024-12-03T05:18:49.169Z
Learning: In the context of the Atmos project, it's acceptable for functions like `execTerraformOutput` to remain as single functions if they perform a single purpose, such as retrieving Terraform outputs for a component in a stack, even if the function is lengthy.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.
📚 Learning: 2025-10-10T23:51:36.597Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.

Applied to files:

  • cmd/terraform/untaint.go
  • cmd/terraform/validate.go
  • cmd/terraform/test.go
  • cmd/terraform/taint.go
  • cmd/terraform/apply.go
  • cmd/terraform/graph.go
  • cmd/terraform/output.go
  • cmd/terraform/show.go
  • cmd/terraform/refresh.go
  • cmd/terraform/compat_flags.go
  • cmd/terraform/init.go
  • cmd/terraform/get.go
  • cmd/terraform/utils.go
📚 Learning: 2025-01-09T22:37:01.004Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.

Applied to files:

  • cmd/terraform/untaint.go
  • cmd/terraform/validate.go
  • cmd/terraform/test.go
  • cmd/terraform/taint.go
  • cmd/terraform/apply.go
  • cmd/terraform/graph.go
  • cmd/terraform/output.go
  • cmd/terraform/show.go
  • cmd/terraform/refresh.go
  • cmd/terraform/compat_flags.go
  • cmd/terraform/init.go
  • cmd/terraform/get.go
  • cmd/terraform/utils.go
📚 Learning: 2025-06-23T02:14:30.937Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: cmd/terraform.go:111-117
Timestamp: 2025-06-23T02:14:30.937Z
Learning: In cmd/terraform.go, flags for the DescribeAffected function are added dynamically at runtime when info.Affected is true. This is intentional to avoid exposing internal flags like "file", "format", "verbose", "include-spacelift-admin-stacks", "include-settings", and "upload" in the terraform command interface, while still providing them for the shared DescribeAffected function used by both `atmos describe affected` and `atmos terraform apply --affected`.

Applied to files:

  • cmd/terraform/untaint.go
  • cmd/terraform/validate.go
  • pkg/flags/compat/compatibility_flags.go
  • cmd/terraform/taint.go
  • cmd/terraform/apply.go
  • cmd/terraform/output.go
  • cmd/terraform/show.go
  • cmd/terraform/compat_flags.go
  • cmd/terraform/init.go
  • cmd/terraform/utils.go
📚 Learning: 2024-10-31T19:25:41.298Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:233-235
Timestamp: 2024-10-31T19:25:41.298Z
Learning: When specifying color values in functions like `confirmDeleteTerraformLocal` in `internal/exec/terraform_clean.go`, avoid hardcoding color values. Instead, use predefined color constants or allow customization through configuration settings to improve accessibility and user experience across different terminals and themes.

Applied to files:

  • cmd/terraform/untaint.go
  • cmd/terraform/test.go
  • cmd/terraform/taint.go
  • cmd/terraform/output.go
  • cmd/terraform/compat_flags.go
  • cmd/terraform/utils.go
📚 Learning: 2024-10-27T04:41:49.199Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:215-223
Timestamp: 2024-10-27T04:41:49.199Z
Learning: In `internal/exec/terraform_clean.go`, the function `determineCleanPath` is necessary and should not be removed.

Applied to files:

  • cmd/terraform/untaint.go
📚 Learning: 2025-10-07T00:25:16.333Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.

Applied to files:

  • cmd/terraform/untaint.go
  • cmd/terraform/validate.go
  • cmd/terraform/test.go
  • cmd/terraform/taint.go
  • cmd/terraform/apply.go
  • cmd/terraform/graph.go
  • cmd/terraform/output.go
  • cmd/terraform/show.go
  • cmd/terraform/refresh.go
  • cmd/terraform/compat_flags.go
  • cmd/terraform/init.go
  • cmd/terraform/get.go
  • cmd/terraform/utils.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions

Applied to files:

  • cmd/terraform/untaint.go
  • cmd/terraform/validate.go
  • cmd/terraform/test.go
  • cmd/terraform/taint.go
  • cmd/terraform/apply.go
  • cmd/terraform/graph.go
  • cmd/terraform/output.go
  • cmd/terraform/show.go
  • cmd/terraform/refresh.go
  • cmd/terraform/compat_flags.go
  • cmd/terraform/init.go
  • cmd/terraform/get.go
  • cmd/terraform/utils.go
📚 Learning: 2025-02-18T13:18:53.146Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-18T13:18:53.146Z
Learning: Error checking is not required for cobra.Command.RegisterFlagCompletionFunc calls as these are static configurations done at init time.

Applied to files:

  • cmd/terraform/untaint.go
  • cmd/terraform/validate.go
  • cmd/terraform/test.go
  • cmd/terraform/taint.go
  • cmd/terraform/refresh.go
  • cmd/terraform/utils.go
📚 Learning: 2024-12-07T16:19:01.683Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.

Applied to files:

  • cmd/terraform/untaint.go
  • cmd/terraform/validate.go
  • cmd/terraform/test.go
  • cmd/terraform/taint.go
  • cmd/terraform/output.go
  • cmd/terraform/show.go
  • cmd/terraform/compat_flags.go
  • cmd/terraform/utils.go
📚 Learning: 2025-01-09T22:27:25.538Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/validate_stacks.go:20-23
Timestamp: 2025-01-09T22:27:25.538Z
Learning: The validate commands in Atmos can have different help handling implementations. Specifically, validate_component.go and validate_stacks.go are designed to handle help requests differently, with validate_stacks.go including positional argument checks while validate_component.go does not.

Applied to files:

  • cmd/terraform/validate.go
  • cmd/terraform/utils.go
📚 Learning: 2025-09-29T02:20:11.636Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1540
File: internal/exec/validate_component.go:117-118
Timestamp: 2025-09-29T02:20:11.636Z
Learning: The ValidateComponent function in internal/exec/validate_component.go had its componentSection parameter type refined from `any` to `map[string]any` without adding new parameters. This is a type safety improvement, not a signature change requiring call site updates.

Applied to files:

  • cmd/terraform/validate.go
📚 Learning: 2025-04-11T22:06:46.999Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1147
File: internal/exec/validate_schema.go:42-57
Timestamp: 2025-04-11T22:06:46.999Z
Learning: The "ExecuteAtmosValidateSchemaCmd" function in internal/exec/validate_schema.go has been reviewed and confirmed to have acceptable cognitive complexity despite static analysis warnings. The function uses a clean structure with only three if statements for error handling and delegates complex operations to helper methods.

Applied to files:

  • cmd/terraform/validate.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under `cmd/` directory

Applied to files:

  • cmd/terraform/validate.go
  • cmd/terraform/test.go
  • cmd/terraform/taint.go
  • cmd/terraform/apply.go
  • cmd/terraform/graph.go
  • cmd/terraform/output.go
  • cmd/terraform/show.go
  • cmd/terraform/refresh.go
  • cmd/terraform/init.go
  • cmd/terraform/get.go
📚 Learning: 2024-11-16T17:30:52.893Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 786
File: internal/exec/shell_utils.go:159-162
Timestamp: 2024-11-16T17:30:52.893Z
Learning: For the `atmos terraform shell` command in `internal/exec/shell_utils.go`, input validation for the custom shell prompt is not required, as users will use this as a CLI tool and any issues will impact themselves.

Applied to files:

  • cmd/terraform/validate.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

Applied to files:

  • cmd/terraform/test.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to **/*.go : Small focused files (<600 lines). One cmd/impl per file. Co-locate tests. Never use //revive:disable:file-length-limit.

Applied to files:

  • cmd/terraform/test.go
  • cmd/terraform/graph.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: When adding new CLI commands: 1) Create cmd/[command]/ with CommandProvider interface, 2) Add blank import to cmd/root.go, 3) Implement in internal/exec/mycommand.go, 4) Add tests in cmd/mycommand/mycommand_test.go, 5) Create Docusaurus docs, 6) Build website.

Applied to files:

  • cmd/terraform/test.go
  • cmd/terraform/taint.go
  • cmd/terraform/show.go
  • cmd/terraform/init.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages

Applied to files:

  • cmd/terraform/test.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to internal/exec/template_funcs.go : New configs support Go templating with FuncMap() from internal/exec/template_funcs.go. Implement template functions in internal/exec/template_funcs.go, register them, add tests, and update documentation.

Applied to files:

  • cmd/terraform/test.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to **/*.go : All comments must end with periods. This is enforced by the godot linter.

Applied to files:

  • cmd/terraform/test.go
  • cmd/terraform/output.go
  • cmd/terraform/compat_flags.go
  • cmd/terraform/utils.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Document complex logic with inline comments in Go code

Applied to files:

  • cmd/terraform/test.go
  • cmd/terraform/output.go
  • cmd/terraform/compat_flags.go
  • cmd/terraform/utils.go
📚 Learning: 2025-01-07T20:38:09.618Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 896
File: cmd/editor_config.go:37-40
Timestamp: 2025-01-07T20:38:09.618Z
Learning: Error handling suggestion for `cmd.Help()` in `cmd/editor_config.go` was deferred as the code is planned for future modifications.

Applied to files:

  • cmd/terraform/test.go
  • cmd/terraform/output.go
  • cmd/terraform/utils.go
📚 Learning: 2025-02-19T05:50:35.853Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: tests/snapshots/TestCLICommands_atmos_terraform_apply_--help.stdout.golden:0-0
Timestamp: 2025-02-19T05:50:35.853Z
Learning: Backtick formatting should only be applied to flag descriptions in Go source files, not in golden test files (test snapshots) as they are meant to capture the raw command output.

Applied to files:

  • cmd/terraform/test.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to **/*.go : NEVER delete existing comments without a very strong reason. Preserve helpful comments, update them to match code changes, refactor for clarity, and add context when modifying code. Only remove factually incorrect, duplicated, or outdated comments.

Applied to files:

  • cmd/terraform/test.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-09-05T14:57:37.360Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 1448
File: cmd/ansible.go:26-28
Timestamp: 2025-09-05T14:57:37.360Z
Learning: The Atmos codebase uses a consistent pattern for commands that delegate to external tools: `PersistentFlags().Bool("", false, doubleDashHint)` where doubleDashHint provides help text about using double dashes to separate Atmos options from native command arguments. This pattern is used across terraform, packer, helmfile, atlantis, aws, and ansible commands.

Applied to files:

  • cmd/terraform/test.go
  • cmd/terraform/apply.go
  • cmd/terraform/output.go
  • cmd/terraform/compat_flags.go
  • cmd/terraform/utils.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to cmd/**/*_test.go : ALWAYS use cmd.NewTestKit(t) for cmd package tests to auto-clean RootCmd state (flags, args). Required for any test touching RootCmd.

Applied to files:

  • cmd/terraform/test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: The atmos codebase has a custom extension to *testing.T that provides a Chdir method, allowing test functions to call t.Chdir() to change working directories during tests. This is used consistently across test files in the codebase.

Applied to files:

  • cmd/terraform/test.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to cmd/**/*.go : Use unified flag parsing infrastructure in pkg/flags/. Commands MUST use flags.NewStandardParser() for command-specific flags. NEVER call viper.BindEnv() or viper.BindPFlag() directly outside pkg/flags/ (Forbidigo enforces this).

Applied to files:

  • cmd/terraform/apply.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-10T03:03:31.505Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-11-10T03:03:31.505Z
Learning: In the Atmos codebase, commands using the `StandardParser` flag pattern (from pkg/flags) do NOT need explicit `viper.BindPFlag()` calls in their code. The StandardParser encapsulates flag binding internally: flags are registered via `parser.RegisterFlags(cmd)` in init(), and bound via `parser.BindFlagsToViper(cmd, v)` in RunE, which internally calls viper.BindPFlag for each flag. This pattern is used throughout Atmos (e.g., cmd/toolchain/get.go, cmd/toolchain/info.go, cmd/toolchain/install.go, cmd/toolchain/path.go). Do not flag missing viper.BindPFlag calls when StandardParser is used.

Applied to files:

  • cmd/terraform/apply.go
  • cmd/terraform/utils.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Use Viper for managing configuration, environment variables, and flags in CLI commands

Applied to files:

  • cmd/terraform/apply.go
📚 Learning: 2025-10-11T19:11:58.965Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:0-0
Timestamp: 2025-10-11T19:11:58.965Z
Learning: For terraform apply interactivity checks in Atmos (internal/exec/terraform.go), use stdin TTY detection (e.g., `IsTTYSupportForStdin()` or checking `os.Stdin`) to determine if user prompts are possible. This is distinct from stdout/stderr TTY checks used for output display (like TUI rendering). User input requires stdin to be a TTY; output display requires stdout/stderr to be a TTY.

Applied to files:

  • cmd/terraform/apply.go
  • cmd/terraform/utils.go
📚 Learning: 2024-12-07T16:16:13.038Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.

Applied to files:

  • cmd/terraform/output.go
  • cmd/terraform/utils.go
📚 Learning: 2025-01-18T15:18:35.475Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/root.go:172-178
Timestamp: 2025-01-18T15:18:35.475Z
Learning: The `showUsageAndExit` function in `cmd/cmd_utils.go` provides user feedback by showing error messages, command suggestions, and valid subcommands before terminating the program with `os.Exit(1)`. It never returns to the caller, making error handling unnecessary for calls to this function.

Applied to files:

  • cmd/terraform/show.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Follow standard Go coding style: use `gofmt` and `goimports` to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to **/*.go : Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig parameter.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-09T19:06:58.470Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1752
File: pkg/profile/list/formatter_table.go:27-29
Timestamp: 2025-11-09T19:06:58.470Z
Learning: In the cloudposse/atmos repository, performance tracking with `defer perf.Track()` is enforced on all functions via linting, including high-frequency utility functions, formatters, and renderers. This is a repository-wide policy to maintain consistency and avoid making case-by-case judgment calls about which functions should have profiling.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2025-10-13T18:13:54.020Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1622
File: pkg/perf/perf.go:140-184
Timestamp: 2025-10-13T18:13:54.020Z
Learning: In pkg/perf/perf.go, the `trackWithSimpleStack` function intentionally skips ownership checks at call stack depth > 1 to avoid expensive `getGoroutineID()` calls on every nested function. This is a performance optimization for the common single-goroutine execution case (most Atmos commands), accepting the rare edge case of potential metric corruption if multi-goroutine execution occurs at depth > 1. The ~19× performance improvement justifies this trade-off.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • cmd/terraform/compat_flags.go
  • cmd/terraform/utils.go
📚 Learning: 2024-12-13T15:28:13.630Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/version.go:34-44
Timestamp: 2024-12-13T15:28:13.630Z
Learning: In `cmd/version.go`, when handling the `--check` flag in the `versionCmd`, avoid using `CheckForAtmosUpdateAndPrintMessage(cliConfig)` as it updates the cache timestamp, which may not be desired in this context.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2024-10-28T01:51:30.811Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:329-332
Timestamp: 2024-10-28T01:51:30.811Z
Learning: In the Atmos Go code, when deleting directories or handling file paths (e.g., in `terraform_clean.go`), always resolve the absolute path using `filepath.Abs` and use the logger `u.LogWarning` for logging messages instead of using `fmt.Printf`.

Applied to files:

  • cmd/terraform/compat_flags.go
  • cmd/terraform/utils.go
📚 Learning: 2024-11-02T15:35:09.958Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 759
File: internal/exec/terraform.go:366-368
Timestamp: 2024-11-02T15:35:09.958Z
Learning: In `internal/exec/terraform.go`, the workspace cleaning code under both the general execution path and within the `case "init":` block is intentionally duplicated because the code execution paths are different. The `.terraform/environment` file should be deleted before executing `terraform init` in both scenarios to ensure a clean state.

Applied to files:

  • cmd/terraform/init.go
📚 Learning: 2024-12-11T18:40:12.808Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/helmfile.go:37-37
Timestamp: 2024-12-11T18:40:12.808Z
Learning: In the atmos project, `cliConfig` is initialized within the `cmd` package in `root.go` and can be used in other command files.

Applied to files:

  • cmd/terraform/init.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to **/*.go : Organize imports in three groups separated by blank lines (Go stdlib, 3rd-party excluding cloudposse/atmos, Atmos packages), sorted alphabetically. Maintain aliases: cfg, log, u, errUtils.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-09-13T18:06:07.674Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/list.go:39-42
Timestamp: 2025-09-13T18:06:07.674Z
Learning: In the cloudposse/atmos repository, for UI messages in the toolchain package, use utils.PrintfMessageToTUI instead of log.Error or fmt.Fprintln(os.Stderr, ...). Import pkg/utils with alias "u" to follow the established pattern.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-05-22T15:42:10.906Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1261
File: internal/exec/utils.go:639-640
Timestamp: 2025-05-22T15:42:10.906Z
Learning: In the Atmos codebase, when appending slices with `args := append(configAndStacksInfo.CliArgs, configAndStacksInfo.AdditionalArgsAndFlags...)`, it's intentional that the result is not stored back in the original slice. This pattern is used when the merged result serves a different purpose than the original slices, such as when creating a filtered version for component section assignments.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-09-30T19:03:50.738Z
Learnt from: Cerebrovinny
Repo: cloudposse/atmos PR: 1560
File: pkg/utils/string_utils.go:43-64
Timestamp: 2025-09-30T19:03:50.738Z
Learning: In the Atmos codebase, YAML tags like !terraform.output rely on positional arguments, so the SplitStringByDelimiter function in pkg/utils/string_utils.go must preserve empty strings (even after trimming quotes) to maintain the correct number of positional arguments. Filtering out empty values after trimming would collapse the array and break these function calls.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-10-03T18:02:08.535Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: internal/exec/terraform.go:269-272
Timestamp: 2025-10-03T18:02:08.535Z
Learning: In internal/exec/terraform.go, when auth.TerraformPreHook fails, the error is logged but execution continues. This is a deliberate design choice to allow Terraform commands to proceed even if authentication setup fails, rather than failing fast.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2024-11-30T22:07:08.610Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: internal/exec/yaml_func_terraform_output.go:35-40
Timestamp: 2024-11-30T22:07:08.610Z
Learning: In the Go function `processTagTerraformOutput` in `internal/exec/yaml_func_terraform_output.go`, parameters cannot contain spaces. The code splits the input by spaces, and if the parameters contain spaces, `len(parts) != 3` will fail and show an error to the user.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-09-25T01:02:48.697Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/manager.go:304-312
Timestamp: 2025-09-25T01:02:48.697Z
Learning: The auth manager in pkg/auth/manager.go should remain cloud-agnostic and not contain AWS-specific logic or references to specific cloud providers. Keep the manager generic and extensible.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-09-09T02:14:36.708Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1452
File: internal/auth/types/whoami.go:14-15
Timestamp: 2025-09-09T02:14:36.708Z
Learning: The WhoamiInfo struct in internal/auth/types/whoami.go requires the Credentials field to be JSON-serializable for keystore unmarshaling operations, despite security concerns about credential exposure.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to **/*.go : All errors MUST be wrapped using static errors defined in errors/errors.go. Use errors.Join for combining multiple errors, fmt.Errorf with %w for adding string context, error builder for complex errors, and errors.Is() for error checking. NEVER use dynamic errors directly.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-04-04T02:03:23.676Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1185
File: internal/exec/yaml_func_store.go:26-26
Timestamp: 2025-04-04T02:03:23.676Z
Learning: The Atmos codebase currently uses `log.Fatal` for error handling in multiple places. The maintainers are aware this isn't an ideal pattern (should only be used in main() or init() functions) and plan to address it comprehensively in a separate PR. CodeRabbit should not flag these issues or push for immediate changes until that refactoring is complete.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using `fmt.Errorf("context: %w", err)`, and consider using custom error types for domain-specific errors

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-01-19T15:49:15.593Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 955
File: tests/snapshots/TestCLICommands_atmos_validate_editorconfig_--help.stdout.golden:0-0
Timestamp: 2025-01-19T15:49:15.593Z
Learning: In future commits, the help text for Atmos CLI commands should be limited to only show component and stack parameters for commands that actually use them. This applies to the example usage section in command help text.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2024-11-13T21:37:07.852Z
Learnt from: Cerebrovinny
Repo: cloudposse/atmos PR: 764
File: internal/exec/describe_stacks.go:289-295
Timestamp: 2024-11-13T21:37:07.852Z
Learning: In the `internal/exec/describe_stacks.go` file of the `atmos` project written in Go, avoid extracting the stack name handling logic into a helper function within the `ExecuteDescribeStacks` method, even if the logic appears duplicated.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-02-03T05:57:18.407Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/cmd_utils.go:121-148
Timestamp: 2025-02-03T05:57:18.407Z
Learning: The Atmos CLI should fail fast (exit) when encountering configuration errors, including command alias configuration issues, to prevent undefined behavior. Use LogErrorAndExit instead of returning errors in such cases.

Applied to files:

  • cmd/terraform/utils.go
📚 Learning: 2025-02-09T14:38:53.443Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 992
File: cmd/cmd_utils.go:0-0
Timestamp: 2025-02-09T14:38:53.443Z
Learning: Error handling for RegisterFlagCompletionFunc in AddStackCompletion is not required as the errors are non-critical for tab completion functionality.

Applied to files:

  • cmd/terraform/utils.go
🧬 Code graph analysis (9)
cmd/terraform/untaint.go (1)
cmd/terraform/completion.go (1)
  • RegisterTerraformCompletions (15-22)
cmd/terraform/test.go (1)
cmd/terraform/completion.go (1)
  • RegisterTerraformCompletions (15-22)
cmd/terraform/taint.go (1)
cmd/terraform/completion.go (1)
  • RegisterTerraformCompletions (15-22)
cmd/terraform/graph.go (1)
cmd/terraform/completion.go (1)
  • RegisterTerraformCompletions (15-22)
cmd/terraform/show.go (1)
cmd/terraform/completion.go (1)
  • RegisterTerraformCompletions (15-22)
cmd/terraform/refresh.go (1)
cmd/terraform/completion.go (1)
  • RegisterTerraformCompletions (15-22)
cmd/terraform/init.go (1)
cmd/terraform/completion.go (1)
  • RegisterTerraformCompletions (15-22)
cmd/terraform/get.go (1)
cmd/terraform/completion.go (1)
  • RegisterTerraformCompletions (15-22)
cmd/terraform/utils.go (8)
internal/exec/cli_utils.go (1)
  • ProcessCommandLineArgs (79-199)
errors/errors.go (9)
  • ErrInitializeCLIConfig (451-451)
  • ErrGetHooks (452-452)
  • ErrPlanHasDiff (83-83)
  • ErrInvalidTerraformComponentWithMultiComponentFlags (86-86)
  • ErrInvalidTerraformFlagsWithAffectedFlag (85-85)
  • ErrInvalidTerraformSingleComponentAndMultiComponentFlags (87-87)
  • ErrNoIdentitiesAvailable (524-524)
  • ErrFailedToInitializeAuthManager (511-511)
  • ErrDefaultIdentity (493-493)
pkg/flags/compat/separated.go (1)
  • GetSeparated (34-40)
pkg/config/const.go (1)
  • TerraformComponentType (57-57)
internal/exec/terraform.go (1)
  • ExecuteTerraform (34-643)
pkg/auth/manager_helpers.go (1)
  • CreateAndAuthenticateManager (180-222)
internal/exec/terraform_clean.go (1)
  • ErrUserAborted (38-38)
errors/exit_code.go (1)
  • ExitCodeSIGINT (12-12)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Summary
🔇 Additional comments (15)
pkg/flags/compat/compatibility_flags.go (1)

34-36: Clean addition of help metadata.

The Description field is a straightforward enhancement that enables richer help output while maintaining backward compatibility through Go's named field initialization pattern.

cmd/terraform/test.go (2)

22-22: Past review comment addressed.

The missing period on the comment has been fixed.


1-30: Clean implementation following established patterns.

The command structure follows the terraform subcommand registry pattern consistently. The delegation to terraformRun, custom help setup, and completion registration align with other terraform subcommands in the migration.

cmd/terraform/output.go (1)

21-29: Command registration and custom help/completions wiring look correct.

setCustomHelp(outputCmd), RegisterTerraformCompletions(outputCmd), and terraformCmd.AddCommand(outputCmd) follow the established terraform command‑registry pattern and should integrate cleanly with the shared help and completion infrastructure.

cmd/terraform/refresh.go (1)

1-30: LGTM!

Clean implementation following the established Terraform subcommand pattern. Command definition, help customization, completion wiring, and parent attachment are all properly configured.

cmd/terraform/validate.go (1)

1-30: LGTM!

Proper implementation of the validate subcommand following the standard pattern. All wiring is correctly in place.

cmd/terraform/utils.go (1)

1-410: LGTM!

The core Terraform command utilities are well-structured. The orchestration logic in terraformRun properly handles flag parsing, identity selection, affected mode, and routing between single-component and multi-component execution paths. All previously flagged issues have been addressed.

cmd/terraform/taint.go (1)

1-30: LGTM!

Standard Terraform subcommand implementation. All wiring is correct and follows the established pattern.

cmd/terraform/graph.go (1)

1-32: LGTM!

Clean implementation of the graph subcommand following the standard pattern. Documentation mentions DOT format output appropriately.

cmd/terraform/show.go (1)

1-30: LGTM!

Proper implementation of the show subcommand. All components are correctly wired.

cmd/terraform/get.go (1)

1-30: LGTM!

Standard implementation of the get subcommand. All wiring follows the established pattern correctly.

cmd/terraform/untaint.go (1)

1-30: LGTM!

Clean implementation following the established pattern for terraform subcommands. Documentation links cover both Terraform and OpenTofu, and the wiring through setCustomHelp, RegisterTerraformCompletions, and AddCommand is consistent with sibling commands.

cmd/terraform/apply.go (1)

1-60: LGTM!

Solid implementation. The StandardParser usage aligns with the unified flag parsing infrastructure, and the PostRunE hook integration for AfterTerraformApply is a nice touch. Import grouping and comment formatting are correct.

cmd/terraform/init.go (2)

7-22: Command wiring and delegation look solid.

The initCmd definition is clear: good Short/Long descriptions, useful Terraform/OpenTofu doc links, and RunE delegating to the shared terraformRun keeps behavior centralized and consistent with other terraform subcommands.


24-33: Nice use of shared help and completions.

Hooking setCustomHelp(initCmd) plus RegisterTerraformCompletions(initCmd) and then attaching to terraformCmd matches the existing terraform completion pattern and keeps component/identity completions available on init. This is exactly what we want for the per-subcommand registration. Based on learnings, this is consistent with RegisterTerraformCompletions usage.

osterman added a commit that referenced this pull request Nov 29, 2025
- Fix --from-plan flag type mismatch (StringFlag → BoolFlag in registry.go)
- Add perf.Track to all 22 exported functions in compat_flags.go
- Add mergeFlags(ProvidersCompatFlags()) call for future-proofing
- Return defensive copy in GetSeparated() to prevent data races
- Fix comment punctuation (godot linter compliance)
- Remove RegisterTerraformCompletions from non-component commands
  (version, login, logout, metadata)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
cmd/terraform/compat_flags.go (1)

224-233: -test-directory remains in GetCompatFlags() despite prior feedback.

This flag is not supported by terraform get. Per Terraform documentation, only -update and -no-color are valid flags for this command. The prior review flagged this, but the code still includes the erroneous entry.

 func GetCompatFlags() map[string]compat.CompatibilityFlag {
 	defer perf.Track(nil, "terraform.GetCompatFlags")()

 	return map[string]compat.CompatibilityFlag{
-		"-update":         {Behavior: compat.AppendToSeparated, Description: "Check for and download updated modules"},
-		"-no-color":       {Behavior: compat.AppendToSeparated, Description: "Disable color output"},
-		"-test-directory": {Behavior: compat.AppendToSeparated, Description: "Directory containing test files"},
+		"-update":   {Behavior: compat.AppendToSeparated, Description: "Check for and download updated modules"},
+		"-no-color": {Behavior: compat.AppendToSeparated, Description: "Disable color output"},
 	}
 }
🧹 Nitpick comments (2)
cmd/terraform/metadata.go (1)

7-26: Thin metadata subcommand wiring looks solid.

Command wiring is clean and consistent with the other terraform subcommands: help text is clear, RunE delegates through terraformRun (so it will pick up the registry-based execution), and you correctly skip completions since metadata doesn’t use components. Attaching via terraformCmd.AddCommand(metadataCmd) in init matches the established Cobra pattern. Based on learnings, inheriting parent flags without redefining them here is expected for terraform metadata.

If you want to go a bit further later, you could add a brief sentence in Long explaining that this proxies the underlying Terraform/OpenTofu metadata command via Atmos, but it’s not strictly necessary.

pkg/flags/compat/separated.go (1)

20-26: Optionally copy the input slice in SetSeparated to fully own state.

Right now SetSeparated stores the incoming slice directly:

globalSeparatedArgs = separatedArgs

If any caller accidentally mutates separatedArgs after calling SetSeparated, they’ll be mutating the shared global state. Not a bug for current usage, but you can harden the API by taking a defensive copy:

-	globalSeparatedArgs = separatedArgs
+	if separatedArgs == nil {
+		globalSeparatedArgs = nil
+		return
+	}
+	globalSeparatedArgs = append([]string{}, separatedArgs...)

This mirrors the defensive stance already taken in GetSeparated.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7ae7339 and ff919ec.

📒 Files selected for processing (8)
  • cmd/terraform/compat_flags.go (1 hunks)
  • cmd/terraform/login.go (1 hunks)
  • cmd/terraform/logout.go (1 hunks)
  • cmd/terraform/metadata.go (1 hunks)
  • cmd/terraform/version_cmd.go (1 hunks)
  • internal/exec/terraform_utils.go (1 hunks)
  • pkg/flags/compat/separated.go (1 hunks)
  • pkg/flags/registry.go (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • cmd/terraform/version_cmd.go
  • internal/exec/terraform_utils.go
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: Use functional options pattern to avoid functions with many parameters. Define Option functions that modify a Config struct and pass variadic options to New functions.
Use context.Context for cancellation signals, deadlines/timeouts, and request-scoped values (trace IDs). Context should be first parameter in functions that accept it. DO NOT use context for configuration, dependencies, or avoiding proper function parameters.
All comments must end with periods. This is enforced by the godot linter.
NEVER delete existing comments without a very strong reason. Preserve helpful comments, update them to match code changes, refactor for clarity, and add context when modifying code. Only remove factually incorrect, duplicated, or outdated comments.
Organize imports in three groups separated by blank lines (Go stdlib, 3rd-party excluding cloudposse/atmos, Atmos packages), sorted alphabetically. Maintain aliases: cfg, log, u, errUtils.
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig parameter.
All errors MUST be wrapped using static errors defined in errors/errors.go. Use errors.Join for combining multiple errors, fmt.Errorf with %w for adding string context, error builder for complex errors, and errors.Is() for error checking. NEVER use dynamic errors directly.
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation. Never create manual mocks.
Use viper.BindEnv with ATMOS_ prefix for environment variables.
Use colors from pkg/ui/theme/colors.go for theme consistency.
Ensure Linux/macOS/Windows compatibility. Use SDKs over binaries. Use filepath.Join(), not hardcoded path separators.
Small focused files (<600 lines). One cmd/impl per file. Co-locate tests. Never use //revive:disable:file-length-limit.

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider us...

Files:

  • pkg/flags/compat/separated.go
  • cmd/terraform/metadata.go
  • cmd/terraform/login.go
  • pkg/flags/registry.go
  • cmd/terraform/logout.go
  • cmd/terraform/compat_flags.go
cmd/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

cmd/**/*.go: Use unified flag parsing infrastructure in pkg/flags/. Commands MUST use flags.NewStandardParser() for command-specific flags. NEVER call viper.BindEnv() or viper.BindPFlag() directly outside pkg/flags/ (Forbidigo enforces this).
Telemetry is auto-enabled via RootCmd.ExecuteC(). Non-standard paths use telemetry.CaptureCmd(). Never capture user data.

cmd/**/*.go: Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under cmd/ directory
Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands

Files:

  • cmd/terraform/metadata.go
  • cmd/terraform/login.go
  • cmd/terraform/logout.go
  • cmd/terraform/compat_flags.go
🧠 Learnings (41)
📓 Common learnings
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: internal/exec/terraform_utils.go:40-213
Timestamp: 2024-12-03T05:18:49.169Z
Learning: In the context of the Atmos project, it's acceptable for functions like `execTerraformOutput` to remain as single functions if they perform a single purpose, such as retrieving Terraform outputs for a component in a stack, even if the function is lengthy.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Use registry pattern for extensibility and plugin-like architecture (Command Registry, Component Registry, Store Registry). New commands MUST use command registry pattern via CommandProvider interface.
📚 Learning: 2025-06-23T02:14:30.937Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: cmd/terraform.go:111-117
Timestamp: 2025-06-23T02:14:30.937Z
Learning: In cmd/terraform.go, flags for the DescribeAffected function are added dynamically at runtime when info.Affected is true. This is intentional to avoid exposing internal flags like "file", "format", "verbose", "include-spacelift-admin-stacks", "include-settings", and "upload" in the terraform command interface, while still providing them for the shared DescribeAffected function used by both `atmos describe affected` and `atmos terraform apply --affected`.

Applied to files:

  • pkg/flags/compat/separated.go
  • cmd/terraform/metadata.go
  • pkg/flags/registry.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-10-10T23:51:36.597Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.

Applied to files:

  • pkg/flags/compat/separated.go
  • cmd/terraform/metadata.go
  • cmd/terraform/login.go
  • pkg/flags/registry.go
  • cmd/terraform/logout.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults

Applied to files:

  • pkg/flags/compat/separated.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-01-09T22:37:01.004Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.

Applied to files:

  • pkg/flags/compat/separated.go
  • cmd/terraform/metadata.go
  • cmd/terraform/login.go
  • cmd/terraform/logout.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-05-22T15:42:10.906Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1261
File: internal/exec/utils.go:639-640
Timestamp: 2025-05-22T15:42:10.906Z
Learning: In the Atmos codebase, when appending slices with `args := append(configAndStacksInfo.CliArgs, configAndStacksInfo.AdditionalArgsAndFlags...)`, it's intentional that the result is not stored back in the original slice. This pattern is used when the merged result serves a different purpose than the original slices, such as when creating a filtered version for component section assignments.

Applied to files:

  • pkg/flags/compat/separated.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to cmd/**/*.go : Use unified flag parsing infrastructure in pkg/flags/. Commands MUST use flags.NewStandardParser() for command-specific flags. NEVER call viper.BindEnv() or viper.BindPFlag() directly outside pkg/flags/ (Forbidigo enforces this).

Applied to files:

  • pkg/flags/compat/separated.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2024-12-02T21:26:32.337Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: pkg/config/config.go:478-483
Timestamp: 2024-12-02T21:26:32.337Z
Learning: In the 'atmos' project, when reviewing Go code like `pkg/config/config.go`, avoid suggesting file size checks after downloading remote configs if such checks aren't implemented elsewhere in the codebase.

Applied to files:

  • pkg/flags/compat/separated.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • pkg/flags/compat/separated.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-04-04T02:03:23.676Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1185
File: internal/exec/yaml_func_store.go:26-26
Timestamp: 2025-04-04T02:03:23.676Z
Learning: The Atmos codebase currently uses `log.Fatal` for error handling in multiple places. The maintainers are aware this isn't an ideal pattern (should only be used in main() or init() functions) and plan to address it comprehensively in a separate PR. CodeRabbit should not flag these issues or push for immediate changes until that refactoring is complete.

Applied to files:

  • pkg/flags/compat/separated.go
📚 Learning: 2025-09-30T19:03:50.738Z
Learnt from: Cerebrovinny
Repo: cloudposse/atmos PR: 1560
File: pkg/utils/string_utils.go:43-64
Timestamp: 2025-09-30T19:03:50.738Z
Learning: In the Atmos codebase, YAML tags like !terraform.output rely on positional arguments, so the SplitStringByDelimiter function in pkg/utils/string_utils.go must preserve empty strings (even after trimming quotes) to maintain the correct number of positional arguments. Filtering out empty values after trimming would collapse the array and break these function calls.

Applied to files:

  • pkg/flags/compat/separated.go
📚 Learning: 2024-10-31T19:25:41.298Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:233-235
Timestamp: 2024-10-31T19:25:41.298Z
Learning: When specifying color values in functions like `confirmDeleteTerraformLocal` in `internal/exec/terraform_clean.go`, avoid hardcoding color values. Instead, use predefined color constants or allow customization through configuration settings to improve accessibility and user experience across different terminals and themes.

Applied to files:

  • pkg/flags/compat/separated.go
  • pkg/flags/registry.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2024-11-22T12:38:33.132Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 768
File: internal/exec/vendor_utils.go:496-513
Timestamp: 2024-11-22T12:38:33.132Z
Learning: In the Atmos project, continue to flag path traversal issues in code reviews but acknowledge when they are expected and acceptable in specific cases.

Applied to files:

  • pkg/flags/compat/separated.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-10-07T00:25:16.333Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.

Applied to files:

  • pkg/flags/compat/separated.go
  • cmd/terraform/metadata.go
  • cmd/terraform/login.go
  • pkg/flags/registry.go
  • cmd/terraform/logout.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-11T03:47:59.576Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/which_test.go:166-223
Timestamp: 2025-11-11T03:47:59.576Z
Learning: In the cloudposse/atmos repo, tests that manipulate environment variables should use testing.T.Setenv for automatic setup/teardown instead of os.Setenv/Unsetenv.

Applied to files:

  • pkg/flags/compat/separated.go
📚 Learning: 2025-11-11T03:47:45.878Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/add_test.go:67-77
Timestamp: 2025-11-11T03:47:45.878Z
Learning: In the cloudposse/atmos codebase, tests should prefer t.Setenv for environment variable setup/teardown instead of os.Setenv/Unsetenv to ensure test-scoped isolation.

Applied to files:

  • pkg/flags/compat/separated.go
📚 Learning: 2025-08-29T20:57:35.423Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1433
File: cmd/theme_list.go:33-36
Timestamp: 2025-08-29T20:57:35.423Z
Learning: In the Atmos codebase, avoid using viper.SetEnvPrefix("ATMOS") with viper.AutomaticEnv() because canonical environment variable names are not exclusive to Atmos and could cause conflicts. Instead, use selective environment variable binding through the setEnv function in pkg/config/load.go with bindEnv(v, "config.key", "ENV_VAR_NAME") for specific environment variables.

Applied to files:

  • pkg/flags/compat/separated.go
📚 Learning: 2025-09-05T14:57:37.360Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 1448
File: cmd/ansible.go:26-28
Timestamp: 2025-09-05T14:57:37.360Z
Learning: The Atmos codebase uses a consistent pattern for commands that delegate to external tools: `PersistentFlags().Bool("", false, doubleDashHint)` where doubleDashHint provides help text about using double dashes to separate Atmos options from native command arguments. This pattern is used across terraform, packer, helmfile, atlantis, aws, and ansible commands.

Applied to files:

  • pkg/flags/compat/separated.go
  • pkg/flags/registry.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions

Applied to files:

  • cmd/terraform/metadata.go
  • cmd/terraform/login.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under `cmd/` directory

Applied to files:

  • cmd/terraform/metadata.go
  • cmd/terraform/login.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: When adding new CLI commands: 1) Create cmd/[command]/ with CommandProvider interface, 2) Add blank import to cmd/root.go, 3) Implement in internal/exec/mycommand.go, 4) Add tests in cmd/mycommand/mycommand_test.go, 5) Create Docusaurus docs, 6) Build website.

Applied to files:

  • cmd/terraform/login.go
📚 Learning: 2025-10-03T18:02:08.535Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: internal/exec/terraform.go:269-272
Timestamp: 2025-10-03T18:02:08.535Z
Learning: In internal/exec/terraform.go, when auth.TerraformPreHook fails, the error is logged but execution continues. This is a deliberate design choice to allow Terraform commands to proceed even if authentication setup fails, rather than failing fast.

Applied to files:

  • cmd/terraform/login.go
📚 Learning: 2025-02-18T13:18:53.146Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-18T13:18:53.146Z
Learning: Error checking is not required for cobra.Command.RegisterFlagCompletionFunc calls as these are static configurations done at init time.

Applied to files:

  • pkg/flags/registry.go
📚 Learning: 2025-02-07T19:21:38.028Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 992
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-07T19:21:38.028Z
Learning: The cobra.Command.RegisterFlagCompletionFunc method (as of cobra v1.8.1) never returns an error. It only initializes an internal map and stores the completion function, always returning nil. Error handling for this method call is unnecessary.

Applied to files:

  • pkg/flags/registry.go
📚 Learning: 2025-02-09T14:38:53.443Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 992
File: cmd/cmd_utils.go:0-0
Timestamp: 2025-02-09T14:38:53.443Z
Learning: Error handling for RegisterFlagCompletionFunc in AddStackCompletion is not required as the errors are non-critical for tab completion functionality.

Applied to files:

  • pkg/flags/registry.go
📚 Learning: 2025-02-07T19:21:38.028Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 992
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-07T19:21:38.028Z
Learning: The cobra.Command.RegisterFlagCompletionFunc method never returns an error as it simply stores the completion function in an internal map. Error handling for this method call is unnecessary.

Applied to files:

  • pkg/flags/registry.go
📚 Learning: 2024-12-07T16:19:01.683Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.

Applied to files:

  • pkg/flags/registry.go
  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to **/*.go : Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig parameter.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-09T19:06:58.470Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1752
File: pkg/profile/list/formatter_table.go:27-29
Timestamp: 2025-11-09T19:06:58.470Z
Learning: In the cloudposse/atmos repository, performance tracking with `defer perf.Track()` is enforced on all functions via linting, including high-frequency utility functions, formatters, and renderers. This is a repository-wide policy to maintain consistency and avoid making case-by-case judgment calls about which functions should have profiling.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2025-10-13T18:13:54.020Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1622
File: pkg/perf/perf.go:140-184
Timestamp: 2025-10-13T18:13:54.020Z
Learning: In pkg/perf/perf.go, the `trackWithSimpleStack` function intentionally skips ownership checks at call stack depth > 1 to avoid expensive `getGoroutineID()` calls on every nested function. This is a performance optimization for the common single-goroutine execution case (most Atmos commands), accepting the rare edge case of potential metric corruption if multi-goroutine execution occurs at depth > 1. The ~19× performance improvement justifies this trade-off.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2025-02-19T05:50:35.853Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: tests/snapshots/TestCLICommands_atmos_terraform_apply_--help.stdout.golden:0-0
Timestamp: 2025-02-19T05:50:35.853Z
Learning: Backtick formatting should only be applied to flag descriptions in Go source files, not in golden test files (test snapshots) as they are meant to capture the raw command output.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2024-12-13T15:28:13.630Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/version.go:34-44
Timestamp: 2024-12-13T15:28:13.630Z
Learning: In `cmd/version.go`, when handling the `--check` flag in the `versionCmd`, avoid using `CheckForAtmosUpdateAndPrintMessage(cliConfig)` as it updates the cache timestamp, which may not be desired in this context.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to **/*.go : NEVER delete existing comments without a very strong reason. Preserve helpful comments, update them to match code changes, refactor for clarity, and add context when modifying code. Only remove factually incorrect, duplicated, or outdated comments.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Document complex logic with inline comments in Go code

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to **/*.go : All comments must end with periods. This is enforced by the godot linter.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2024-12-17T07:08:41.288Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 863
File: internal/exec/yaml_func_terraform_output.go:34-38
Timestamp: 2024-12-17T07:08:41.288Z
Learning: In the `processTagTerraformOutput` function within `internal/exec/yaml_func_terraform_output.go`, parameters are separated by spaces and do not contain spaces. Therefore, using `strings.Fields()` for parsing is acceptable, and there's no need to handle parameters with spaces.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2024-12-07T16:16:13.038Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2024-10-28T01:51:30.811Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:329-332
Timestamp: 2024-10-28T01:51:30.811Z
Learning: In the Atmos Go code, when deleting directories or handling file paths (e.g., in `terraform_clean.go`), always resolve the absolute path using `filepath.Abs` and use the logger `u.LogWarning` for logging messages instead of using `fmt.Printf`.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.

Applied to files:

  • cmd/terraform/compat_flags.go
📚 Learning: 2025-11-10T03:03:31.505Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-11-10T03:03:31.505Z
Learning: In the Atmos codebase, commands using the `StandardParser` flag pattern (from pkg/flags) do NOT need explicit `viper.BindPFlag()` calls in their code. The StandardParser encapsulates flag binding internally: flags are registered via `parser.RegisterFlags(cmd)` in init(), and bound via `parser.BindFlagsToViper(cmd, v)` in RunE, which internally calls viper.BindPFlag for each flag. This pattern is used throughout Atmos (e.g., cmd/toolchain/get.go, cmd/toolchain/info.go, cmd/toolchain/install.go, cmd/toolchain/path.go). Do not flag missing viper.BindPFlag calls when StandardParser is used.

Applied to files:

  • cmd/terraform/compat_flags.go
🧬 Code graph analysis (1)
cmd/terraform/compat_flags.go (2)
pkg/flags/compat/compatibility_flags.go (2)
  • CompatibilityFlag (33-37)
  • AppendToSeparated (24-24)
pkg/perf/perf.go (1)
  • Track (121-138)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Summary
🔇 Additional comments (16)
pkg/flags/compat/separated.go (2)

28-44: Concurrency + defensive copy in GetSeparated looks solid.

The combination of RLock/RUnlock with returning a copy via append([]string{}, globalSeparatedArgs...) is a good pattern here and avoids data races from callers mutating the returned slice.


46-53: ResetSeparated is simple and test-friendly.

The write-locked reset to nil plus perf instrumentation is clean and gives tests and callers a clear way to reset global state.

cmd/terraform/logout.go (3)

1-5: Clean import structure.

Package declaration and imports follow conventions. Single import appropriately reflects the simple delegation pattern.


7-19: Solid command implementation.

The logout command follows the established pattern: comprehensive docs with both Terraform/OpenTofu links, clean delegation to terraformRun, and no unnecessary complexity. The absence of flag parsing is appropriate since logout takes arguments rather than flags.


21-26: Clear initialization logic.

The init function properly attaches the command and documents why completions aren't registered. The explanatory comment is helpful for future maintainers.

cmd/terraform/compat_flags.go (6)

1-6: Imports look clean.

Minimal dependencies with proper alphabetical ordering.


8-120: Solid pattern for composing command-specific flags.

The approach of extending TerraformCompatFlags() for commands that share common flags (plan, apply, destroy, refresh, import) while using standalone maps for specialized commands (init, validate) is clean. All functions include perf tracking and well-written descriptions.


182-187: Good reuse pattern.

UntaintCompatFlags returning TaintCompatFlags() is a clean way to handle identical flag sets. The inline comment explains the relationship clearly.


235-271: Test, Console, and Workspace flags look correct.

The flags defined for these commands align with Terraform CLI documentation.


273-279: Placeholder for future provider flags.

Empty map with explanatory comment is appropriate. Including this in AllTerraformCompatFlags() future-proofs against additions.


281-320: Comprehensive aggregation of all Terraform flags.

The local mergeFlags closure keeps the code DRY. All 21 subcommand flag sources are included, ensuring the preprocessor can identify any pass-through flag regardless of which subcommand is invoked.

pkg/flags/registry.go (3)

123-131: Clarifying stack completion comment is helpful as-is.

The note about CompletionFunc being set from cmd/terraform to avoid an import cycle is clear, follows the comment-style rules (period-terminated), and matches the new completion API. No changes needed here.


145-253: TerraformFlags additions look consistent; double-check env var alias on identity.

The expanded Terraform flag set looks cohesive:

  • identity gains NoOptDefVal for interactive selection, which integrates correctly with PreprocessNoOptDefValArgs.
  • New toggles (init-pass-vars, append-user-agent, process-templates, process-functions, skip, query, components) follow the existing patterns and use ATMOS-prefixed env vars, which will bind cleanly via BindToViper.

One thing to verify:

  • The identity flag adds EnvVars: []string{"ATMOS_IDENTITY", "IDENTITY"}. Project guidelines say env vars should use the ATMOS_ prefix; if IDENTITY is a deliberate legacy/compatibility alias, consider adding a short comment to make that exception explicit for future maintainers, or confirm that the extra alias is still required. As per coding guidelines.

255-317: TerraformAffectedFlags registry cleanly centralizes affected-mode flags.

The new TerraformAffectedFlags registry mirrors existing flag style:

  • Clear, specific descriptions for repo-path, ref, sha, SSH key options, and affected-graph behavior (include-dependents, clone-target-ref).
  • All env vars use the ATMOS_ prefix and should bind correctly via BindToViper.

The separation into its own registry aligns well with the registry pattern and should make reuse across --affected-aware commands straightforward.

cmd/terraform/login.go (2)

16-18: No issues found—terraformRun correctly handles the login command.

The terraformRun function in cmd/terraform/utils.go properly:

  1. Extracts the subcommand name ("login") from actualCmd.Name()
  2. Prepends it to the passed arguments: append([]string{subCommand}, args...)
  3. Passes the combined arguments to ProcessCommandLineArgs for standard Cobra flag parsing
  4. This correctly handles the optional hostname argument that terraform login accepts

The implementation follows the intended delegation pattern and works correctly for all terraform subcommands, including login.


1-26: Based on my verification of the codebase, I can now provide the rewritten review comment.

The registry pattern and StandardFlagParser concerns are not applicable to this file.

The review comment conflates two separate architectural patterns:

  1. Registry pattern: Implemented at the parent level via TerraformCommandProvider interface (in cmd/terraform/terraform.go), not at the subcommand level. Individual subcommands like login.go simply use Cobra's AddCommand() pattern—this is correct.

  2. StandardFlagParser: Only required for commands that define Atmos-specific flags (e.g., plan, apply, deploy). The login command is a terraform native passthrough command with no Atmos-specific flags, so it correctly has no parser.

The login.go file follows the intended pattern for simple terraform passthrough commands, consistent with logout.go (which has identical structure and the same explicit comment explaining why RegisterTerraformCompletions is not called). Both are credential management operations that don't operate on components.

Change /blog/ to /changelog/ since blog posts are routed
to the changelog path in docusaurus config.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
cmd/terraform/utils.go (1)

273-316: Guard against nil auth manager in handleInteractiveIdentitySelection and consider minor robustness tweaks

handleInteractiveIdentitySelection still assumes auth.CreateAndAuthenticateManager always returns a non‑nil manager. Per the documented contract, it can return (nil, nil) when auth is globally disabled, which would cause a panic on authManager.GetDefaultIdentity(true). Suggest adding an explicit nil guard before calling GetDefaultIdentity:

 	authManager, err := auth.CreateAndAuthenticateManager(
 		cfg.IdentityFlagSelectValue,
 		&atmosConfig.Auth,
 		cfg.IdentityFlagSelectValue,
 	)
 	if err != nil {
 		errUtils.CheckErrorPrintAndExit(fmt.Errorf(errWrapFormat, errUtils.ErrFailedToInitializeAuthManager, err), "", "")
 	}
+
+	// Guard against nil auth manager (can occur when authentication is disabled globally).
+	if authManager == nil {
+		errUtils.CheckErrorPrintAndExit(errUtils.ErrNoIdentitiesAvailable, "", "")
+	}
 
 	// Get default identity with forced interactive selection.
 	// GetDefaultIdentity() handles TTY and CI detection via isInteractive().
 	selectedIdentity, err := authManager.GetDefaultIdentity(true)

Two smaller, non‑blocking tweaks you may want to consider:

  • enableHeatmapIfRequested: also detect --heatmap= forms so --heatmap=true is honored:
-	for _, arg := range os.Args {
-		if arg == "--heatmap" {
+	for _, arg := range os.Args {
+		if arg == "--heatmap" || strings.HasPrefix(arg, "--heatmap=") {
 			perf.EnableTracking(true)
 			return
 		}
  • identityFlagCompletion: if you ever need completions to respect --base-path/--config/--config-path/--profile, consider following the flags.ParseGlobalFlagscfg.InitCliConfig(configAndStacksInfo, ...) pattern used elsewhere instead of passing an empty schema.ConfigAndStacksInfo{}. For now, returning a generic completion list from the default config is acceptable.

Based on learnings about CreateAndAuthenticateManager’s (nil, nil) behavior and the cfg.InitCliConfig usage pattern.

Also applies to: 379-409

🧹 Nitpick comments (3)
cmd/terraform/generate/varfile.go (1)

18-24: Command shape and args look solid; consider adding examples.

The Use, Args, and completion wiring for varfileCmd look consistent with the newer Terraform command style, and keeping the positional component optional pairs nicely with the interactive prompt.

Given the CLI guidelines, it’d be nice to add an Example field (and possibly slightly richer Long text) showing a couple of typical invocations, e.g.:

  • atmos terraform generate varfile my-component -s tenant/ue2/dev
  • atmos terraform generate varfile my-component -s tenant/ue2/dev --file ./varfile.tfvars.json

This keeps atmos terraform generate --help and ... varfile --help more self-documenting alongside the other generate subcommands.

cmd/terraform/flags.go (1)

183-195: Consider moving perf.Track to the registry construction, not the Option wrapper.

The defer perf.Track() in WithTerraformFlags() and WithTerraformAffectedFlags() will measure the time to create the option closure, not the actual flag registration. Since TerraformFlags() already has its own perf.Track, these may be redundant.

 // WithTerraformFlags returns a flags.Option that adds all Terraform-specific flags.
 func WithTerraformFlags() flags.Option {
-	defer perf.Track(nil, "terraform.WithTerraformFlags")()
-
 	return flags.WithFlagRegistry(TerraformFlags())
 }
 
 // WithTerraformAffectedFlags returns a flags.Option that adds affected component detection flags.
 func WithTerraformAffectedFlags() flags.Option {
-	defer perf.Track(nil, "terraform.WithTerraformAffectedFlags")()
-
 	return flags.WithFlagRegistry(TerraformAffectedFlags())
 }
cmd/terraform/shared/prompt.go (1)

18-27: Consider adding perf.Track to public prompt functions.

Per coding guidelines, public functions should have defer perf.Track(atmosConfig, "pkg.FuncName")(). Since these don't have atmosConfig available, use nil.

+import "github.com/cloudposse/atmos/pkg/perf"
+
 // PromptForComponent shows an interactive selector for component selection.
 func PromptForComponent(cmd *cobra.Command) (string, error) {
+	defer perf.Track(nil, "shared.PromptForComponent")()
+
 	return flags.PromptForPositionalArg(
 // ...

 // PromptForStack shows an interactive selector for stack selection.
 func PromptForStack(cmd *cobra.Command, component string) (string, error) {
+	defer perf.Track(nil, "shared.PromptForStack")()
+
 	var args []string

Also applies to: 29-43

…s in varfile

- Add Profile field to ParseGlobalFlags return block so --profile flag is respected
- Update generate/varfile.go to use ParseGlobalFlags before InitCliConfig
- This ensures --base-path, --config, --config-path, and --profile flags work

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
website/blog/2025-12-15-interactive-terraform-prompts.mdx (2)

1-11: Front matter and blog scaffolding look solid

Front matter, slug, authors, tags, and <!--truncate--> placement all match the blog conventions for this repo. I don’t see structural issues here.

As per coding guidelines, this is aligned with the expected blog format.


105-125: Clarify or link to the full list of supported commands

The table plus “And 10 more...” is readable, but it can leave readers guessing which exact terraform subcommands get prompts (especially as the registry evolves).

Two lightweight improvements you could consider:

  • Link “And 10 more...” to the canonical CLI docs page that lists all interactive‑enabled terraform commands, or
  • Replace it with a brief note like “See atmos terraform --help for the full list of interactive‑enabled subcommands.”

This keeps the post evergreen even as the command registry expands.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f698e4f and a4cc2c7.

📒 Files selected for processing (3)
  • cmd/terraform/generate/varfile.go (1 hunks)
  • pkg/flags/global_registry.go (1 hunks)
  • website/blog/2025-12-15-interactive-terraform-prompts.mdx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/terraform/generate/varfile.go
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using fmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: use gofmt and goimports to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

**/*.go: Comment style: All comments must end with periods (enforced by godot linter)
Import organization: Three groups separated by blank lines (stdlib, 3rd-party, Atmos packages), sorted alphabetically within groups, maintain aliases: cfg, log, u, errUtils
Performance tracking: Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig param
Error handling: ALL user-facing errors MUST use ErrorBuilder with sentinel errors from errors/errors.go. ALWAYS use errors.Is() for checking, NEVER string comparison. ALWAYS use assert.ErrorIs() in tests, NEVER assert.Contains(err.Error(), ...)
Mock generation: Use go.uber.org/mock/mockgen with //go:generate directives. Never manual mocks
File organization: Keep files small and focused (<600 lines). One cmd/impl per file. Co-locate tests. Never use `//revive:disable:file-lengt...

Files:

  • pkg/flags/global_registry.go
website/**

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

website/**: Update website documentation in the website/ directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in the website/ directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Files:

  • website/blog/2025-12-15-interactive-terraform-prompts.mdx
website/blog/*.mdx

📄 CodeRabbit inference engine (CLAUDE.md)

Blog posts: Use .mdx format with YAML front matter in website/blog/YYYY-MM-DD-feature-name.mdx. Include <!--truncate--> after intro. Use only tags defined in website/blog/tags.yml. Use authors from website/blog/authors.yml

Files:

  • website/blog/2025-12-15-interactive-terraform-prompts.mdx
🧠 Learnings (14)
📓 Common learnings
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Adding new CLI command: 1) Create `cmd/[command]/` with CommandProvider interface, 2) Add blank import to `cmd/root.go`: `_ "github.com/cloudposse/atmos/cmd/mycommand"`, 3) Implement in `internal/exec/mycommand.go`, 4) Add tests in `cmd/mycommand/mycommand_test.go`, 5) Create Docusaurus docs in `website/docs/cli/commands/<command>/<subcommand>.mdx`, 6) Build website: `cd website && npm run build`. See `docs/developing-atmos-commands.md` and `docs/prd/command-registry-pattern.md`
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Registry pattern: Use registry pattern for extensibility and plugin-like architecture. New commands MUST use command registry pattern. See docs/prd/command-registry-pattern.md
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: errors/errors.go:184-203
Timestamp: 2025-12-13T06:10:06.715Z
Learning: cloudposse/atmos: For toolchain work, duplicate/unused error sentinels in errors/errors.go should be cleaned up in a separate refactor PR and not block feature PRs; canonical toolchain sentinels live under toolchain/registry with re-exports in toolchain/errors.go.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to internal/exec/template_funcs.go : Template functions: Implement in `internal/exec/template_funcs.go`, register, test, document. Available: `atmos.Component/Stack/Setting()`, `terraform.output/state()`, `store.get()`, `exec()`, `env()`
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: internal/exec/terraform.go:269-272
Timestamp: 2025-10-03T18:02:08.535Z
Learning: In internal/exec/terraform.go, when auth.TerraformPreHook fails, the error is logged but execution continues. This is a deliberate design choice to allow Terraform commands to proceed even if authentication setup fails, rather than failing fast.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: cmd/terraform.go:111-117
Timestamp: 2025-06-23T02:14:30.937Z
Learning: In cmd/terraform.go, flags for the DescribeAffected function are added dynamically at runtime when info.Affected is true. This is intentional to avoid exposing internal flags like "file", "format", "verbose", "include-spacelift-admin-stacks", "include-settings", and "upload" in the terraform command interface, while still providing them for the shared DescribeAffected function used by both `atmos describe affected` and `atmos terraform apply --affected`.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: internal/exec/terraform_utils.go:144-145
Timestamp: 2024-12-03T03:52:02.524Z
Learning: Avoid adding context timeouts to Terraform commands in `execTerraformOutput` because their execution time can vary from seconds to hours, and making it configurable would require redesigning the command interface.
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:233-235
Timestamp: 2024-10-31T19:25:41.298Z
Learning: When specifying color values in functions like `confirmDeleteTerraformLocal` in `internal/exec/terraform_clean.go`, avoid hardcoding color values. Instead, use predefined color constants or allow customization through configuration settings to improve accessibility and user experience across different terminals and themes.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 759
File: internal/exec/terraform.go:366-368
Timestamp: 2024-11-02T15:35:09.958Z
Learning: In `internal/exec/terraform.go`, the workspace cleaning code under both the general execution path and within the `case "init":` block is intentionally duplicated because the code execution paths are different. The `.terraform/environment` file should be deleted before executing `terraform init` in both scenarios to ensure a clean state.
📚 Learning: 2025-12-13T03:21:27.620Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1813
File: cmd/terraform/shell.go:28-73
Timestamp: 2025-12-13T03:21:27.620Z
Learning: In Atmos, when calling cfg.InitCliConfig, you must first populate the schema.ConfigAndStacksInfo struct with global flag values using flags.ParseGlobalFlags(cmd, v) rather than passing an empty struct. The LoadConfig function (pkg/config/load.go) reads config selection fields (AtmosConfigFilesFromArg, AtmosConfigDirsFromArg, BasePath, ProfilesFromArg) directly from the ConfigAndStacksInfo struct, NOT from Viper. Passing an empty struct causes config selection flags (--base-path, --config, --config-path, --profile) to be silently ignored. Correct pattern: parse flags → populate struct → call InitCliConfig. See cmd/terraform/plan_diff.go for reference implementation.

Applied to files:

  • pkg/flags/global_registry.go
📚 Learning: 2025-06-23T02:14:30.937Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: cmd/terraform.go:111-117
Timestamp: 2025-06-23T02:14:30.937Z
Learning: In cmd/terraform.go, flags for the DescribeAffected function are added dynamically at runtime when info.Affected is true. This is intentional to avoid exposing internal flags like "file", "format", "verbose", "include-spacelift-admin-stacks", "include-settings", and "upload" in the terraform command interface, while still providing them for the shared DescribeAffected function used by both `atmos describe affected` and `atmos terraform apply --affected`.

Applied to files:

  • pkg/flags/global_registry.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Use Viper for managing configuration, environment variables, and flags in CLI commands

Applied to files:

  • pkg/flags/global_registry.go
📚 Learning: 2025-10-11T19:11:58.965Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:0-0
Timestamp: 2025-10-11T19:11:58.965Z
Learning: For terraform apply interactivity checks in Atmos (internal/exec/terraform.go), use stdin TTY detection (e.g., `IsTTYSupportForStdin()` or checking `os.Stdin`) to determine if user prompts are possible. This is distinct from stdout/stderr TTY checks used for output display (like TUI rendering). User input requires stdin to be a TTY; output display requires stdout/stderr to be a TTY.

Applied to files:

  • website/blog/2025-12-15-interactive-terraform-prompts.mdx
📚 Learning: 2024-10-21T17:51:53.976Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform.go:114-118
Timestamp: 2024-10-21T17:51:53.976Z
Learning: When `atmos terraform clean --everything` is used without specifying a component and without the `--force` flag, prompt the user for confirmation before deleting all components. Use the `--force` flag to skip the confirmation prompt.

Applied to files:

  • website/blog/2025-12-15-interactive-terraform-prompts.mdx
📚 Learning: 2025-01-19T15:49:15.593Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 955
File: tests/snapshots/TestCLICommands_atmos_validate_editorconfig_--help.stdout.golden:0-0
Timestamp: 2025-01-19T15:49:15.593Z
Learning: In future commits, the help text for Atmos CLI commands should be limited to only show component and stack parameters for commands that actually use them. This applies to the example usage section in command help text.

Applied to files:

  • website/blog/2025-12-15-interactive-terraform-prompts.mdx
📚 Learning: 2024-11-16T17:30:52.893Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 786
File: internal/exec/shell_utils.go:159-162
Timestamp: 2024-11-16T17:30:52.893Z
Learning: For the `atmos terraform shell` command in `internal/exec/shell_utils.go`, input validation for the custom shell prompt is not required, as users will use this as a CLI tool and any issues will impact themselves.

Applied to files:

  • website/blog/2025-12-15-interactive-terraform-prompts.mdx
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • website/blog/2025-12-15-interactive-terraform-prompts.mdx
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Adding new CLI command: 1) Create `cmd/[command]/` with CommandProvider interface, 2) Add blank import to `cmd/root.go`: `_ "github.com/cloudposse/atmos/cmd/mycommand"`, 3) Implement in `internal/exec/mycommand.go`, 4) Add tests in `cmd/mycommand/mycommand_test.go`, 5) Create Docusaurus docs in `website/docs/cli/commands/<command>/<subcommand>.mdx`, 6) Build website: `cd website && npm run build`. See `docs/developing-atmos-commands.md` and `docs/prd/command-registry-pattern.md`

Applied to files:

  • website/blog/2025-12-15-interactive-terraform-prompts.mdx
📚 Learning: 2025-10-07T00:25:16.333Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.

Applied to files:

  • website/blog/2025-12-15-interactive-terraform-prompts.mdx
📚 Learning: 2024-11-12T13:06:56.194Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 768
File: website/docs/cheatsheets/vendoring.mdx:70-70
Timestamp: 2024-11-12T13:06:56.194Z
Learning: In `atmos vendor pull --everything`, the `--everything` flag uses the TTY for TUI but is not interactive.

Applied to files:

  • website/blog/2025-12-15-interactive-terraform-prompts.mdx
📚 Learning: 2024-10-21T17:51:07.087Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform.go:114-118
Timestamp: 2024-10-21T17:51:07.087Z
Learning: Use `bubbletea` for confirmation prompts instead of `fmt.Scanln` in the `atmos terraform clean` command.

Applied to files:

  • website/blog/2025-12-15-interactive-terraform-prompts.mdx
📚 Learning: 2025-11-07T14:52:55.217Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1761
File: docs/prd/claude-agent-architecture.md:331-439
Timestamp: 2025-11-07T14:52:55.217Z
Learning: In the cloudposse/atmos repository, Claude agents are used as interactive tools, not in automated/headless CI/CD contexts. Agent documentation and patterns should assume synchronous human interaction.

Applied to files:

  • website/blog/2025-12-15-interactive-terraform-prompts.mdx
🧬 Code graph analysis (1)
pkg/flags/global_registry.go (1)
pkg/flags/parser.go (1)
  • GetStringSlice (129-138)
🪛 LanguageTool
website/blog/2025-12-15-interactive-terraform-prompts.mdx

[typographical] ~52-~52: Consider using a typographic opening quote here.
Context: ...he burden on senior engineers to answer "what components do we have?" questions. ...

(EN_QUOTES)


[typographical] ~52-~52: Consider using a typographic close quote here.
Context: ...s to answer "what components do we have?" questions. ## How It Works Interactiv...

(EN_QUOTES)


[typographical] ~60-~60: To join two clauses or introduce examples, consider using an em dash.
Context: ...or in CI) 3. --interactive enabled - On by default, disable with `--interacti...

(DASH_RULE)


[style] ~123-~123: Consider using the typographical ellipsis character here instead.
Context: ...port| Import resources | | And 10 more... | | Custom commands likeshell, cle...

(ELLIPSIS)

⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Summary
🔇 Additional comments (3)
pkg/flags/global_registry.go (1)

59-61: Profile slice wiring looks consistent; please confirm end‑to‑end integration.

Reading Profile via v.GetStringSlice("profile") is consistent with how other multi‑value globals (like config/config-path) are handled, and respects Viper’s precedence. The change itself looks good.

Please double‑check that:

  • The profile flag (and ATMOS_PROFILE env) is registered somewhere in the global flag registry, and
  • global.Flags.Profile is actually threaded into cfg.ConfigAndStacksInfo.ProfilesFromArg (or equivalent) before calling cfg.InitCliConfig, so profile selection is honored the same way as config paths. Based on learnings, this struct is read directly by LoadConfig, not via Viper.
website/blog/2025-12-15-interactive-terraform-prompts.mdx (2)

56-61: Verify CI/TTY/interactive gating matches the implemented behavior

The blog states that prompts appear when:

  1. Component or stack are missing
  2. Running in a TTY (not piped or in CI)
  3. --interactive is enabled (default), or disabled via flag/env/config

Verification requires checking whether the code actually gates on:

  • stdin TTY (not just stdout) — critical for user prompts to work
  • CI environment detection — to auto-disable in CI
  • Flag/env/config precedence — matching your documented order (--interactive, ATMOS_INTERACTIVE, settings.interactive)

Check that all command paths using interactive prompts share a common gating helper rather than having scattered checks. Based on learnings, stdin TTY detection is especially important and distinct from stdout/stderr checks used for output display.


14-28: Verify the "22 terraform commands" claim and ensure documentation stays synchronized with code

Hard-coding a specific command count in the blog post risks future drift if new terraform subcommands are added or the interactive prompts feature scope changes. Either drop the exact number and reference "all terraform subcommands that require component and stack arguments," or establish a way to keep the count in sync—such as documenting where this number is derived from or using a programmatic check (e.g., an enumeration helper or central registry) that the docs can reference.

The same applies to the "previously…unhelpful error message" phrasing—it should be grounded in the actual behavior when those flags are missing, not assumptions about past behavior.

osterman and others added 2 commits December 15, 2025 14:52
The CI test was failing because the trace log "Checking for atmos.yaml
in working directory" appears in different positions between local and
CI environments. Adding this pattern to the diff ignore list ensures
the test focuses on behavior rather than debug output ordering.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Populate ConfigAndStacksInfo with global flags (--base-path, --config,
--config-path, --profile) in list command handlers. Previously, these
flags were silently ignored because checkAtmosConfig and initConfigAndAuth
used empty ConfigAndStacksInfo structs.

- Modified checkAtmosConfig to accept cmd and viper, parse global flags
- Modified initConfigAndAuth to accept cmd and viper, parse global flags
- Added buildConfigAndStacksInfo helper to create ConfigAndStacksInfo from flags
- Updated all list commands to pass cmd and viper to these functions

This follows the pattern established in cmd/terraform/shell.go and
ensures config selection flags are respected across all list commands.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@mergify
Copy link

mergify bot commented Dec 15, 2025

Important

Cloud Posse Engineering Team Review Required

This pull request modifies files that require Cloud Posse's review. Please be patient, and a core maintainer will review your changes.

To expedite this process, reach out to us on Slack in the #pr-reviews channel.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
cmd/list/values.go (1)

317-330: Critical: Config selection flags will be silently ignored.

Passing an empty schema.ConfigAndStacksInfo{} to config.InitCliConfig causes global config flags (--base-path, --config, --config-path, --profile) to be ignored. Per the learning from cmd/terraform/shell.go, LoadConfig reads these fields directly from the ConfigAndStacksInfo struct, NOT from Viper.

Other list commands (components, metadata, stacks, workflows, instances) correctly call e.ProcessCommandLineArgs before InitCliConfig, which populates the struct with CLI flags. This command should follow the same pattern.

Apply this diff to fix the issue:

 func listValuesWithOptions(cmd *cobra.Command, opts *ValuesOptions, args []string) (string, error) {
 	// Ensure we have a component name
 	if len(args) == 0 {
 		return "", ErrComponentNameRequired
 	}
 	componentName := args[0]
 
-	// Initialize CLI config
-	configAndStacksInfo := schema.ConfigAndStacksInfo{}
+	// Initialize CLI config with global flags to honor --base-path, --config, etc.
+	configAndStacksInfo, err := e.ProcessCommandLineArgs("list", cmd, args, nil)
+	if err != nil {
+		return "", err
+	}
+	
-	atmosConfig, err := config.InitCliConfig(configAndStacksInfo, true)
+	atmosConfig, err := config.InitCliConfig(configAndStacksInfo, true)
 	if err != nil {
 		return "", fmt.Errorf(ErrFmtWrapErr, ErrInitializingCLIConfig, err)
 	}

Based on learnings from cmd/terraform/shell.go and cmd/terraform/plan_diff.go.

cmd/list/vendor.go (1)

121-128: Critical: Config selection flags will be silently ignored.

Same issue as cmd/list/values.go: passing an empty schema.ConfigAndStacksInfo{} causes global config flags (--base-path, --config, --config-path, --profile) to be ignored. LoadConfig reads these fields directly from the struct, not from Viper.

Other list commands correctly call e.ProcessCommandLineArgs before InitCliConfig. This command should follow the same pattern.

Apply this diff:

 func listVendorWithOptions(opts *VendorOptions) error {
 	defer perf.Track(nil, "list.vendor.listVendorWithOptions")()
 
-	configAndStacksInfo := schema.ConfigAndStacksInfo{}
+	// Note: ProcessCommandLineArgs requires cmd and args parameters
+	// This function signature needs to be updated to accept them
+	configAndStacksInfo, err := e.ProcessCommandLineArgs("list", cmd, args, nil)
+	if err != nil {
+		return err
+	}
+	
-	atmosConfig, err := config.InitCliConfig(configAndStacksInfo, false)
+	atmosConfig, err := config.InitCliConfig(configAndStacksInfo, false)
 	if err != nil {
 		return err
 	}

Note: The function signature needs updating to accept cmd *cobra.Command and args []string parameters to call ProcessCommandLineArgs. See how other list commands handle this.

Based on learnings from cmd/terraform/shell.go.

🧹 Nitpick comments (1)
cmd/list/utils.go (1)

94-125: Consider honoring global flags in completion helpers (optional enhancement).

The listStacksForComponent and listAllStacks functions still use empty ConfigAndStacksInfo{}, which means shell completions won't respect global flags like --base-path or --config.

The stackFlagCompletion function receives the cmd parameter that could be passed down to these helpers, enabling them to honor global flags using the same pattern as the rest of this file.

However, completion functions may intentionally use defaults for simplicity and performance. If this is intentional, consider adding a comment explaining why completions use default config.

Example enhancement if desired:

-func listStacksForComponent(component string) ([]string, error) {
-	configAndStacksInfo := schema.ConfigAndStacksInfo{}
+func listStacksForComponent(cmd *cobra.Command, component string) ([]string, error) {
+	globalFlags := flags.ParseGlobalFlags(cmd, viper.GetViper())
+	configAndStacksInfo := buildConfigAndStacksInfo(&globalFlags)

And update the call site:

-		output, err := listStacksForComponent(args[0])
+		output, err := listStacksForComponent(cmd, args[0])
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9295538 and fa80c3b.

📒 Files selected for processing (9)
  • cmd/list/components.go (1 hunks)
  • cmd/list/instances.go (1 hunks)
  • cmd/list/metadata.go (1 hunks)
  • cmd/list/settings.go (3 hunks)
  • cmd/list/stacks.go (1 hunks)
  • cmd/list/utils.go (4 hunks)
  • cmd/list/values.go (2 hunks)
  • cmd/list/vendor.go (1 hunks)
  • cmd/list/workflows.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
cmd/**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

cmd/**/*.go: Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under cmd/ directory
Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands

Files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using fmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: use gofmt and goimports to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

**/*.go: Comment style: All comments must end with periods (enforced by godot linter)
Import organization: Three groups separated by blank lines (stdlib, 3rd-party, Atmos packages), sorted alphabetically within groups, maintain aliases: cfg, log, u, errUtils
Performance tracking: Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig param
Error handling: ALL user-facing errors MUST use ErrorBuilder with sentinel errors from errors/errors.go. ALWAYS use errors.Is() for checking, NEVER string comparison. ALWAYS use assert.ErrorIs() in tests, NEVER assert.Contains(err.Error(), ...)
Mock generation: Use go.uber.org/mock/mockgen with //go:generate directives. Never manual mocks
File organization: Keep files small and focused (<600 lines). One cmd/impl per file. Co-locate tests. Never use `//revive:disable:file-lengt...

Files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
cmd/*/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

cmd/*/*.go: Flag handling: Commands MUST use flags.NewStandardParser() for command-specific flags. NEVER call viper.BindEnv() or viper.BindPFlag() directly (enforced by Forbidigo linter)
CLI commands structure: Embed examples from cmd/markdown/*_usage.md using //go:embed. Render with utils.PrintfMarkdown()

Files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
🧠 Learnings (34)
📓 Common learnings
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Adding new CLI command: 1) Create `cmd/[command]/` with CommandProvider interface, 2) Add blank import to `cmd/root.go`: `_ "github.com/cloudposse/atmos/cmd/mycommand"`, 3) Implement in `internal/exec/mycommand.go`, 4) Add tests in `cmd/mycommand/mycommand_test.go`, 5) Create Docusaurus docs in `website/docs/cli/commands/<command>/<subcommand>.mdx`, 6) Build website: `cd website && npm run build`. See `docs/developing-atmos-commands.md` and `docs/prd/command-registry-pattern.md`
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Registry pattern: Use registry pattern for extensibility and plugin-like architecture. New commands MUST use command registry pattern. See docs/prd/command-registry-pattern.md
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: errors/errors.go:184-203
Timestamp: 2025-12-13T06:10:06.715Z
Learning: cloudposse/atmos: For toolchain work, duplicate/unused error sentinels in errors/errors.go should be cleaned up in a separate refactor PR and not block feature PRs; canonical toolchain sentinels live under toolchain/registry with re-exports in toolchain/errors.go.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to internal/exec/template_funcs.go : Template functions: Implement in `internal/exec/template_funcs.go`, register, test, document. Available: `atmos.Component/Stack/Setting()`, `terraform.output/state()`, `store.get()`, `exec()`, `env()`
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: cmd/terraform.go:111-117
Timestamp: 2025-06-23T02:14:30.937Z
Learning: In cmd/terraform.go, flags for the DescribeAffected function are added dynamically at runtime when info.Affected is true. This is intentional to avoid exposing internal flags like "file", "format", "verbose", "include-spacelift-admin-stacks", "include-settings", and "upload" in the terraform command interface, while still providing them for the shared DescribeAffected function used by both `atmos describe affected` and `atmos terraform apply --affected`.
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: internal/exec/terraform.go:269-272
Timestamp: 2025-10-03T18:02:08.535Z
Learning: In internal/exec/terraform.go, when auth.TerraformPreHook fails, the error is logged but execution continues. This is a deliberate design choice to allow Terraform commands to proceed even if authentication setup fails, rather than failing fast.
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:233-235
Timestamp: 2024-10-31T19:25:41.298Z
Learning: When specifying color values in functions like `confirmDeleteTerraformLocal` in `internal/exec/terraform_clean.go`, avoid hardcoding color values. Instead, use predefined color constants or allow customization through configuration settings to improve accessibility and user experience across different terminals and themes.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.
📚 Learning: 2025-11-08T19:56:18.660Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1697
File: internal/exec/oci_utils.go:0-0
Timestamp: 2025-11-08T19:56:18.660Z
Learning: In the Atmos codebase, when a function receives an `*schema.AtmosConfiguration` parameter, it should read configuration values from `atmosConfig.Settings` fields rather than using direct `os.Getenv()` or `viper.GetString()` calls. The Atmos pattern is: viper.BindEnv in cmd/root.go binds environment variables → Viper unmarshals into atmosConfig.Settings via mapstructure → business logic reads from the Settings struct. This provides centralized config management, respects precedence, and enables testability. Example: `atmosConfig.Settings.AtmosGithubToken` instead of `os.Getenv("ATMOS_GITHUB_TOKEN")` in functions like `getGHCRAuth` in internal/exec/oci_utils.go.

Applied to files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
📚 Learning: 2025-12-13T03:21:27.620Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1813
File: cmd/terraform/shell.go:28-73
Timestamp: 2025-12-13T03:21:27.620Z
Learning: In Atmos, when calling cfg.InitCliConfig, you must first populate the schema.ConfigAndStacksInfo struct with global flag values using flags.ParseGlobalFlags(cmd, v) rather than passing an empty struct. The LoadConfig function (pkg/config/load.go) reads config selection fields (AtmosConfigFilesFromArg, AtmosConfigDirsFromArg, BasePath, ProfilesFromArg) directly from the ConfigAndStacksInfo struct, NOT from Viper. Passing an empty struct causes config selection flags (--base-path, --config, --config-path, --profile) to be silently ignored. Correct pattern: parse flags → populate struct → call InitCliConfig. See cmd/terraform/plan_diff.go for reference implementation.

Applied to files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Use Viper for managing configuration, environment variables, and flags in CLI commands

Applied to files:

  • cmd/list/components.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
📚 Learning: 2025-08-29T20:57:35.423Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1433
File: cmd/theme_list.go:33-36
Timestamp: 2025-08-29T20:57:35.423Z
Learning: In the Atmos codebase, avoid using viper.SetEnvPrefix("ATMOS") with viper.AutomaticEnv() because canonical environment variable names are not exclusive to Atmos and could cause conflicts. Instead, use selective environment variable binding through the setEnv function in pkg/config/load.go with bindEnv(v, "config.key", "ENV_VAR_NAME") for specific environment variables.

Applied to files:

  • cmd/list/components.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
📚 Learning: 2025-11-10T03:03:31.505Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-11-10T03:03:31.505Z
Learning: In the Atmos codebase, commands using the `StandardParser` flag pattern (from pkg/flags) do NOT need explicit `viper.BindPFlag()` calls in their code. The StandardParser encapsulates flag binding internally: flags are registered via `parser.RegisterFlags(cmd)` in init(), and bound via `parser.BindFlagsToViper(cmd, v)` in RunE, which internally calls viper.BindPFlag for each flag. This pattern is used throughout Atmos (e.g., cmd/toolchain/get.go, cmd/toolchain/info.go, cmd/toolchain/install.go, cmd/toolchain/path.go). Do not flag missing viper.BindPFlag calls when StandardParser is used.

Applied to files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*.go : Environment variables: Use `viper.BindEnv("ATMOS_VAR", "ATMOS_VAR", "FALLBACK")` - ATMOS_ prefix required

Applied to files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
📚 Learning: 2025-04-23T15:02:50.246Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1202
File: pkg/utils/yaml_func_exec.go:104-104
Timestamp: 2025-04-23T15:02:50.246Z
Learning: In the Atmos codebase, direct calls to `os.Getenv` should be avoided. Instead, use `viper.BindEnv` for environment variable access. This provides a consistent approach to configuration management across the codebase.

Applied to files:

  • cmd/list/components.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
📚 Learning: 2024-12-11T18:40:12.808Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/helmfile.go:37-37
Timestamp: 2024-12-11T18:40:12.808Z
Learning: In the atmos project, `cliConfig` is initialized within the `cmd` package in `root.go` and can be used in other command files.

Applied to files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/stacks.go
📚 Learning: 2024-12-13T15:28:13.630Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/version.go:34-44
Timestamp: 2024-12-13T15:28:13.630Z
Learning: In `cmd/version.go`, when handling the `--check` flag in the `versionCmd`, avoid using `CheckForAtmosUpdateAndPrintMessage(cliConfig)` as it updates the cache timestamp, which may not be desired in this context.

Applied to files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
📚 Learning: 2025-01-30T19:30:59.120Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/workflow.go:74-74
Timestamp: 2025-01-30T19:30:59.120Z
Learning: Error handling for `cmd.Usage()` is not required in the Atmos CLI codebase, as confirmed by the maintainer.

Applied to files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
📚 Learning: 2025-10-07T00:25:16.333Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.

Applied to files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/vendor.go
  • cmd/list/stacks.go
📚 Learning: 2025-01-18T15:15:41.645Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform.go:37-46
Timestamp: 2025-01-18T15:15:41.645Z
Learning: In the atmos CLI, error handling is intentionally structured to use LogErrorAndExit for consistent error display, avoiding Cobra's default error handling to prevent duplicate error messages.

Applied to files:

  • cmd/list/components.go
  • cmd/list/workflows.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
📚 Learning: 2024-12-07T16:16:13.038Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.

Applied to files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/settings.go
  • cmd/list/vendor.go
  • cmd/list/stacks.go
📚 Learning: 2025-01-09T22:27:25.538Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/validate_stacks.go:20-23
Timestamp: 2025-01-09T22:27:25.538Z
Learning: The validate commands in Atmos can have different help handling implementations. Specifically, validate_component.go and validate_stacks.go are designed to handle help requests differently, with validate_stacks.go including positional argument checks while validate_component.go does not.

Applied to files:

  • cmd/list/components.go
  • cmd/list/vendor.go
  • cmd/list/stacks.go
📚 Learning: 2024-12-05T22:33:54.807Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 820
File: cmd/list_stacks.go:55-56
Timestamp: 2024-12-05T22:33:54.807Z
Learning: In the atmos project, the `u.LogErrorAndExit` function logs the error and exits the command execution appropriately within flag completion functions.

Applied to files:

  • cmd/list/components.go
📚 Learning: 2025-09-05T14:57:37.360Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 1448
File: cmd/ansible.go:26-28
Timestamp: 2025-09-05T14:57:37.360Z
Learning: The Atmos codebase uses a consistent pattern for commands that delegate to external tools: `PersistentFlags().Bool("", false, doubleDashHint)` where doubleDashHint provides help text about using double dashes to separate Atmos options from native command arguments. This pattern is used across terraform, packer, helmfile, atlantis, aws, and ansible commands.

Applied to files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/instances.go
📚 Learning: 2025-12-13T04:37:40.435Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/toolchain/get.go:23-40
Timestamp: 2025-12-13T04:37:40.435Z
Learning: In Go CLI command files using Cobra, constrain the subcommand to accept at most one positional argument (MaximumNArgs(1)) so it supports both listing all items (zero args) and fetching a specific item (one arg). Define and parse flags with a standard parser (e.g., flags.NewStandardParser()) and avoid binding flags to Viper (no viper.BindEnv/BindPFlag). This promotes explicit argument handling and predictable flag behavior across command files.

Applied to files:

  • cmd/list/components.go
  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
📚 Learning: 2025-10-10T23:51:36.597Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.

Applied to files:

  • cmd/list/utils.go
📚 Learning: 2024-10-20T13:12:46.499Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 736
File: pkg/config/const.go:6-6
Timestamp: 2024-10-20T13:12:46.499Z
Learning: In `cmd/cmd_utils.go`, it's acceptable to have hardcoded references to `atmos.yaml` in logs, and it's not necessary to update them to use the `CliConfigFileName` constant.

Applied to files:

  • cmd/list/utils.go
  • cmd/list/workflows.go
  • cmd/list/vendor.go
📚 Learning: 2025-09-07T18:07:00.549Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1452
File: cmd/auth_login.go:43-44
Timestamp: 2025-09-07T18:07:00.549Z
Learning: In the atmos project, the identity flag is defined as a persistent flag on the auth root command (cmd/auth.go), making it available to all auth subcommands without needing to be redefined in each individual subcommand.

Applied to files:

  • cmd/list/utils.go
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*.go : Import organization: Three groups separated by blank lines (stdlib, 3rd-party, Atmos packages), sorted alphabetically within groups, maintain aliases: `cfg`, `log`, `u`, `errUtils`

Applied to files:

  • cmd/list/utils.go
📚 Learning: 2025-07-05T20:59:02.914Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1363
File: internal/exec/template_utils.go:18-18
Timestamp: 2025-07-05T20:59:02.914Z
Learning: In the Atmos project, gomplate v4 is imported with a blank import (`_ "github.com/hairyhenderson/gomplate/v4"`) alongside v3 imports to resolve AWS SDK version conflicts. V3 uses older AWS SDK versions that conflict with newer AWS modules used by Atmos. A full migration to v4 requires extensive refactoring due to API changes and should be handled in a separate PR.

Applied to files:

  • cmd/list/utils.go
📚 Learning: 2025-10-22T14:55:44.014Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1695
File: pkg/auth/manager.go:169-171
Timestamp: 2025-10-22T14:55:44.014Z
Learning: Go 1.20+ supports multiple %w verbs in fmt.Errorf, which returns an error implementing Unwrap() []error. This is valid and does not panic. Atmos uses Go 1.24.8 and configures errorlint with errorf-multi: true to validate this pattern.

Applied to files:

  • cmd/list/utils.go
📚 Learning: 2025-12-13T04:37:18.265Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/root.go:0-0
Timestamp: 2025-12-13T04:37:18.265Z
Learning: In Atmos cmd/root.go Execute(), after cfg.InitCliConfig, we must call both toolchainCmd.SetAtmosConfig(&atmosConfig) and toolchain.SetAtmosConfig(&atmosConfig) so the CLI wrapper and the toolchain package receive configuration; missing either can cause nil-pointer panics in toolchain path resolution.

Applied to files:

  • cmd/list/utils.go
  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
  • cmd/list/stacks.go
📚 Learning: 2024-12-02T21:26:32.337Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: pkg/config/config.go:478-483
Timestamp: 2024-12-02T21:26:32.337Z
Learning: In the 'atmos' project, when reviewing Go code like `pkg/config/config.go`, avoid suggesting file size checks after downloading remote configs if such checks aren't implemented elsewhere in the codebase.

Applied to files:

  • cmd/list/utils.go
📚 Learning: 2025-08-16T23:32:40.412Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:455-456
Timestamp: 2025-08-16T23:32:40.412Z
Learning: In the cloudposse/atmos Go codebase, `InitCliConfig` returns a `schema.AtmosConfiguration` value (not a pointer), while `ExecuteDescribeDependents` expects a `*schema.AtmosConfiguration` pointer parameter. Therefore, when passing the result of `InitCliConfig` to `ExecuteDescribeDependents`, use `&atmosConfig` to pass the address of the value.

Applied to files:

  • cmd/list/utils.go
📚 Learning: 2024-12-11T18:46:02.483Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/terraform.go:39-39
Timestamp: 2024-12-11T18:46:02.483Z
Learning: `cliConfig` is initialized in `cmd/root.go` and can be used across the `cmd` package.

Applied to files:

  • cmd/list/utils.go
📚 Learning: 2025-12-13T06:10:19.505Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: internal/exec/workflow_utils.go:0-0
Timestamp: 2025-12-13T06:10:19.505Z
Learning: Atmos workflows: In internal/exec/workflow_utils.go ExecuteWorkflow, non-identity steps intentionally use baseWorkflowEnv, which is constructed from the parent environment with PATH modifications for the toolchain. Avoid appending os.Environ() again; prefer documenting this behavior and testing that standard environment variables are preserved.

Applied to files:

  • cmd/list/workflows.go
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.

Applied to files:

  • cmd/list/workflows.go
📚 Learning: 2025-09-29T15:47:10.908Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1540
File: internal/exec/terraform_cli_args_utils.go:64-73
Timestamp: 2025-09-29T15:47:10.908Z
Learning: In the Atmos codebase, viper.BindEnv is required for CLI commands in the cmd/ package, but internal utilities can use os.Getenv directly when parsing environment variables for business logic purposes. The requirement to use viper is specific to the CLI interface layer, not all environment variable access throughout the codebase.

Applied to files:

  • cmd/list/metadata.go
  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/vendor.go
  • cmd/list/instances.go
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to cmd/*/*.go : Flag handling: Commands MUST use `flags.NewStandardParser()` for command-specific flags. NEVER call `viper.BindEnv()` or `viper.BindPFlag()` directly (enforced by Forbidigo linter)

Applied to files:

  • cmd/list/settings.go
  • cmd/list/values.go
  • cmd/list/instances.go
📚 Learning: 2024-11-13T21:37:07.852Z
Learnt from: Cerebrovinny
Repo: cloudposse/atmos PR: 764
File: internal/exec/describe_stacks.go:289-295
Timestamp: 2024-11-13T21:37:07.852Z
Learning: In the `internal/exec/describe_stacks.go` file of the `atmos` project written in Go, avoid extracting the stack name handling logic into a helper function within the `ExecuteDescribeStacks` method, even if the logic appears duplicated.

Applied to files:

  • cmd/list/stacks.go
🧬 Code graph analysis (1)
cmd/list/utils.go (3)
pkg/flags/global_registry.go (1)
  • ParseGlobalFlags (33-77)
pkg/config/config.go (1)
  • InitCliConfig (28-67)
pkg/schema/schema.go (2)
  • ConfigAndStacksInfo (646-742)
  • AtmosConfiguration (53-96)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
🔇 Additional comments (12)
cmd/list/values.go (1)

77-88: LGTM: Consistent Viper-based precedence pattern.

The shared Viper instance approach ensures flag/env precedence is honored throughout the RunE flow. This aligns with the StandardParser pattern used across list commands.

cmd/list/components.go (1)

48-59: LGTM: Proper Viper instance management.

The shared Viper instance for both config checks and flag binding ensures consistent precedence. The downstream call to e.ProcessCommandLineArgs (line 172) before config.InitCliConfig correctly populates the ConfigAndStacksInfo struct, honoring global config flags.

cmd/list/metadata.go (1)

39-50: LGTM: Consistent flag/env precedence handling.

The Viper-based flow correctly honors config selection flags. The call to e.ProcessCommandLineArgs (line 118) before cfg.InitCliConfig ensures global flags are properly propagated.

cmd/list/stacks.go (1)

49-60: LGTM: Proper Viper integration.

The shared Viper instance pattern is correctly implemented. The downstream e.ProcessCommandLineArgs call (line 178) ensures config flags are respected when initializing the CLI config.

cmd/list/vendor.go (1)

45-56: LGTM: Viper-based precedence with appropriate validation skip.

The shared Viper instance correctly centralizes flag/env handling. Skipping stack validation for the vendor command makes sense since vendor configs don't require stack context.

cmd/list/workflows.go (1)

41-52: LGTM: Correct Viper and config initialization pattern.

The shared Viper instance ensures consistent precedence, and the call to e.ProcessCommandLineArgs (line 118) properly populates the ConfigAndStacksInfo before config initialization.

cmd/list/instances.go (1)

43-54: LGTM: Proper Viper-based precedence flow.

The shared Viper instance and downstream e.ProcessCommandLineArgs call (line 137) ensure config selection flags are honored correctly.

cmd/list/settings.go (1)

46-57: LGTM: Consistent Viper threading through command flow.

The Viper instance is properly obtained and passed through to downstream functions. The initConfigAndAuth call (line 131) should ensure config flags are honored, though the implementation isn't visible in this file.

cmd/list/utils.go (4)

16-16: Import addition looks good.

The global package import is correctly placed in the Atmos packages group and is needed for the new flag parsing pattern.


28-33: Correct implementation of global flag parsing pattern.

The changes properly honor config selection flags by parsing global flags and building ConfigAndStacksInfo before calling InitCliConfig. This follows the established pattern from the reference implementation.


51-64: Clean helper function for ConfigAndStacksInfo construction.

The nil check provides good defensive programming, and the field mapping correctly translates global flags into the ConfigAndStacksInfo struct that InitCliConfig expects.


226-230: Consistent flag parsing pattern.

The initConfigAndAuth function correctly mirrors the pattern used in checkAtmosConfig, ensuring consistent handling of global flags across list commands.

Change the description from "Execute on components filtered by a YQ
expression" to "Execute atmos terraform command on components filtered
by a YQ expression" to clarify what is being executed.

Regenerated affected golden snapshots.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 15, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
website/docs/cli/commands/terraform/terraform-shell.mdx (1)

195-199: Use em dashes for improved typography in list descriptions.

Consider replacing the hyphens with em dashes (—) in the Related Commands section to better join the command link with its description. This aligns with typographical best practices for documentation.

## Related Commands

- [terraform plan](/cli/commands/terraform/plan) — Generate an execution plan
- [terraform apply](/cli/commands/terraform/apply) — Apply changes to infrastructure
- [terraform init](/cli/commands/terraform/init) — Initialize a Terraform working directory
website/docs/cli/commands/terraform/terraform-workspace.mdx (1)

171-175: Optional: Use em-dashes in related commands list for style consistency.

LanguageTool suggests using em-dashes () instead of hyphens (-) when joining two independent clauses or introducing descriptive elements. This is a minor style refinement that can improve readability if adopted across the documentation consistently.

Apply this diff if adopting em-dash style:

-
-## Related Commands
-
-- [terraform init](/cli/commands/terraform/init) - Initialize a Terraform working directory
-- [terraform plan](/cli/commands/terraform/plan) - Generate an execution plan
-- [terraform shell](/cli/commands/terraform/shell) - Start a shell in the component's context
+
+## Related Commands
+
+- [terraform init](/cli/commands/terraform/init) — Initialize a Terraform working directory
+- [terraform plan](/cli/commands/terraform/plan) — Generate an execution plan
+- [terraform shell](/cli/commands/terraform/shell) — Start a shell in the component's context
website/docs/cli/commands/terraform/terraform-clean.mdx (2)

69-72: Clarify the component behavior description.

The phrase "along with --force" is ambiguous—it could mean "without --force" or "with --force". Based on the warning section (line 26), the intended behavior is: when component is not specified, all components are cleaned, and confirmation is prompted unless --force is used.

Consider this clearer wording:

-    Atmos terraform component. If not specified along with `--force`, cleans all components.
+    Atmos terraform component. If not specified, cleans all components. Without `--force`, prompts for confirmation before proceeding.

92-99: Clarify --everything behavior when no component specified.

The description says "for the component" (singular), but since the component argument is now optional, it should clarify what happens when --everything is used without specifying a component.

Consider updating the description:

-        If set, Atmos will also delete the Terraform state files and directories for the component (the `terraform.tfstate.d` directory).
+        If set, Atmos will also delete the Terraform state files and directories (the `terraform.tfstate.d` directory). When no component is specified, applies to all components.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 399f135 and b046a5d.

📒 Files selected for processing (9)
  • cmd/terraform/terraform.go (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_terraform_-help_passthrough.stdout.golden (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_terraform_-version_passthrough.stdout.golden (1 hunks)
  • website/docs/cli/commands/terraform/terraform-clean.mdx (2 hunks)
  • website/docs/cli/commands/terraform/terraform-deploy.mdx (1 hunks)
  • website/docs/cli/commands/terraform/terraform-destroy.mdx (1 hunks)
  • website/docs/cli/commands/terraform/terraform-output.mdx (1 hunks)
  • website/docs/cli/commands/terraform/terraform-shell.mdx (1 hunks)
  • website/docs/cli/commands/terraform/terraform-workspace.mdx (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • website/docs/cli/commands/terraform/terraform-destroy.mdx
  • website/docs/cli/commands/terraform/terraform-output.mdx
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/snapshots/TestCLICommands_atmos_terraform_-help_passthrough.stdout.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_-version_passthrough.stdout.golden
  • cmd/terraform/terraform.go
🧰 Additional context used
📓 Path-based instructions (2)
website/**

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

website/**: Update website documentation in the website/ directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in the website/ directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Files:

  • website/docs/cli/commands/terraform/terraform-deploy.mdx
  • website/docs/cli/commands/terraform/terraform-clean.mdx
  • website/docs/cli/commands/terraform/terraform-shell.mdx
  • website/docs/cli/commands/terraform/terraform-workspace.mdx
website/docs/cli/commands/**/*.mdx

📄 CodeRabbit inference engine (CLAUDE.md)

Documentation requirements: CLI command docs MUST include: 1) Frontmatter (title, sidebar_label, sidebar_class_name, id, description), 2) Intro component, 3) Screengrab, 4) Usage section with shell code block, 5) Arguments/Flags using <dl><dt> and <dd>, 6) Examples section. File location: website/docs/cli/commands/<command>/<subcommand>.mdx

Files:

  • website/docs/cli/commands/terraform/terraform-deploy.mdx
  • website/docs/cli/commands/terraform/terraform-clean.mdx
  • website/docs/cli/commands/terraform/terraform-shell.mdx
  • website/docs/cli/commands/terraform/terraform-workspace.mdx
🧠 Learnings (19)
📓 Common learnings
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Adding new CLI command: 1) Create `cmd/[command]/` with CommandProvider interface, 2) Add blank import to `cmd/root.go`: `_ "github.com/cloudposse/atmos/cmd/mycommand"`, 3) Implement in `internal/exec/mycommand.go`, 4) Add tests in `cmd/mycommand/mycommand_test.go`, 5) Create Docusaurus docs in `website/docs/cli/commands/<command>/<subcommand>.mdx`, 6) Build website: `cd website && npm run build`. See `docs/developing-atmos-commands.md` and `docs/prd/command-registry-pattern.md`
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: docs/prd/tool-dependencies-integration.md:58-64
Timestamp: 2025-12-13T06:07:34.794Z
Learning: cloudposse/atmos: For PRD docs (docs/prd/*.md), markdownlint issues like MD040/MD010/MD034 can be handled in a separate documentation cleanup commit and should not block the current PR.
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: errors/errors.go:184-203
Timestamp: 2025-12-13T06:10:06.715Z
Learning: cloudposse/atmos: For toolchain work, duplicate/unused error sentinels in errors/errors.go should be cleaned up in a separate refactor PR and not block feature PRs; canonical toolchain sentinels live under toolchain/registry with re-exports in toolchain/errors.go.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Registry pattern: Use registry pattern for extensibility and plugin-like architecture. New commands MUST use command registry pattern. See docs/prd/command-registry-pattern.md
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under `cmd/` directory
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: cmd/terraform.go:111-117
Timestamp: 2025-06-23T02:14:30.937Z
Learning: In cmd/terraform.go, flags for the DescribeAffected function are added dynamically at runtime when info.Affected is true. This is intentional to avoid exposing internal flags like "file", "format", "verbose", "include-spacelift-admin-stacks", "include-settings", and "upload" in the terraform command interface, while still providing them for the shared DescribeAffected function used by both `atmos describe affected` and `atmos terraform apply --affected`.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Package organization philosophy: Prefer `pkg/` over `internal/exec/` or new `internal/` packages. Create focused packages in `pkg/` for each new feature/domain. Commands are thin wrappers in `cmd/` with only CLI concerns. Business logic lives in `pkg/`
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to internal/exec/template_funcs.go : Template functions: Implement in `internal/exec/template_funcs.go`, register, test, document. Available: `atmos.Component/Stack/Setting()`, `terraform.output/state()`, `store.get()`, `exec()`, `env()`
📚 Learning: 2025-06-23T02:14:30.937Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: cmd/terraform.go:111-117
Timestamp: 2025-06-23T02:14:30.937Z
Learning: In cmd/terraform.go, flags for the DescribeAffected function are added dynamically at runtime when info.Affected is true. This is intentional to avoid exposing internal flags like "file", "format", "verbose", "include-spacelift-admin-stacks", "include-settings", and "upload" in the terraform command interface, while still providing them for the shared DescribeAffected function used by both `atmos describe affected` and `atmos terraform apply --affected`.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-deploy.mdx
  • website/docs/cli/commands/terraform/terraform-clean.mdx
📚 Learning: 2025-10-10T23:51:36.597Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-deploy.mdx
📚 Learning: 2025-10-07T00:25:16.333Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-deploy.mdx
  • website/docs/cli/commands/terraform/terraform-clean.mdx
📚 Learning: 2024-12-03T03:49:30.395Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: website/docs/core-concepts/stacks/yaml-functions/terraform.output.mdx:104-110
Timestamp: 2024-12-03T03:49:30.395Z
Learning: In the documentation for `!terraform.output`, warnings about template variable availability are already covered in other sections, so no need to suggest adding them here.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-deploy.mdx
📚 Learning: 2025-09-05T14:57:37.360Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 1448
File: cmd/ansible.go:26-28
Timestamp: 2025-09-05T14:57:37.360Z
Learning: The Atmos codebase uses a consistent pattern for commands that delegate to external tools: `PersistentFlags().Bool("", false, doubleDashHint)` where doubleDashHint provides help text about using double dashes to separate Atmos options from native command arguments. This pattern is used across terraform, packer, helmfile, atlantis, aws, and ansible commands.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-deploy.mdx
  • website/docs/cli/commands/terraform/terraform-clean.mdx
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-deploy.mdx
📚 Learning: 2024-12-01T00:33:20.298Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml:28-32
Timestamp: 2024-12-01T00:33:20.298Z
Learning: In `examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml`, `!exec atmos terraform output` is used in examples to demonstrate its usage, even though `!terraform.output` is the recommended approach according to the documentation.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-deploy.mdx
📚 Learning: 2025-12-13T03:21:27.620Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1813
File: cmd/terraform/shell.go:28-73
Timestamp: 2025-12-13T03:21:27.620Z
Learning: In Atmos, when calling cfg.InitCliConfig, you must first populate the schema.ConfigAndStacksInfo struct with global flag values using flags.ParseGlobalFlags(cmd, v) rather than passing an empty struct. The LoadConfig function (pkg/config/load.go) reads config selection fields (AtmosConfigFilesFromArg, AtmosConfigDirsFromArg, BasePath, ProfilesFromArg) directly from the ConfigAndStacksInfo struct, NOT from Viper. Passing an empty struct causes config selection flags (--base-path, --config, --config-path, --profile) to be silently ignored. Correct pattern: parse flags → populate struct → call InitCliConfig. See cmd/terraform/plan_diff.go for reference implementation.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-deploy.mdx
📚 Learning: 2024-10-21T17:51:53.976Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform.go:114-118
Timestamp: 2024-10-21T17:51:53.976Z
Learning: When `atmos terraform clean --everything` is used without specifying a component and without the `--force` flag, prompt the user for confirmation before deleting all components. Use the `--force` flag to skip the confirmation prompt.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-deploy.mdx
  • website/docs/cli/commands/terraform/terraform-clean.mdx
📚 Learning: 2025-01-19T15:49:15.593Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 955
File: tests/snapshots/TestCLICommands_atmos_validate_editorconfig_--help.stdout.golden:0-0
Timestamp: 2025-01-19T15:49:15.593Z
Learning: In future commits, the help text for Atmos CLI commands should be limited to only show component and stack parameters for commands that actually use them. This applies to the example usage section in command help text.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-deploy.mdx
  • website/docs/cli/commands/terraform/terraform-clean.mdx
📚 Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-deploy.mdx
📚 Learning: 2024-12-03T04:01:16.446Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: website/docs/core-concepts/stacks/yaml-functions/terraform.output.mdx:0-0
Timestamp: 2024-12-03T04:01:16.446Z
Learning: In the `terraform.output.mdx` documentation file (`website/docs/core-concepts/stacks/yaml-functions/terraform.output.mdx`), the cache invalidation and cache scope behavior for the `!terraform.output` function are already described.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-clean.mdx
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to website/docs/cli/commands/**/*.mdx : Documentation requirements: CLI command docs MUST include: 1) Frontmatter (title, sidebar_label, sidebar_class_name, id, description), 2) Intro component, 3) Screengrab, 4) Usage section with shell code block, 5) Arguments/Flags using `<dl><dt>` and `<dd>`, 6) Examples section. File location: `website/docs/cli/commands/<command>/<subcommand>.mdx`

Applied to files:

  • website/docs/cli/commands/terraform/terraform-clean.mdx
  • website/docs/cli/commands/terraform/terraform-shell.mdx
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Documentation (MANDATORY): All cmds/flags need Docusaurus docs in `website/docs/cli/commands/`. Use `<dl>` for args/flags. Build: `cd website && npm run build`. Verify links by finding doc file, checking slug in frontmatter, verifying existing links. Never use command name vs. filename or guess URLs

Applied to files:

  • website/docs/cli/commands/terraform/terraform-clean.mdx
📚 Learning: 2025-01-09T22:27:25.538Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/validate_stacks.go:20-23
Timestamp: 2025-01-09T22:27:25.538Z
Learning: The validate commands in Atmos can have different help handling implementations. Specifically, validate_component.go and validate_stacks.go are designed to handle help requests differently, with validate_stacks.go including positional argument checks while validate_component.go does not.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-clean.mdx
📚 Learning: 2024-10-21T17:51:07.087Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform.go:114-118
Timestamp: 2024-10-21T17:51:07.087Z
Learning: Use `bubbletea` for confirmation prompts instead of `fmt.Scanln` in the `atmos terraform clean` command.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-clean.mdx
📚 Learning: 2024-11-02T15:35:09.958Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 759
File: internal/exec/terraform.go:366-368
Timestamp: 2024-11-02T15:35:09.958Z
Learning: In `internal/exec/terraform.go`, the workspace cleaning code under both the general execution path and within the `case "init":` block is intentionally duplicated because the code execution paths are different. The `.terraform/environment` file should be deleted before executing `terraform init` in both scenarios to ensure a clean state.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-clean.mdx
  • website/docs/cli/commands/terraform/terraform-workspace.mdx
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to README.md : Update README.md with new commands and features

Applied to files:

  • website/docs/cli/commands/terraform/terraform-shell.mdx
🪛 LanguageTool
website/docs/cli/commands/terraform/terraform-deploy.mdx

[typographical] ~199-~199: To join two clauses or introduce examples, consider using an em dash.
Context: ...form plan](/cli/commands/terraform/plan) - Generate an execution plan - [terraform ...

(DASH_RULE)


[typographical] ~200-~200: To join two clauses or introduce examples, consider using an em dash.
Context: ...rm apply](/cli/commands/terraform/apply) - Apply changes with confirmation - [terra...

(DASH_RULE)


[typographical] ~201-~201: To join two clauses or introduce examples, consider using an em dash.
Context: ...estroy](/cli/commands/terraform/destroy) - Destroy infrastructure

(DASH_RULE)

website/docs/cli/commands/terraform/terraform-clean.mdx

[typographical] ~118-~118: To join two clauses or introduce examples, consider using an em dash.
Context: ...form init](/cli/commands/terraform/init) - Initialize a Terraform working directory...

(DASH_RULE)


[typographical] ~119-~119: To join two clauses or introduce examples, consider using an em dash.
Context: ...form plan](/cli/commands/terraform/plan) - Generate an execution plan - [terraform ...

(DASH_RULE)


[typographical] ~120-~120: To join two clauses or introduce examples, consider using an em dash.
Context: ...rm apply](/cli/commands/terraform/apply) - Apply changes to infrastructure

(DASH_RULE)

website/docs/cli/commands/terraform/terraform-shell.mdx

[typographical] ~197-~197: To join two clauses or introduce examples, consider using an em dash.
Context: ...form plan](/cli/commands/terraform/plan) - Generate an execution plan - [terraform ...

(DASH_RULE)


[typographical] ~198-~198: To join two clauses or introduce examples, consider using an em dash.
Context: ...rm apply](/cli/commands/terraform/apply) - Apply changes to infrastructure - [terra...

(DASH_RULE)


[typographical] ~199-~199: To join two clauses or introduce examples, consider using an em dash.
Context: ...form init](/cli/commands/terraform/init) - Initialize a Terraform working directory...

(DASH_RULE)

website/docs/cli/commands/terraform/terraform-workspace.mdx

[typographical] ~173-~173: To join two clauses or introduce examples, consider using an em dash.
Context: ...form init](/cli/commands/terraform/init) - Initialize a Terraform working directory...

(DASH_RULE)


[typographical] ~174-~174: To join two clauses or introduce examples, consider using an em dash.
Context: ...form plan](/cli/commands/terraform/plan) - Generate an execution plan - [terraform ...

(DASH_RULE)


[typographical] ~175-~175: To join two clauses or introduce examples, consider using an em dash.
Context: ...rm shell](/cli/commands/terraform/shell) - Start a shell in the component's context...

(DASH_RULE)

⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (30)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
🔇 Additional comments (7)
website/docs/cli/commands/terraform/terraform-workspace.mdx (1)

1-169: Documentation structure meets all requirements.

The file comprehensively covers the terraform workspace command with proper frontmatter, intro, screengrab, usage examples, argument/flag definitions, and a configuration section. The format follows the established documentation pattern.

website/docs/cli/commands/terraform/terraform-deploy.mdx (2)

189-195: Nice documentation clarity improvement.

Converting this to an explicit section heading makes the native Terraform flags discussion more discoverable and easier to scan. The guidance on planfile handling is clear and properly cross-references the comprehensive guide.


197-201: Good addition for discoverability.

The Related Commands section helps users navigate between complementary terraform commands. The static analysis warnings about em dashes are false positives—the hyphens are correct markdown list syntax.

website/docs/cli/commands/terraform/terraform-clean.mdx (4)

78-80: LGTM!

Making the stack flag optional with the clear requirement that it's needed when targeting a specific component is logically consistent with the new component-optional behavior.


83-90: LGTM!

The expanded --dry-run description is clear, and the example correctly demonstrates the flag usage without requiring an explicit =true value.


101-108: LGTM!

The --force flag documentation is clear and correctly describes the confirmation-skipping behavior that aligns with the warning section.


116-120: Nice addition with the Related Commands section.

The cross-references to related Terraform commands improve discoverability and follow standard documentation patterns.

Note: The static analysis hints about em dashes (DASH_RULE) are false positives—the hyphen syntax used here is standard for Markdown lists and documentation.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 16, 2025
Add sanitization and diff patterns to handle terraform version variations:
- Normalize download URL (terraform.io vs developer.hashicorp.com)
- Filter out version-specific subcommands (modules, stacks) only in newer versions

These changes ensure passthrough tests work across different terraform versions
installed in CI environments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 16, 2025
Add sanitize pattern to handle minor punctuation variation in terraform help:
"output, or the help" vs "output or the help"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions
Copy link

These changes were released in v1.202.0-rc.4.

@github-actions
Copy link

These changes were released in v1.203.0-test.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor New features that do not break anything size/xl Extra large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants