refactor: Migrate terraform commands to registry pattern#1813
Conversation
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughSplit 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 ( Changes
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (10)
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. Comment |
|
Warning CLAUDE.md Too LargeThe modified CLAUDE.md exceeds the 40000 byte size limit:
Action needed: Please refactor the oversized CLAUDE.md file. Consider:
All MANDATORY requirements must be preserved. |
|
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. |
Dependency Review✅ No vulnerabilities or license issues found.Scanned FilesNone |
e81df0a to
d0dddec
Compare
There was a problem hiding this comment.
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/1813Or 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 environmentsinternal/exec/terraform.go (1)
549-557:os.Stdin == nildoesn’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.Stdinis typically a non‑nil*os.Fileeven when it isn’t a TTY (e.g., in CI or when piped).Given the prior guidance to use stdin TTY detection helpers for
applyinteractivity 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-approvewill reliably get the intendedErrNoTtyinstead 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
HandleCleanSubCommanddecides whether to collect stack‑scoped state folders via:if info.Component != "" && info.Stack != "" { stackFolders, err := getStackTerraformStateFolder(cleanPath, info.Stack) ... }However,
ExecuteCleanonly setsComponentFromArgand never setsinfo.Component, so for calls like:ExecuteClean("my-component", "my-stack", force, everything, skipLockFile, atmosConfig)this condition will be false and
terraform.tfstate.dcontents 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
ComponentalongsideComponentFromArgwhen buildinginfo: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
Componentbefore callingHandleCleanSubCommand.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--heatmapflag present. However, the assertionassert.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 aligningformatvalidation and CSV parsing with the underlying helperThe main flow here looks good, but there are a couple of small polish points you might want to consider:
ExecuteTerraformGenerateVarfilessupportsyaml/json/hclper the internal exec helper, while the CLI validation only allowsjsonorhcl. Either exposingyamlhere or updating the helper to match would avoid a silent capability mismatch.- When splitting
stacksCsv/componentsCsvyou currently do a plainstrings.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 punctuationThe PRD reads clearly, but if you want it completely clean against tooling:
- Code blocks currently use hard tabs, which triggers
markdownlintMD010; 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: AlignUsestring with optional component argumentThe implementation correctly treats the component as optional (
MaximumNArgs(1)and the comment “if empty, cleans all components”), butUse: "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 cleanwithout a component is supported. The rest of the flag parsing and delegation toExecuteCleanlooks solid.Also applies to: 72-96
cmd/terraform/generate/varfile.go (1)
44-45: Double‑check--stackrequired semantics vsATMOS_STACKYou both (a) mark
stackas required on the Cobra command and (b) bind it toATMOS_STACKviaWithEnvVarsand then validatestack == ""from Viper.With Cobra’s required‑flag behavior, a missing
--stackwill fail beforeRunEexecutes, even ifATMOS_STACKis set. If you intend to support “env‑only” usage (stack fromATMOS_STACKwithout explicitly passing--stack), consider relying solely on the Viper‑basedstack == ""check and droppingMarkFlagRequired, 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 toExecuteTerraformGenerateBackendswith the expected arguments. If you ever see users passing spaces in CSV lists ("stack1, stack2"), you might later consider trimming entries afterstrings.Split, but that’s a nicety, not a blocker.cmd/terraform/terraform.go (1)
16-51: Baseterraformcommand + registry provider look consistentUsing
StandardParserwithWithTerraformFlagsandWithTerraformAffectedFlags, registering persistent flags once, and binding them to Viper in init is in line with the shared pattern. Attachinggenerate.GenerateCmd, wiring completions, and registeringTerraformCommandProviderall look correct.Minor nit:
GetAliasesreturnsnilwhile the Cobra command hasAliases: []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--origmust be a flag or can come from envYou bind
origtoATMOS_TERRAFORM_PLAN_DIFF_ORIGviaWithEnvVars, 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
RunEif--origisn’t present, even when the env var is set, soATMOS_TERRAFORM_PLAN_DIFF_ORIGalone won’t satisfy the requirement.If you want env‑only usage to work, you can rely on the Viper‑based
orig == ""check and dropMarkPersistentFlagRequired. If you want to force the explicit--origflag 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: NewTerraformAffectedFlagsregistry is straightforward; watch for flag-role overlap
TerraformAffectedFlagscleanly encapsulates the affected‑component detection flags and keeps them separate from the core Terraform flag set, which works well with the combinedWithTerraformFlags+WithTerraformAffectedFlagspattern.One thing to keep an eye on long‑term: comments earlier in this file note that
identityalready exists inGlobalFlagsRegistry(), and you now also define a Terraform‑specificidentityflag inTerraformFlags. 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 populateCliArgsfor telemetry.Function behavior looks solid, but a couple of small consistency nits:
perf.Tracklabel and the debug message still use"ExecuteShell"while the function isExecuteTerraformShell. For perf dashboards and log grepability, it’s clearer if these match the function name.- Other new exec entrypoints (e.g., planfile) set
info.CliArgsbefore callingProcessStacks; 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 threadingatmosConfigthrough or dropping it from this API.
ExecuteGeneratePlanfilecurrently acceptsatmosConfigbut only uses it forperf.Track, whileExecuteTerraformGeneratePlanfilestill callscfg.InitCliConfiginternally and ignores the caller’s config.That’s functionally safe, but slightly confusing for callers who might expect their pre-initialized
atmosConfigto be honored. Two possible cleanups:
- Either change
ExecuteTerraformGeneratePlanfileto accept an*schema.AtmosConfigurationand reuse the passed-in config instead of reinitializing, or- If you want
ExecuteTerraformGeneratePlanfileto remain self-contained, drop theatmosConfigparameter fromExecuteGeneratePlanfileand callperf.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‑firstProcessStacksflow looks good; explicit empty‑stack check is probably redundant.Routing through
ExecuteDescribeComponentfirst, then creatingauthManagerand passing it intoProcessStacksis 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
checkStackhard‑coded totrue,ProcessStacksitself will already returnErrMissingStackwhen 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 explicitlen(info.Stack)check.cmd/terraform/varfile.go (1)
72-85: Confirm CobraUsestring matches the intendedterraform write varfileCLIWith
Use: "write varfile <component>", Cobra will treat the command name aswrite, andvarfilebecomes part of the usage text, not a separate subcommand token. If the legacy UX truly expectsatmos terraform write varfile <component>, that path may not exist as a distinct subcommand anymore andvarfilewould instead be parsed as an argument.Consider either:
- Modeling
writeas a parent command with avarfilesubcommand, 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 --helpto ensure behavior matches expectations.cmd/cmd_utils.go (1)
785-871: Stack completion behavior is sensible; consider minor polish onlyThe new
StackFlagCompletion+listStacksForComponent/listStackshelpers 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
toCompleteto trim the suggestion set when shells don’t pre-filter aggressively.- DRY up
listStacksForComponent/listStacksby sharing the commonInitCliConfig+ExecuteDescribeStacksblock.Functionally, this looks good as-is.
cmd/terraform/utils.go (2)
295-306: Use Cobra’s output writer instead offmt.PrintinsetCustomHelpRight 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 redirectcmd.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 thetoCompleteprefixBoth
componentsArgCompletionandstackFlagCompletionreturn full lists without filtering ontoComplete. 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 mapsA few of the description sets don’t currently cover all flags declared in
cmd/terraform/compat_flags.go:
ValidateCompatFlagDescriptionsomits-no-testsand-test-directory, which are present inValidateCompatFlags.RefreshCompatFlagDescriptionsreturns onlyTerraformCompatFlagDescriptions, so it never documents-backup,-state, or-state-outfromRefreshCompatFlags.StateCompatFlagDescriptionsdoesn’t mention-state-outfromStateCompatFlags.ImportCompatFlagDescriptionsdoesn’t include-state/-state-out, which are inImportCompatFlags.GetCompatFlagDescriptionsomits-test-directoryfromGetCompatFlags.TestCompatFlagDescriptionsomits-varand-var-filefromTestCompatFlags.For a future pass, it’d be good to align these so the help output fully reflects what the compatibility layer actually passes through.
There was a problem hiding this comment.
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--identityflag 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: Clarifyviper.BindEnvguidance 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 “Useviper.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/bindEnvinpkg/config/load.go) instead of directviper.BindEnvin random call sites.That should make it clearer where direct
BindEnvis allowed and where it is not.Also applies to: 272-274
cmd/terraform/utils.go (4)
36-60: Confirm which command is passed intorunHookssoProcessCommandLineArgssees the right argv
finalArgsis built as[]string{cmd_.Name()} + argsand then handed toProcessCommandLineArgs("terraform", cmd_, finalArgs, argsAfterDoubleDash). That’s correct only ifcmd_represents the terraform parent command andargsstart with the subcommand name; ifcmd_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 ofcmd_.Name()here.
63-93: Ensure pass‑through (Terraform/OpenTofu) flags wired viaparsedConfig.SeparatedArgs
terraformRuncorrectly usesAtmosFlagParserto 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
ProcessCommandLineArgsrelies on itsadditionalArgsAndFlagsparameter to populateinfo.AdditionalArgsAndFlags(as in the older terraform flow), pass‑through flags like-var,-target, etc. may never reachExecuteTerraform*.Consider threading
SeparatedArgsthrough:- info, err := e.ProcessCommandLineArgs(cfg.TerraformComponentType, parentCmd, argsWithSubCommand, nil) + info, err := e.ProcessCommandLineArgs( + cfg.TerraformComponentType, + parentCmd, + argsWithSubCommand, + parsedConfig.SeparatedArgs, + )If
AtmosFlagParser.Parsealready 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 offmt.PrintHooking
cmd.SetHelpFuncand appending the compatibility flags block viaFormatCompatFlagsHelpis 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, andlistAllStacks:
- Reuse
InitCliConfigandExecuteDescribeStacks.- 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: NewExecuteGenerateVarfileAPI looks correct and side‑effect freeThe new entrypoint:
- Constructs
ConfigAndStacksInfowithComponentFromArg,Stack,StackFromArg,ComponentType: "terraform", andCliArgs: []string{"terraform", "generate", "varfile"}.- Runs
ProcessStackswith the passedAtmosConfiguration, honoringprocessTemplates,processFunctions, andskip.- Derives the output path from
fileif provided, otherwise fromconstructTerraformComponentVarfilePath.- Respects
info.DryRunbefore writing JSON viau.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:FormatCompatFlagsHelpproduces clean, aligned help blocksThe 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
--helpoutput. Coupled with the optional tweak insetCustomHelpto write viaOutOrStdout, the UX is solid.cmd/auth_login.go (1)
82-86: CreateAuthManager export looks fine; just ensure it’s the single sourceThe exported
CreateAuthManagerwrapper cleanly exposes the existing initialization logic for reuse by other command packages without changing behavior, which is nice.Given the broader PR mentions
CreateAuthManagerincmd/cmd_utils.goas well, please double‑check that this function only exists in one place inpackage cmdto avoid duplicate definitions and to keep the public entrypoint obvious.pkg/flags/registry.go (1)
125-233: Align TerraformFlags with existing identity/from-plan usageNice to see Terraform‑specific flags centralized here; this should simplify future command wiring. A couple of things to sanity‑check:
Identity flag scope
TerraformFlags()now registers anidentityStringFlag with shorthand-iandNoOptDefVal="__SELECT__".- Earlier comments on
CommonFlags()mention that identity comes fromGlobalFlagsRegistry()and is not duplicated there.If a global identity flag still exists (e.g., via a global registry on the root command), registering
identityagain 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.
from-planconsistency with deploy
- Here,
from-planis a string flag intended to hold a plan file path.- In
cmd/terraform/deploy.go,deployCmdcurrently defines a boolfrom-planflag.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 forfrom-planacross 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) butCheckErrorPrintAndExit()for MarkPersistentFlagRequired errors (line 107). Since both are static init-time configurations, consider usingpanic()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: Confirmstackrequired semantics with env vars + StandardParserYou’re wiring
stackboth as a flag (and marking it required) and as an env-bound value viaATMOS_STACK, then validatingstack == ""via Viper. Depending on howStandardParserand Cobra interact,MarkFlagRequired("stack")may still reject invocations that rely solely onATMOS_STACKbefore 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 (droppingMarkFlagRequired), or- Keep
MarkFlagRequiredbut 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 revisitingATMOS_FORMATreuse for this commandTwo small points:
The
stacksandcomponentsCSVs are split withstrings.Splitonly. Inputs like--stacks foo, barwill include a leading space in" bar". Trimming would make the CLI a bit more forgiving.The
formatflag is wired toATMOS_FORMATviaflags.WithEnvVars("format", "ATMOS_FORMAT")but only acceptshcl,json, andbackend-config. If users already setATMOS_FORMAT=yamlfor 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: AlignUsestring with optional component argumentThe implementation treats
componentas optional (cobra.MaximumNArgs(1)and comment “if empty, cleans all components”), but the usage string isclean <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 componentThe new completion path looks solid overall and the error handling is appropriately conservative, but there are two things worth double‑checking:
Assumption about
args[0]
StackFlagCompletiontreatsargs[0]as a component selector for every command that callsAddStackCompletion. If any caller usesAddStackCompletionwhere the first positional argument is not a component, stack completion will silently return an empty or misleading set. Either:
- Confirm
AddStackCompletionis only used for commands whereargs[0]is indeed the component, or- Narrow this behavior (or document it) so callers understand the contract.
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 bytoCompleteinlistStacksForComponent/listStacksto 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 reuseAddStackCompletion.docs/prd/terraform-registry-migration.md (1)
1-353: PRD is clear and matches the staged implementationThe 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.
|
💥 This pull request now has conflicts. Could you fix it @osterman? 🙏 |
|
Warning Changelog Entry RequiredThis PR is labeled Action needed: Add a new blog post in Example filename: Alternatively: If this change doesn't require a changelog entry, remove the |
There was a problem hiding this comment.
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
finalArgsbefore extractingargsAfterDoubleDash, so the tail after--is never captured. This breaks hook processing when users pass--and pass-through args.Extract
argsAfterDoubleDashbefore truncatingfinalArgs: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 contentThe new header + error line look consistent, but the
## Explanationsection 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 toflags.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.
📒 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.gocmd/terraform/generate/varfile/varfile.gocmd/terraform/utils.gopkg/flags/flag_parser.gocmd/terraform/terraform.gocmd/cmd_utils.gointernal/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 undercmd/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.gocmd/terraform/generate/varfile/varfile.gocmd/terraform/utils.gocmd/terraform/terraform.gocmd/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.gocmd/terraform/utils.gotests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.goldenpkg/flags/flag_parser.gocmd/terraform/terraform.gocmd/cmd_utils.gotests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.goldeninternal/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.gocmd/terraform/utils.gotests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.goldencmd/terraform/terraform.gocmd/cmd_utils.gointernal/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.gocmd/terraform/utils.gocmd/terraform/terraform.gocmd/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.gocmd/terraform/utils.gopkg/flags/flag_parser.gocmd/terraform/terraform.gocmd/cmd_utils.gointernal/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.gopkg/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.gointernal/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.gopkg/flags/flag_parser.gocmd/terraform/terraform.gocmd/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.gotests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.goldentests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.goldentests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.goldenpkg/flags/flag_parser.gocmd/terraform/terraform.gotests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.goldentests/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.gopkg/flags/flag_parser.gocmd/terraform/terraform.gocmd/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.gopkg/flags/flag_parser.gointernal/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.gopkg/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.gopkg/flags/flag_parser.gointernal/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.gocmd/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.gotests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.goldenpkg/flags/flag_parser.gocmd/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.gotests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.goldentests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.goldentests/snapshots/TestCLICommands_atmos_workflow_failure_with_filepath.stderr.goldeninternal/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.gocmd/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.goldentests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.goldentests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.goldentests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.goldentests/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.goldentests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.goldentests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.goldentests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.goldentests/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.goldentests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.goldentests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.goldentests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.goldentests/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.goldentests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.goldentests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.goldentests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.goldentests/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.goldentests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.goldentests/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., `<component>`) rather than converted to backticks or other markdown formatting.
Applied to files:
tests/snapshots/TestCLICommands_atmos_workflow_failure.stderr.goldentests/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.goldentests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.goldentests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.goldenpkg/flags/flag_parser.gotests/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.goldentests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.goldentests/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.goldentests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.goldentests/snapshots/TestCLICommands_atmos_terraform_deploy_locked_component.stderr.goldentests/snapshots/TestCLICommands_atmos_terraform_plan_non-existent_in_non_workspace.stderr.goldentests/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.goldentests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.goldentests/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.goldentests/snapshots/TestCLICommands_atmos_workflow_failure_with_stack.stderr.goldentests/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.gocmd/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.gocmd/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.gocmd/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.gocmd/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.gocmd/terraform/terraform.gocmd/cmd_utils.gotests/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.gocmd/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.gointernal/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
There was a problem hiding this comment.
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.
📒 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.gopkg/flags/standard_parser.gopkg/flags/types.gopkg/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 thewebsite/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 thewebsite/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.gopkg/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.gopkg/flags/types.gopkg/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.gopkg/flags/types.gopkg/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.gopkg/flags/types.gopkg/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.gopkg/flags/types.gopkg/flags/registry.gotests/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.gowebsite/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.gowebsite/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.gowebsite/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.gowebsite/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.mdxtests/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
--stackto--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
stringFlagis 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
--affectedmode.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.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
cmd/terraform/utils.go (1)
25-36: Fix double-dash splitting inrunHooks(lost tail args / potential slice bug).Right now
finalArgsis truncated before you slice outargsAfterDoubleDash, so anything after--is never captured andlo.Slice(finalArgs, doubleDashIndex+1, len(finalArgs))can index past the end of the (already-shortened) slice.A safer pattern is to keep an
originalArgscopy, compute head/tail from that, then assignfinalArgsfrom 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--queryThe 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-varsas 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 sinceinfois initialized empty on line 209. At this point in execution,SubCommandwill 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: Prefert.Setenvoveros.Unsetenvfor test isolation.Using
os.Unsetenvdoesn't restore the original value after the test. Per project conventions, uset.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.Setenvfor environment variable setup/teardown.tests/cli_terraform_test.go (1)
29-32: Prefert.Setenvfor environment variable manipulation.Per project conventions, use
t.Setenv("")instead ofos.Unsetenvfor 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.Setenvfor 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
NoFileCompon errors and derive components/stacks fromExecuteDescribeStacks, which is nice for UX.Two small follow-ups you might consider (not blocking):
listTerraformComponents,listStacksForComponent, andlistAllStackscurrently wrap errors with genericfmt.Errorf("error ...: %w", err). If we have matching sentinels inerrors/(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.
There was a problem hiding this comment.
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-planflag semantics between root terraform and applyHere
--from-planlooks 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 stringwith 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: PotentialcleanPathdouble‑join for component‑only cleans impactsTF_DATA_DIRhandling.With the new
ExecuteClean:
- When
component != ""andstack == "",componentPathis already set tofilepath.Join(atmosConfig.TerraformDirAbsolutePath, terraformComponent)(whereterraformComponentis derived frominfo.Context.BaseComponentorcomponent).- In
HandleCleanSubCommand, the branchcleanPath := 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
cleanPathlike<terraform-dir>/<component>/<base-component>. For valid components whereContext.BaseComponentmatches the resolved component path, that effectively double‑joins the component.This only shows up when
TF_DATA_DIRis set:tfDataDirFolders, err = CollectDirectoryObjects(cleanPath, []string{tfDataDir}) ... if len(tfDataDirFolders) > 0 { tfDataDirFolder := tfDataDirFolders[0] handleTFDataDir(tfDataDirFolder.FullPath, relativePath) }Because
cleanPathpoints at the nested path,CollectDirectoryObjectswill not find the actualTF_DATA_DIRunder the real component root, soTF_DATA_DIRcleanup becomes a silent no‑op for component‑only cleans. Regular.terraformandterraform.tfstate.dcleanup is unaffected because those useCollectComponentsDirectoryObjectswithTerraformDirAbsolutePath.A small conditional tweak keeps the old behavior for callers that pass the terraform root, while avoiding the double‑join when
ExecuteCleanhas 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
elsebranch starting at Line 532,FilterComponentsis initialized and only populated underif info.ComponentFromArg != "", but that condition can never be true there (we are already in theelseofif info.ComponentFromArg != ""). You can safely drop that innerifand just passnilforFilterComponentstoExecuteDescribeStacksto 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
finalArgsbefore line 33 extractsargsAfterDoubleDash, 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 asatmos terraform helpThis 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--querydescription).
🧹 Nitpick comments (4)
internal/exec/cli_utils.go (1)
214-230: Single-argument handling forversion/cleanlooks solidThe
standaloneCommandsmap cleanly extends the previouscleanspecial-case to includeversion, while preserving the existing behavior for other single-argument commands (still settingSubCommand+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--querydescription
Execute atmos terraform on components...has a double space beforeon. If you care about polish, consider tightening the source help string so this snapshot reflows asterraform on.internal/exec/terraform_clean_test.go (1)
38-45: Optional: uset.Setenvfor 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.Setenvover directos.Unsetenv.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (5)
internal/exec/terraform_generate_planfile.go (1)
39-77: TheatmosConfigparameter doesn't control execution behavior.This matches a previously flagged issue:
ExecuteGeneratePlanfileacceptsatmosConfigbut constructs a freshConfigAndStacksInfoat lines 68-74 and delegates toExecuteTerraformGeneratePlanfile, which initializes its own config viaInitCliConfig(*info, true)at line 175. Your caller'satmosConfigis only used for perf tracking, then discarded.Consider either:
- Plumbing
atmosConfiginto the core implementation so callers can supply pre-initialized configs, or- Removing the parameter to clarify the API contract.
cmd/terraform/deploy.go (1)
32-41: Re‑check--from-planflag type/semantics against TerraformFlags registry.Here
deploydefines--from-planas a bool with its own env var, while the shared Terraform flag registry previously exposedfrom-planas a string plan‑file path on the parentterraformcommand. 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-planflag 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 callingGetDefaultIdentity.
CreateAndAuthenticateManagercan return(nil, nil)when auth is globally disabled; in that caseauthManager.GetDefaultIdentity(true)will panic. That can happen even when the user explicitly passes--identitybut 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-planbool vs string mismatch across Terraform commands.Apply is also defining
--from-planas a bool plus its own env var. If the shared Terraform flag registry still definesfrom-planas a string (plan file path) on the parentterraformcommand, you end up with the same flag name behaving differently depending on context, which is pretty confusing.Worth considering:
- Use a single string
--from-planflag everywhere (and treat “set but empty” as “use default plan file”), or- Rename this toggle (e.g.
--use-from-plan) and reserve--from-planfor 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 wheninfo.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 newExecuteGeneratePlanfileentry point.
TestExecuteTerraformGeneratePlanfiletests the core implementation directly, but the new public wrapperExecuteGeneratePlanfile(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 isExecuteTerraformShell. 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 inshellpath.Here you call
InitCliConfigwithprocessStacks=truebut pass an emptyConfigAndStacksInfo;ExecuteTerraformShellthen does its ownProcessStacksbased oncomponentandstack. You can likely setprocessStackstofalsehere (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" )
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
cmd/terraform/utils.go (1)
204-247: Guard against nil auth manager.
CreateAndAuthenticateManagercan return(nil, nil)when authentication is globally disabled, which would cause a panic at line 233 when callingauthManager.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.
📒 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.gopkg/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 undercmd/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.gopkg/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.gopkg/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.gopkg/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.gopkg/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.gopkg/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.gopkg/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.gopkg/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.ErrHelpallows the--helpflag to be processed by Cobra's help system in the normal execution flow, which is the correct approach. The use oferrors.Is()for error checking follows the coding guidelines.
256-268: The comment inadjustForCobraParsing(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:
What actually happens: Terraform commands call
extractSubcommandArgs()which parsesos.Argsdirectly (bypassing Cobra entirely), capturing all arguments including the--separator from the user's original command.Why the check is correct: The
adjustForCobraParsingcheck correctly skips adjustment forUnknownFlags=truebecause:
- 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
Fix the comment: Rewrite lines 255-259 to clarify that
UnknownFlags=truecommands are handled differently because they extract args directly fromos.Argsrather than receiving Cobra-parsed args, and therefore don't need theadjustForCobraParsinglogic.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
--heatmapflag 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.
There was a problem hiding this comment.
Actionable comments posted: 7
♻️ Duplicate comments (2)
cmd/terraform/version_cmd.go (1)
22-27: Skip component completions forterraform version.
RegisterTerraformCompletionsunconditionally wirescomponentsArgCompletionasValidArgsFunction, soterraform versionends 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 inProcessCommandLineArgs.I’d either:
- stop calling
RegisterTerraformCompletions(versionCmd_)here, or- teach
RegisterTerraformCompletionsto skip component completion for non-component commands likeversion(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.
CreateAndAuthenticateManageris allowed to return(nil, nil)when auth is globally disabled; in that caseauthManager.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,
CreateAndAuthenticateManagermay 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
outputcommand 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 anExamplefield showing at least one typical invocation (e.g.,atmos terraform output <component> -s <stack>and a--helpusage) 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.
GetCompatFlagsForCommandis a new public API used on the CLI hot path, but it doesn’t include the standardperf.Trackcall 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.Errorfcalls 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, theerrUtils.CheckErrorPrintAndExitpattern 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-planand--planfileflags haveWithEnvVarsbindings, but--affectedand--alldon'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 newerterraform testflags toTestCompatFlags.Current
TestCompatFlagscovers 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
AllTerraformCompatFlagsis used to decide which args are pass‑through vs. Atmos flags, omitting these meansatmos terraform testusers 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.)
There was a problem hiding this comment.
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:
All exported functions (TerraformCompatFlags, PlanCompatFlags, etc.) are missing
defer perf.Track(nil, "terraform.FuncName")()calls required by repo guidelines.
GetCompatFlags()at line 196 incorrectly includes-test-directory, which is not a valid flag forterraform get(only-updateand-no-colorare supported).
AllTerraformCompatFlags()at lines 238-242 has comment sentences not ending with periods, and line 272 is missingmergeFlags(ProvidersCompatFlags())for future-proofing.
🧹 Nitpick comments (3)
cmd/terraform/output.go (1)
7-19: Add anExamplesection to the Cobra command help.The
Use,Short, andLongfields are solid, but there is noExamplestring. To align with the repo’s CLI docs pattern and makeatmos terraform output --helpmore 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--affectedand--allflags.The
from-planandplanfileflags have correspondingATMOS_TERRAFORM_APPLY_*env vars, butaffectedandalldon'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.
📒 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.gocmd/terraform/validate.gopkg/flags/compat/compatibility_flags.gocmd/terraform/test.gocmd/terraform/taint.gocmd/terraform/apply.gocmd/terraform/graph.gocmd/terraform/output.gocmd/terraform/show.gocmd/terraform/refresh.gocmd/terraform/compat_flags.gocmd/terraform/init.gocmd/terraform/get.gocmd/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 undercmd/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.gocmd/terraform/validate.gocmd/terraform/test.gocmd/terraform/taint.gocmd/terraform/apply.gocmd/terraform/graph.gocmd/terraform/output.gocmd/terraform/show.gocmd/terraform/refresh.gocmd/terraform/compat_flags.gocmd/terraform/init.gocmd/terraform/get.gocmd/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.gocmd/terraform/validate.gocmd/terraform/test.gocmd/terraform/taint.gocmd/terraform/apply.gocmd/terraform/graph.gocmd/terraform/output.gocmd/terraform/show.gocmd/terraform/refresh.gocmd/terraform/compat_flags.gocmd/terraform/init.gocmd/terraform/get.gocmd/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.gocmd/terraform/validate.gocmd/terraform/test.gocmd/terraform/taint.gocmd/terraform/apply.gocmd/terraform/graph.gocmd/terraform/output.gocmd/terraform/show.gocmd/terraform/refresh.gocmd/terraform/compat_flags.gocmd/terraform/init.gocmd/terraform/get.gocmd/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.gocmd/terraform/validate.gopkg/flags/compat/compatibility_flags.gocmd/terraform/taint.gocmd/terraform/apply.gocmd/terraform/output.gocmd/terraform/show.gocmd/terraform/compat_flags.gocmd/terraform/init.gocmd/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.gocmd/terraform/test.gocmd/terraform/taint.gocmd/terraform/output.gocmd/terraform/compat_flags.gocmd/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.gocmd/terraform/validate.gocmd/terraform/test.gocmd/terraform/taint.gocmd/terraform/apply.gocmd/terraform/graph.gocmd/terraform/output.gocmd/terraform/show.gocmd/terraform/refresh.gocmd/terraform/compat_flags.gocmd/terraform/init.gocmd/terraform/get.gocmd/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.gocmd/terraform/validate.gocmd/terraform/test.gocmd/terraform/taint.gocmd/terraform/apply.gocmd/terraform/graph.gocmd/terraform/output.gocmd/terraform/show.gocmd/terraform/refresh.gocmd/terraform/compat_flags.gocmd/terraform/init.gocmd/terraform/get.gocmd/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.gocmd/terraform/validate.gocmd/terraform/test.gocmd/terraform/taint.gocmd/terraform/refresh.gocmd/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.gocmd/terraform/validate.gocmd/terraform/test.gocmd/terraform/taint.gocmd/terraform/output.gocmd/terraform/show.gocmd/terraform/compat_flags.gocmd/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.gocmd/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.gocmd/terraform/test.gocmd/terraform/taint.gocmd/terraform/apply.gocmd/terraform/graph.gocmd/terraform/output.gocmd/terraform/show.gocmd/terraform/refresh.gocmd/terraform/init.gocmd/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.gocmd/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.gocmd/terraform/taint.gocmd/terraform/show.gocmd/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.gocmd/terraform/output.gocmd/terraform/compat_flags.gocmd/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.gocmd/terraform/output.gocmd/terraform/compat_flags.gocmd/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.gocmd/terraform/output.gocmd/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.gocmd/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.gocmd/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.gocmd/terraform/apply.gocmd/terraform/output.gocmd/terraform/compat_flags.gocmd/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.gocmd/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.gocmd/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.gocmd/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.gocmd/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.gocmd/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.gocmd/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), andterraformCmd.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
terraformRunproperly 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, andAddCommandis consistent with sibling commands.cmd/terraform/apply.go (1)
1-60: LGTM!Solid implementation. The
StandardParserusage aligns with the unified flag parsing infrastructure, and thePostRunEhook integration forAfterTerraformApplyis a nice touch. Import grouping and comment formatting are correct.cmd/terraform/init.go (2)
7-22: Command wiring and delegation look solid.The
initCmddefinition is clear: good Short/Long descriptions, useful Terraform/OpenTofu doc links, andRunEdelegating to the sharedterraformRunkeeps behavior centralized and consistent with other terraform subcommands.
24-33: Nice use of shared help and completions.Hooking
setCustomHelp(initCmd)plusRegisterTerraformCompletions(initCmd)and then attaching toterraformCmdmatches the existing terraform completion pattern and keeps component/identity completions available oninit. This is exactly what we want for the per-subcommand registration. Based on learnings, this is consistent withRegisterTerraformCompletionsusage.
- 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>
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
cmd/terraform/compat_flags.go (1)
224-233:-test-directoryremains inGetCompatFlags()despite prior feedback.This flag is not supported by
terraform get. Per Terraform documentation, only-updateand-no-colorare 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 viaterraformCmd.AddCommand(metadataCmd)ininitmatches the established Cobra pattern. Based on learnings, inheriting parent flags without redefining them here is expected forterraform metadata.If you want to go a bit further later, you could add a brief sentence in
Longexplaining that this proxies the underlying Terraform/OpenTofumetadatacommand via Atmos, but it’s not strictly necessary.pkg/flags/compat/separated.go (1)
20-26: Optionally copy the input slice inSetSeparatedto fully own state.Right now
SetSeparatedstores the incoming slice directly:globalSeparatedArgs = separatedArgsIf any caller accidentally mutates
separatedArgsafter callingSetSeparated, 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.
📒 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.gocmd/terraform/metadata.gocmd/terraform/login.gopkg/flags/registry.gocmd/terraform/logout.gocmd/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 undercmd/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.gocmd/terraform/login.gocmd/terraform/logout.gocmd/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.gocmd/terraform/metadata.gopkg/flags/registry.gocmd/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.gocmd/terraform/metadata.gocmd/terraform/login.gopkg/flags/registry.gocmd/terraform/logout.gocmd/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.gocmd/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.gocmd/terraform/metadata.gocmd/terraform/login.gocmd/terraform/logout.gocmd/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.gocmd/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.gocmd/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.gocmd/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.gopkg/flags/registry.gocmd/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.gocmd/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.gocmd/terraform/metadata.gocmd/terraform/login.gopkg/flags/registry.gocmd/terraform/logout.gocmd/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.gopkg/flags/registry.gocmd/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.gocmd/terraform/login.gocmd/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.gocmd/terraform/login.gocmd/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.gocmd/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 inGetSeparatedlooks solid.The combination of
RLock/RUnlockwith returning a copy viaappend([]string{}, globalSeparatedArgs...)is a good pattern here and avoids data races from callers mutating the returned slice.
46-53:ResetSeparatedis simple and test-friendly.The write-locked reset to
nilplus 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.
UntaintCompatFlagsreturningTaintCompatFlags()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
mergeFlagsclosure 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
CompletionFuncbeing set fromcmd/terraformto 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 onidentity.The expanded Terraform flag set looks cohesive:
identitygainsNoOptDefValfor interactive selection, which integrates correctly withPreprocessNoOptDefValArgs.- 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 viaBindToViper.One thing to verify:
- The
identityflag addsEnvVars: []string{"ATMOS_IDENTITY", "IDENTITY"}. Project guidelines say env vars should use theATMOS_prefix; ifIDENTITYis 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
TerraformAffectedFlagsregistry 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 viaBindToViper.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
terraformRunfunction incmd/terraform/utils.goproperly:
- Extracts the subcommand name ("login") from
actualCmd.Name()- Prepends it to the passed arguments:
append([]string{subCommand}, args...)- Passes the combined arguments to
ProcessCommandLineArgsfor standard Cobra flag parsing- This correctly handles the optional hostname argument that
terraform loginacceptsThe 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:
Registry pattern: Implemented at the parent level via
TerraformCommandProviderinterface (incmd/terraform/terraform.go), not at the subcommand level. Individual subcommands likelogin.gosimply use Cobra'sAddCommand()pattern—this is correct.StandardFlagParser: Only required for commands that define Atmos-specific flags (e.g.,
plan,apply,deploy). Thelogincommand is a terraform native passthrough command with no Atmos-specific flags, so it correctly has no parser.The
login.gofile follows the intended pattern for simple terraform passthrough commands, consistent withlogout.go(which has identical structure and the same explicit comment explaining whyRegisterTerraformCompletionsis 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>
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
cmd/terraform/utils.go (1)
273-316: Guard against nil auth manager inhandleInteractiveIdentitySelectionand consider minor robustness tweaks
handleInteractiveIdentitySelectionstill assumesauth.CreateAndAuthenticateManageralways returns a non‑nil manager. Per the documented contract, it can return(nil, nil)when auth is globally disabled, which would cause a panic onauthManager.GetDefaultIdentity(true). Suggest adding an explicit nil guard before callingGetDefaultIdentity: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=trueis 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 theflags.ParseGlobalFlags→cfg.InitCliConfig(configAndStacksInfo, ...)pattern used elsewhere instead of passing an emptyschema.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 forvarfileCmdlook 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
Examplefield (and possibly slightly richerLongtext) showing a couple of typical invocations, e.g.:
atmos terraform generate varfile my-component -s tenant/ue2/devatmos terraform generate varfile my-component -s tenant/ue2/dev --file ./varfile.tfvars.jsonThis keeps
atmos terraform generate --helpand... varfile --helpmore 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()inWithTerraformFlags()andWithTerraformAffectedFlags()will measure the time to create the option closure, not the actual flag registration. SinceTerraformFlags()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, usenil.+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 []stringAlso 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>
There was a problem hiding this comment.
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 solidFront 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 commandsThe 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 --helpfor 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.
📒 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 usingfmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: usegofmtandgoimportsto 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 bygodotlinter)
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: Adddefer perf.Track(atmosConfig, "pkg.FuncName")()+ blank line to all public functions. Usenilif no atmosConfig param
Error handling: ALL user-facing errors MUST use ErrorBuilder with sentinel errors fromerrors/errors.go. ALWAYS useerrors.Is()for checking, NEVER string comparison. ALWAYS useassert.ErrorIs()in tests, NEVERassert.Contains(err.Error(), ...)
Mock generation: Usego.uber.org/mock/mockgenwith//go:generatedirectives. 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 thewebsite/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 thewebsite/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
.mdxformat with YAML front matter inwebsite/blog/YYYY-MM-DD-feature-name.mdx. Include<!--truncate-->after intro. Use only tags defined inwebsite/blog/tags.yml. Use authors fromwebsite/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
Profileviav.GetStringSlice("profile")is consistent with how other multi‑value globals (likeconfig/config-path) are handled, and respects Viper’s precedence. The change itself looks good.Please double‑check that:
- The
profileflag (andATMOS_PROFILEenv) is registered somewhere in the global flag registry, andglobal.Flags.Profileis actually threaded intocfg.ConfigAndStacksInfo.ProfilesFromArg(or equivalent) before callingcfg.InitCliConfig, so profile selection is honored the same way as config paths. Based on learnings, this struct is read directly byLoadConfig, not via Viper.website/blog/2025-12-15-interactive-terraform-prompts.mdx (2)
56-61: Verify CI/TTY/interactive gating matches the implemented behaviorThe blog states that prompts appear when:
- Component or stack are missing
- Running in a TTY (not piped or in CI)
--interactiveis enabled (default), or disabled via flag/env/configVerification 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 codeHard-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.
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>
|
Important Cloud Posse Engineering Team Review RequiredThis 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 |
There was a problem hiding this comment.
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{}toconfig.InitCliConfigcauses global config flags (--base-path,--config,--config-path,--profile) to be ignored. Per the learning from cmd/terraform/shell.go,LoadConfigreads these fields directly from theConfigAndStacksInfostruct, NOT from Viper.Other list commands (components, metadata, stacks, workflows, instances) correctly call
e.ProcessCommandLineArgsbeforeInitCliConfig, 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 emptyschema.ConfigAndStacksInfo{}causes global config flags (--base-path,--config,--config-path,--profile) to be ignored.LoadConfigreads these fields directly from the struct, not from Viper.Other list commands correctly call
e.ProcessCommandLineArgsbeforeInitCliConfig. 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.Commandandargs []stringparameters to callProcessCommandLineArgs. 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
listStacksForComponentandlistAllStacksfunctions still use emptyConfigAndStacksInfo{}, which means shell completions won't respect global flags like--base-pathor--config.The
stackFlagCompletionfunction receives thecmdparameter 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.
📒 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 undercmd/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.gocmd/list/utils.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/list/instances.gocmd/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 usingfmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: usegofmtandgoimportsto 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 bygodotlinter)
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: Adddefer perf.Track(atmosConfig, "pkg.FuncName")()+ blank line to all public functions. Usenilif no atmosConfig param
Error handling: ALL user-facing errors MUST use ErrorBuilder with sentinel errors fromerrors/errors.go. ALWAYS useerrors.Is()for checking, NEVER string comparison. ALWAYS useassert.ErrorIs()in tests, NEVERassert.Contains(err.Error(), ...)
Mock generation: Usego.uber.org/mock/mockgenwith//go:generatedirectives. 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.gocmd/list/utils.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/list/instances.gocmd/list/stacks.go
cmd/*/*.go
📄 CodeRabbit inference engine (CLAUDE.md)
cmd/*/*.go: Flag handling: Commands MUST useflags.NewStandardParser()for command-specific flags. NEVER callviper.BindEnv()orviper.BindPFlag()directly (enforced by Forbidigo linter)
CLI commands structure: Embed examples fromcmd/markdown/*_usage.mdusing//go:embed. Render withutils.PrintfMarkdown()
Files:
cmd/list/components.gocmd/list/utils.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/list/instances.gocmd/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.gocmd/list/utils.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/list/instances.gocmd/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.gocmd/list/utils.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/list/instances.gocmd/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.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/list/instances.gocmd/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.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/list/instances.gocmd/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.gocmd/list/utils.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/list/instances.gocmd/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.gocmd/list/utils.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/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.gocmd/list/utils.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/list/instances.gocmd/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.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/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.gocmd/list/utils.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/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.gocmd/list/utils.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/values.gocmd/list/vendor.gocmd/list/instances.gocmd/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.gocmd/list/utils.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/list/instances.gocmd/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.gocmd/list/utils.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/vendor.gocmd/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.gocmd/list/workflows.gocmd/list/instances.gocmd/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.gocmd/list/utils.gocmd/list/workflows.gocmd/list/settings.gocmd/list/vendor.gocmd/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.gocmd/list/vendor.gocmd/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.gocmd/list/utils.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/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.gocmd/list/utils.gocmd/list/workflows.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/list/instances.gocmd/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.gocmd/list/workflows.gocmd/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.gocmd/list/metadata.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/list/instances.gocmd/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.gocmd/list/settings.gocmd/list/values.gocmd/list/vendor.gocmd/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.gocmd/list/values.gocmd/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) beforeconfig.InitCliConfigcorrectly populates theConfigAndStacksInfostruct, 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) beforecfg.InitCliConfigensures 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.ProcessCommandLineArgscall (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 theConfigAndStacksInfobefore config initialization.cmd/list/instances.go (1)
43-54: LGTM: Proper Viper-based precedence flow.The shared Viper instance and downstream
e.ProcessCommandLineArgscall (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
initConfigAndAuthcall (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
globalpackage 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>
There was a problem hiding this comment.
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 directorywebsite/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 contextwebsite/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--forceis 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
--everythingis 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.
📒 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 thewebsite/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 thewebsite/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.mdxwebsite/docs/cli/commands/terraform/terraform-clean.mdxwebsite/docs/cli/commands/terraform/terraform-shell.mdxwebsite/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.mdxwebsite/docs/cli/commands/terraform/terraform-clean.mdxwebsite/docs/cli/commands/terraform/terraform-shell.mdxwebsite/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.mdxwebsite/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.mdxwebsite/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.mdxwebsite/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.mdxwebsite/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.mdxwebsite/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.mdxwebsite/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.mdxwebsite/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 workspacecommand 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-rundescription is clear, and the example correctly demonstrates the flag usage without requiring an explicit=truevalue.
101-108: LGTM!The
--forceflag 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.
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>
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>
|
These changes were released in v1.202.0-rc.4. |
|
These changes were released in v1.203.0-test.1. |
what
cmd/terraform/terraform plan-diffto usedata.Writeln()for proper output layeringwhy
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
docs/prd/command-registry-pattern.mdCLAUDE.mddocs/prd/terraform-registry-migration.mdwith detailed migration architectureSummary by CodeRabbit
New Features
Improvements
Chores
✏️ Tip: You can customize this high-level summary in your review settings.