Skip to content

Add generate section inheritance and auto-generation support#1878

Merged
aknysh merged 31 commits intomainfrom
osterman/generate-section-prd
Jan 5, 2026
Merged

Add generate section inheritance and auto-generation support#1878
aknysh merged 31 commits intomainfrom
osterman/generate-section-prd

Conversation

@osterman
Copy link
Member

@osterman osterman commented Dec 16, 2025

what

  • Add generate section to stack config inheritance pipeline with full support for base components, component-level overrides, and component overrides
  • Implement atmos terraform generate files command with --all, --dry-run, and --clean flags for generating auxiliary configuration files
  • Add auto_generate_files: true configuration option to automatically generate files during terraform operations
  • Extension-aware serialization: .json, .yaml, .yml files serialize in their respective formats, .tf and .hcl files generate valid HCL
  • Go template support: String values in generate sections are processed as Go templates with full access to component context
  • Update all integration test snapshots to reflect new auto_generate_files configuration field

why

Teams often need to generate auxiliary configuration files alongside Terraform components—files like .tool-versions, terragrunt.hcl shims for gradual migration, or environment-specific locals. This feature brings file generation directly into Atmos's declarative configuration model, maintaining the principle that infrastructure configuration should be fully described in YAML and reproducible from stack manifests. The inheritance support ensures teams can define common generate patterns in base components while allowing component-specific customization.

references

  • Implements declarative file generation PRD
  • Feature branch: osterman/generate-section-prd

Summary by CodeRabbit

  • New Features

    • Added declarative file generation for Terraform components via new generate sections in stack configurations.
    • New atmos terraform generate files command to automatically create auxiliary configuration files.
    • Support for extension-aware serialization (JSON, YAML, HCL, Terraform).
    • Go template processing for dynamic content in generated files.
    • Dry-run mode to preview generated files without writing.
    • Multi-level configuration inheritance for generated files.
    • Auto-generation toggle via auto_generate_files configuration.
  • Documentation

    • Added comprehensive guides for declarative file generation and CLI usage.
  • Tests

    • Added extensive test coverage for file generation and cleanup workflows.

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

@osterman osterman requested a review from a team as a code owner December 16, 2025 21:20
@github-actions github-actions bot added the size/xl Extra large size PR label Dec 16, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 16, 2025

📝 Walkthrough

Walkthrough

This pull request introduces declarative file generation for Terraform components in Atmos. It adds a new atmos terraform generate files subcommand, introduces a generate section at multiple configuration levels (global, terraform-type, base component, component, and component overrides), implements file generation with template rendering and extension-aware serialization, and refactors the Terraform clean subsystem into a pluggable service architecture. The changes extend stack processing to handle generate sections through deferred-merge semantics, add comprehensive schema definitions, and include CLI wiring, adapters, and extensive test coverage.

Changes

Cohort / File(s) Summary
CLI Command Layer
cmd/terraform/generate/files.go, cmd/terraform/generate/generate.go, cmd/terraform/clean.go
New files subcommand under generate with flag parsing (stack, all, stacks, components, dry-run, clean), validation rules (--all excludes component; component requires --stack), and wiring to Terraform generate service. Updated generate command description. Clean command refactored to use public tfclean service API instead of internal logic.
Terraform Generate Service
pkg/terraform/generate/generate.go, pkg/terraform/generate/adapter.go, pkg/terraform/generate/file_generator.go
New service orchestrating file generation for single/all components with auto-generation support. Adapter bridges internal exec functions to public interface. File generator handles template rendering, serialization by extension (JSON/YAML/HCL), dry-run, clean, and file lifecycle management.
Terraform Clean Service (Refactored)
pkg/terraform/clean/clean.go, pkg/terraform/clean/adapter.go, pkg/terraform/clean/collector.go, pkg/terraform/clean/deleter.go, pkg/terraform/clean/errors.go, pkg/terraform/clean/types.go, pkg/terraform/clean/validation.go
New public service-based clean subsystem replacing internal utilities. Includes stack processor interface, options/result types, orchestration logic, file/folder collection with deduplication, deletion utilities, TF_DATA_DIR handling, path validation, and 18 new error sentinels.
Internal Execution Adapters
internal/exec/clean_adapter_funcs.go, internal/exec/generate_adapter_funcs.go
Wrapper functions delegating to existing core logic with performance instrumentation, enabling service-based clean/generate workflows without altering core algorithms.
Stack Processing Extensions
internal/exec/stack_processor_merge.go, internal/exec/stack_processor_process_stacks.go, internal/exec/stack_processor_process_stacks_helpers.go, internal/exec/stack_processor_process_stacks_helpers_extraction.go, internal/exec/stack_processor_process_stacks_helpers_overrides.go, internal/exec/stack_processor_utils.go
Added support for generate section merging with deferred-merge semantics across global, terraform-type, base, component, and component-override levels. New fields: GlobalAndTerraformGenerate, ComponentGenerate, ComponentOverridesGenerate, BaseComponentGenerate.
Terraform Execution Integration
internal/exec/terraform.go
Added call to generateFilesForComponent after backend generation, gating file generation via auto_generate_files config.
Schema and Configuration
pkg/schema/schema.go, pkg/config/const.go, pkg/datafetcher/schema/stacks/stack-config/1.0.json, tests/fixtures/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json, website/static/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json
New GenerateSectionName constant, AutoGenerateFiles bool field in Terraform struct, BaseComponentGenerate field in BaseComponentConfig. Comprehensive generate schema definition supporting oneOf (string include or object with per-extension serialization).
Test Infrastructure
tests/snapshots/TestCLICommands_*.golden, tests/test-cases/terraform-generate-files.yaml, tests/fixtures/scenarios/terraform-generate-files/*
Golden snapshots updated to include auto_generate_files: false. New test scenario fixture with atmos.yaml, vpc/s3-bucket components, and dev/prod stacks demonstrating file generation with inheritance and overrides.
Unit and Integration Tests
pkg/terraform/generate/*_test.go, pkg/terraform/clean/*_test.go, internal/exec/*_test.go, cmd/terraform/*_test.go
Comprehensive test suites for generate service/adapter/file_generator, clean service/adapter/collector/deleter/validation, clean/generate adapter funcs, and CLI command flags/args. Includes mock generation via GoMock.
Removed Internal Utilities
internal/exec/terraform_clean.go, internal/exec/terraform_clean_test.go, internal/exec/terraform_clean_e2e_test.go, internal/exec/terraform_clean_integration_test.go, internal/exec/terraform_clean_util_test.go, internal/exec/terraform_clean_util.go, internal/exec/terraform_clean_duplicate_test.go, pkg/generate/terraform_generate_varfiles_test.go, pkg/generate/atmos.yaml
Removed legacy internal clean utilities, replaced by public service layer. Removed obsolete test file and config.
Error Definitions
errors/errors.go
Added four new error sentinels: ErrInvalidComponentGenerate, ErrInvalidComponentOverridesGenerate, ErrInvalidGenerateSection, ErrInvalidTerraformGenerateSection.
Documentation
docs/prd/code-generation.md, website/docs/stacks/generate.mdx, website/docs/cli/commands/terraform/generate/files.mdx, website/docs/cli/commands/terraform/terraform-clean.mdx, website/docs/cli/configuration/components/terraform.mdx, website/docs/stacks/components/terraform.mdx, website/docs/cli/commands/terraform/workdir/*, website/blog/2025-12-16-declarative-file-generation.mdx, cmd/markdown/atmos_terraform_clean_usage.md, cmd/markdown/atmos_terraform_generate_files_usage.md
New PRD detailing declarative code-generation feature, end-user docs for generate files command, update to terraform component config docs, new workdir documentation tree, blog post, and CLI usage markdown.
Metadata and Configuration
website/src/data/roadmap.js
Updated feature parity progress from 70 to 80; added PR, docs, and changelog references to file generation milestone.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as Atmos CLI<br/>(files cmd)
    participant Service as Generate<br/>Service
    participant Adapter as ExecAdapter
    participant StackProc as Internal<br/>Stack Processor
    participant FileGen as File<br/>Generator
    participant FS as Filesystem

    CLI->>Service: ExecuteForComponent(component, stack, dryRun, clean)
    Service->>Adapter: ProcessStacks(atmosConfig, info, ...)
    Adapter->>StackProc: ProcessStacks (internal)
    StackProc-->>Adapter: returns processed config
    Adapter-->>Service: returns config
    
    Service->>Adapter: FindStacksMap(atmosConfig)
    Adapter->>StackProc: FindStacksMap (internal)
    StackProc-->>Adapter: returns stacks map
    Adapter-->>Service: returns stacks map
    
    Service->>Service: Extract generate section<br/>Build template context
    Service->>FileGen: GenerateFiles(generateSection, ...)
    FileGen->>FileGen: Render templates<br/>Serialize by extension
    alt DryRun
        FileGen->>FileGen: Report what would happen
    else Normal
        FileGen->>FS: Create/update files
    else Clean
        FileGen->>FS: Delete generated files
    end
    FileGen-->>Service: results
    Service-->>CLI: done
Loading
sequenceDiagram
    participant CLI as Atmos CLI<br/>(clean cmd)
    participant Service as Clean<br/>Service
    participant Adapter as ExecAdapter
    participant Collector as Collector
    participant Deleter as Deleter
    participant FS as Filesystem

    CLI->>Service: Execute(opts, atmosConfig)
    
    alt Cache mode
        Service->>FS: Delete plugin cache
    else Normal/Component mode
        Service->>Adapter: ExecuteDescribeStacks()
        Adapter-->>Service: stacks info
        Service->>Adapter: GetAllStacksComponentsPaths()
        Adapter-->>Service: component paths (deduplicated)
        Service->>Collector: CollectComponentsDirectoryObjects()
        Collector->>FS: Scan directories (glob patterns)
        Collector-->>Service: Directory/ObjectInfo list
        Service->>Service: initializeFilesToClear()<br/>countFilesToDelete()
        alt DryRun
            Service->>Service: printDryRunOutput()
        else Normal
            Service->>Service: promptForConfirmation()
            alt User confirms
                Service->>Deleter: executeCleanDeletion()
                Deleter->>FS: Delete files/folders
                Deleter->>FS: Handle TF_DATA_DIR
                Deleter-->>Service: status
            end
        end
    end
    Service-->>CLI: done
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Suggested reviewers

  • osterman

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 70.48% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add generate section inheritance and auto-generation support' directly reflects the main changes: a new generate section with multi-level inheritance and auto-generation capabilities via CLI and configuration flags.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch osterman/generate-section-prd

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

❤️ Share

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

@mergify
Copy link

mergify bot commented Dec 16, 2025

Warning

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

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

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

@github-actions
Copy link

github-actions bot commented Dec 16, 2025

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@codecov
Copy link

codecov bot commented Dec 16, 2025

Codecov Report

❌ Patch coverage is 77.99296% with 250 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.02%. Comparing base (2cd3971) to head (2f1ac06).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
pkg/terraform/clean/collector.go 76.69% 29 Missing and 26 partials ⚠️
pkg/terraform/clean/clean.go 79.18% 37 Missing and 9 partials ⚠️
cmd/terraform/generate/files.go 25.45% 40 Missing and 1 partial ⚠️
pkg/terraform/generate/file_generator.go 86.63% 14 Missing and 13 partials ⚠️
pkg/terraform/clean/deleter.go 67.92% 10 Missing and 7 partials ⚠️
cmd/terraform/clean.go 0.00% 12 Missing ⚠️
internal/exec/stack_processor_process_stacks.go 28.57% 7 Missing and 3 partials ⚠️
pkg/terraform/generate/generate.go 96.11% 4 Missing and 4 partials ⚠️
internal/exec/generate_adapter_funcs.go 53.84% 6 Missing ⚠️
...ack_processor_process_stacks_helpers_extraction.go 37.50% 4 Missing and 1 partial ⚠️
... and 6 more
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1878      +/-   ##
==========================================
+ Coverage   73.97%   74.02%   +0.04%     
==========================================
  Files         760      769       +9     
  Lines       68654    69276     +622     
==========================================
+ Hits        50789    51280     +491     
- Misses      14444    14585     +141     
+ Partials     3421     3411      -10     
Flag Coverage Δ
unittests 74.02% <77.99%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
errors/errors.go 100.00% <ø> (ø)
...nal/exec/stack_processor_process_stacks_helpers.go 73.33% <ø> (ø)
...ck_processor_process_stacks_helpers_inheritance.go 95.16% <100.00%> (+0.07%) ⬆️
pkg/schema/schema.go 88.98% <ø> (ø)
pkg/terraform/clean/adapter.go 100.00% <100.00%> (ø)
pkg/terraform/generate/adapter.go 100.00% <100.00%> (ø)
internal/exec/terraform.go 60.22% <33.33%> (-0.19%) ⬇️
internal/exec/clean_adapter_funcs.go 82.60% <82.60%> (ø)
internal/exec/stack_processor_merge.go 74.66% <75.00%> (+0.02%) ⬆️
internal/exec/stack_processor_utils.go 80.09% <55.55%> (-0.27%) ⬇️
... and 12 more

... and 4 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@osterman osterman added the minor New features that do not break anything label Dec 16, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (4)
pkg/generate/generate_test.go (1)

242-272: HCL test could be more specific.

The assertions check for presence of strings but don't verify HCL structure. Consider adding checks for HCL block syntax like { and } or = for attribute assignment.

internal/exec/terraform_generate_files.go (1)

356-372: Redundant prefix matching.

filepath.Match already handles * patterns. The manual prefix check (lines 364-368) duplicates this behavior and can be removed for simplicity.

 func matchesStackFilter(stackName string, filters []string) bool {
 	for _, filter := range filters {
 		matched, err := filepath.Match(filter, stackName)
 		if err == nil && matched {
 			return true
 		}
-		// Also check if the filter matches as a prefix.
-		if len(filter) > 0 && filter[len(filter)-1] == '*' {
-			prefix := filter[:len(filter)-1]
-			if len(stackName) >= len(prefix) && stackName[:len(prefix)] == prefix {
-				return true
-			}
-		}
 	}
 	return false
 }
docs/prd/code-generation.md (1)

125-133: Table formatting issue.

The YAML block scalar reference table has column count mismatches flagged by markdownlint (pipes in "Behavior" column content are causing issues). Per learnings, this can be addressed in a follow-up documentation cleanup PR.

pkg/generate/generate.go (1)

50-87: Consider returning aggregated errors.

Individual file errors are captured in result.Error, but GenerateFiles always returns nil for the error. Consider returning a combined error when any file fails so callers can detect failures without iterating results.

 func GenerateFiles(
 	generateSection map[string]any,
 	componentDir string,
 	templateContext map[string]any,
 	config GenerateConfig,
 ) ([]GenerateResult, error) {
 	defer perf.Track(nil, "generate.GenerateFiles")()

 	if generateSection == nil {
 		return nil, nil
 	}

 	var results []GenerateResult
+	var errs []error

 	for filename, content := range generateSection {
 		result := GenerateResult{Filename: filename}
 		filePath := filepath.Join(componentDir, filename)
 		result.Path = filePath

 		if config.Clean {
 			processCleanFile(&result, filePath, config.DryRun)
 		} else {
 			processGenerateFile(&result, fileContext{
 				filename:        filename,
 				filePath:        filePath,
 				content:         content,
 				templateContext: templateContext,
 				dryRun:          config.DryRun,
 			})
 		}

+		if result.Error != nil {
+			errs = append(errs, result.Error)
+		}
 		results = append(results, result)
 	}

-	return results, nil
+	if len(errs) > 0 {
+		return results, errors.Join(errs...)
+	}
+	return results, nil
 }

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 16, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
website/docs/cli/commands/terraform/terraform-generate-files.mdx (1)

7-11: Consider adding Screengrab component.

Per project guidelines, CLI command docs typically include a Screengrab component after the Intro. This provides visual consistency with other command documentation pages.

 <Intro>
 Use this command to generate auxiliary configuration files for Terraform components based on the `generate` section in stack configuration.
 </Intro>
+
+import Screengrab from '@site/src/components/Screengrab'
+
+<Screengrab title="atmos terraform generate files --help" slug="atmos-terraform-generate-files--help" />
cmd/terraform/generate/files.go (1)

48-111: Consider adding performance tracking.

Per coding guidelines, public functions should include defer perf.Track(atmosConfig, "pkg.FuncName")(). The RunE handler could benefit from this for observability.

 	RunE: func(cmd *cobra.Command, args []string) error {
+		defer perf.Track(nil, "cmd.terraform.generate.files")()
+
 		// Use Viper to respect precedence (flag > env > config > default).
 		v := viper.GetViper()

Note: Uses nil since atmosConfig isn't available until after InitCliConfig.

pkg/generate/generate.go (1)

64-86: Map iteration order is non-deterministic.

Iterating over generateSection map produces files in random order. This is fine functionally but may cause inconsistent CLI output ordering between runs. Consider sorting keys if consistent output ordering is desired for user experience or test stability.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 69bd85c and 23a658f.

📒 Files selected for processing (7)
  • cmd/terraform/generate/files.go (1 hunks)
  • pkg/generate/generate.go (1 hunks)
  • pkg/generate/generate_test.go (1 hunks)
  • pkg/schema/schema.go (2 hunks)
  • tests/snapshots/TestCLICommands_atmos_terraform_-help_passthrough.stdout.golden (1 hunks)
  • website/blog/2025-12-16-declarative-file-generation.mdx (1 hunks)
  • website/docs/cli/commands/terraform/terraform-generate-files.mdx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • pkg/schema/schema.go
  • website/blog/2025-12-16-declarative-file-generation.mdx
  • pkg/generate/generate_test.go
🧰 Additional context used
📓 Path-based instructions (4)
website/**

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

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

Files:

  • website/docs/cli/commands/terraform/terraform-generate-files.mdx
website/docs/cli/commands/**/*.mdx

📄 CodeRabbit inference engine (CLAUDE.md)

All CLI commands/flags need Docusaurus documentation in website/docs/cli/commands/ with specific structure: frontmatter, Intro component, Screengrab component, Usage section, Arguments/Flags using

/
, and Examples section

Files:

  • website/docs/cli/commands/terraform/terraform-generate-files.mdx
cmd/**/*.go

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

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

cmd/**/*.go: Commands MUST use flags.NewStandardParser() for command-specific flags; NEVER call viper.BindEnv() or viper.BindPFlag() directly (Forbidigo enforces this); see cmd/version/version.go for reference
Embed CLI examples from cmd/markdown/*_usage.md using //go:embed; render with utils.PrintfMarkdown()

Files:

  • cmd/terraform/generate/files.go
**/*.go

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

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

**/*.go: NEVER use fmt.Fprintf(os.Stdout/Stderr) or fmt.Println(); use data.* or ui.* functions instead
All comments must end with periods (enforced by godot linter)
Organize imports in three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages; maintain aliases: cfg, log, u, errUtils
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions for performance tracking; use nil if no atmosConfig param
All errors MUST be wrapped using static errors defined in errors/errors.go; use errors.Join for combining multiple errors; use fmt.Errorf with %w for adding string context; use error builder for complex errors; use 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
Keep files small...

Files:

  • cmd/terraform/generate/files.go
  • pkg/generate/generate.go
🧠 Learnings (41)
📓 Common learnings
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:37.766Z
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.
📚 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_terraform_-help_passthrough.stdout.golden
  • website/docs/cli/commands/terraform/terraform-generate-files.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:

  • tests/snapshots/TestCLICommands_atmos_terraform_-help_passthrough.stdout.golden
  • website/docs/cli/commands/terraform/terraform-generate-files.mdx
  • cmd/terraform/generate/files.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:

  • tests/snapshots/TestCLICommands_atmos_terraform_-help_passthrough.stdout.golden
  • website/docs/cli/commands/terraform/terraform-generate-files.mdx
  • cmd/terraform/generate/files.go
  • pkg/generate/generate.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:

  • tests/snapshots/TestCLICommands_atmos_terraform_-help_passthrough.stdout.golden
  • website/docs/cli/commands/terraform/terraform-generate-files.mdx
📚 Learning: 2025-02-14T23:12:38.030Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1061
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:8-8
Timestamp: 2025-02-14T23:12:38.030Z
Learning: Test snapshots in the Atmos project, particularly for dry run scenarios, may be updated during the development process, and temporary inconsistencies in their content should not be flagged as issues.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_terraform_-help_passthrough.stdout.golden
📚 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:

  • tests/snapshots/TestCLICommands_atmos_terraform_-help_passthrough.stdout.golden
  • website/docs/cli/commands/terraform/terraform-generate-files.mdx
  • cmd/terraform/generate/files.go
📚 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_terraform_-help_passthrough.stdout.golden
📚 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:

  • tests/snapshots/TestCLICommands_atmos_terraform_-help_passthrough.stdout.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_terraform_-help_passthrough.stdout.golden
  • website/docs/cli/commands/terraform/terraform-generate-files.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 **/*_test.go : Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_terraform_-help_passthrough.stdout.golden
📚 Learning: 2025-12-16T18:20:55.614Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.614Z
Learning: Applies to website/docs/cli/commands/**/*.mdx : All CLI commands/flags need Docusaurus documentation in website/docs/cli/commands/ with specific structure: frontmatter, Intro component, Screengrab component, Usage section, Arguments/Flags using <dl><dt>/<dd>, and Examples section

Applied to files:

  • website/docs/cli/commands/terraform/terraform-generate-files.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-generate-files.mdx
📚 Learning: 2025-10-14T01:54:48.410Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-completion--help.html:2-7
Timestamp: 2025-10-14T01:54:48.410Z
Learning: Screengrab HTML files in website/src/components/Screengrabs/ are generated from actual Atmos CLI output converted to HTML. The ANSI-art headers and formatting in these files are intentional and reflect the real CLI user experience, so they should not be suggested for removal or modification.

Applied to files:

  • website/docs/cli/commands/terraform/terraform-generate-files.mdx
📚 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-generate-files.mdx
  • cmd/terraform/generate/files.go
📚 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-generate-files.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-generate-files.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 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/generate/files.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/generate/files.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/files.go
📚 Learning: 2025-12-16T18:20:55.614Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.614Z
Learning: Applies to **/*.go : Keep files small and focused (<600 lines); one cmd/impl per file; co-locate tests; never use //revive:disable:file-length-limit

Applied to files:

  • cmd/terraform/generate/files.go
  • pkg/generate/generate.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 initializing CLI config via cfg.InitCliConfig, always first populate the ConfigAndStacksInfo struct with global flag values by calling flags.ParseGlobalFlags(cmd, v) before LoadConfig. LoadConfig (pkg/config/load.go) reads config selection fields (AtmosConfigFilesFromArg, AtmosConfigDirsFromArg, BasePath, ProfilesFromArg) from the ConfigAndStacksInfo struct, not from Viper. Passing an empty struct causes the --base-path, --config, --config-path, and --profile flags to be ignored. Recommended pattern: parse flags → populate struct → call InitCliConfig. See cmd/terraform/plan_diff.go for reference implementation.

Applied to files:

  • cmd/terraform/generate/files.go
📚 Learning: 2025-12-16T18:20:55.614Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.614Z
Learning: Applies to **/*.go : Organize imports in three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages; maintain aliases: cfg, log, u, errUtils

Applied to files:

  • cmd/terraform/generate/files.go
  • pkg/generate/generate.go
📚 Learning: 2025-12-13T04:37:25.223Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/root.go:0-0
Timestamp: 2025-12-13T04:37:25.223Z
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/terraform/generate/files.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/generate/files.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/files.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/terraform/generate/files.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/generate/files.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/generate/files.go
  • pkg/generate/generate.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/generate/files.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/terraform/generate/files.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:

  • pkg/generate/generate.go
📚 Learning: 2025-06-07T19:28:21.289Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1266
File: cmd/describe_affected.go:0-0
Timestamp: 2025-06-07T19:28:21.289Z
Learning: In the Atmos codebase, using panic for unsupported flag types in flag processing functions like setDescribeAffectedFlagValueInCliArgs is the expected behavior rather than returning errors. This pattern is preferred for developer errors when unsupported types are added to the flagsKeyValue map.

Applied to files:

  • pkg/generate/generate.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/generate/generate.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:

  • pkg/generate/generate.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/generate/generate.go
📚 Learning: 2025-12-13T06:10:13.688Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: errors/errors.go:184-203
Timestamp: 2025-12-13T06:10:13.688Z
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.

Applied to files:

  • pkg/generate/generate.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/generate/generate.go
📚 Learning: 2025-01-25T04:01:58.095Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: internal/exec/docs_generate.go:98-101
Timestamp: 2025-01-25T04:01:58.095Z
Learning: In the `generateSingleReadme` function of the docs generation feature (internal/exec/docs_generate.go), errors from `fetchAndParseYAML` should be logged and skipped rather than causing early returns. This is by design to process all inputs and collect all errors, instead of failing fast on the first error.

Applied to files:

  • pkg/generate/generate.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:

  • pkg/generate/generate.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:

  • pkg/generate/generate.go
🧬 Code graph analysis (1)
pkg/generate/generate.go (2)
pkg/perf/perf.go (1)
  • Track (121-138)
errors/errors.go (2)
  • ErrInvalidConfig (49-49)
  • ErrUnsupportedInputType (53-53)
🪛 LanguageTool
website/docs/cli/commands/terraform/terraform-generate-files.mdx

[typographical] ~86-~86: To join two clauses or introduce examples, consider using an em dash.
Context: ... Go templates with access to: - .vars - Component variables - .settings - Comp...

(DASH_RULE)


[typographical] ~93-~93: To join two clauses or introduce examples, consider using an em dash.
Context: ...nt, .environment, .stage, .region- Context variables -.atmos_component` -...

(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). (3)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
🔇 Additional comments (12)
tests/snapshots/TestCLICommands_atmos_terraform_-help_passthrough.stdout.golden (1)

32-32: LGTM!

Snapshot update reflects updated terraform CLI help text for the test subcommand. Expected change for passthrough snapshot tests.

website/docs/cli/commands/terraform/terraform-generate-files.mdx (2)

53-98: Clear and comprehensive configuration documentation.

Template context variables and extension-aware serialization are well documented. The examples effectively demonstrate both map-based and string template content types.


110-171: LGTM!

Arguments and flags documented correctly using the <dl><dt>/<dd> structure per project conventions. Each flag includes inline examples.

cmd/terraform/generate/files.go (2)

1-15: LGTM!

Imports properly organized in three groups: stdlib, third-party, Atmos packages. Aliases follow conventions (errUtils, cfg).


114-138: LGTM!

Parser initialization follows the StandardParser pattern. Environment variable bindings use the ATMOS_ prefix correctly. The panic on BindToViper failure is appropriate for init-time configuration errors.

pkg/generate/generate.go (7)

1-21: LGTM!

Package documentation clear. Imports properly organized in three groups with correct aliases. Dependencies on hclwrite and yaml.v3 are appropriate for the serialization needs.


98-148: LGTM!

Clean separation between clean and generate modes. Proper handling of non-existent files during clean. Uses ui.Writef for user-facing output per guidelines.


180-193: Template execution uses basic Go templates.

Currently uses plain text/template without additional template functions. If users need more expressive templates (e.g., string manipulation, conditionals), consider adding sprig or custom functions in a future iteration.


198-237: LGTM!

Extension-aware serialization with proper case-insensitive matching. YAML encoder properly closed. Defaulting to JSON for unknown extensions is a sensible fallback.


239-305: LGTM!

Recursive template rendering handles nested maps and arrays correctly. Error propagation maintains context through the recursion.


341-398: LGTM!

HCL value conversion correctly uses TupleVal and ObjectVal to support mixed types, addressing the previous review concern. Empty collections and nil values handled appropriately.


319-339: LGTM!

Block creation for nested maps and attribute setting for primitives follows HCL conventions. Error context preserved through recursion.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (15)
pkg/terraform/clean/validation.go (1)

23-26: Minor: Redundant clean check.

filepath.Clean("/") always returns "/" on Unix, so the second comparison is redundant. Not a blocker.

-	if absTFDataDir == "/" || absTFDataDir == filepath.Clean("/") {
+	if absTFDataDir == "/" {
pkg/terraform/clean/errors.go (1)

1-25: Error definitions look solid, but a few messages could use polish.

Some error messages have grammatical quirks that may confuse users:

  • Line 9: "error describe stacks""error describing stacks"
  • Line 11: "path not exist""path does not exist"
  • Line 12: "error get file stat""error getting file stat"

These are user-facing strings, so clarity helps.

-	ErrDescribeStack             = errors.New("error describe stacks")
+	ErrDescribeStack             = errors.New("error describing stacks")
-	ErrPathNotExist              = errors.New("path not exist")
+	ErrPathNotExist              = errors.New("path does not exist")
-	ErrFileStat                  = errors.New("error get file stat")
+	ErrFileStat                  = errors.New("error getting file stat")
internal/exec/terraform_clean_test.go (2)

38-47: Prefer t.Setenv for environment variable manipulation.

Using os.Unsetenv directly doesn't auto-restore on test failure. t.Setenv handles cleanup automatically.

 func TestCLITerraformClean(t *testing.T) {
-	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, t.Setenv is preferred for automatic setup/teardown.


134-141: Consider errors.Is() for error assertions.

Current approach with require.Contains works but errors.Is() is preferred per guidelines when checking sentinel errors.

-			if tt.expectedError != nil {
-				require.Error(t, err)
-				require.Contains(t, err.Error(), tt.expectedError.Error())
+			if tt.expectedError != nil {
+				require.Error(t, err)
+				require.ErrorIs(t, err, tt.expectedError)

Note: This depends on how errors are wrapped in the implementation. If they're wrapped with fmt.Errorf("%w", ...), ErrorIs will work.

pkg/terraform/generate/file_generator_internal_test.go (1)

828-890: Test name doesn't match implementation.

Function TestWriteHCLBlock calls serializeToHCL at line 881, not writeHCLBlock. Consider renaming for clarity.

-func TestWriteHCLBlock(t *testing.T) {
+func TestSerializeToHCL_BlockBehavior(t *testing.T) {

Or if writeHCLBlock exists and should be tested, update the test to call it.

internal/exec/terraform_clean_util.go (1)

16-16: Consider moving ErrRelPath to centralized errors.

Per guidelines, static errors should be defined in errors/errors.go. This local definition works but could be centralized for consistency.

Also note: pkg/errors.New is used here while pkg/terraform/clean/errors.go uses standard errors.New. Consistency across packages would help.

pkg/terraform/clean/collector.go (2)

189-194: Variable shadowing detected.

tfStateFolderPath on line 190 shadows the outer variable from line 183. Consider renaming the inner variable to something like folderFullPath for clarity.

Additionally, the existence check on lines 192-194 is redundant since CollectDirectoryObjects already validates path existence internally.

 	for _, folderName := range tfStateFolderNames {
-		tfStateFolderPath := filepath.Join(componentPath, "terraform.tfstate.d", folderName)
-		// Check if exists.
-		if _, err := os.Stat(tfStateFolderPath); os.IsNotExist(err) {
-			continue
-		}
-		directories, err := CollectDirectoryObjects(tfStateFolderPath, []string{"*.tfstate", "*.tfstate.backup"})
+		folderFullPath := filepath.Join(componentPath, "terraform.tfstate.d", folderName)
+		directories, err := CollectDirectoryObjects(folderFullPath, []string{"*.tfstate", "*.tfstate.backup"})

212-229: Consider wrapping errors for consistency.

The function returns raw errors from filepath.Abs and filepath.Rel. For consistency with other functions in this file that wrap errors with context, consider adding descriptive wrapping here as well.

pkg/terraform/generate/generate_test.go (1)

15-46: Consider using mockgen for consistency.

Per project guidelines, mocks should be generated with go.uber.org/mock/mockgen. This manual mock works fine, but generated mocks offer better maintainability as the interface evolves.

pkg/terraform/generate/generate.go (2)

114-116: Consider returning or logging generation results.

GenerateFiles returns []GenerateResult but only the error is propagated. If callers need to know what was generated, consider returning the results or logging a summary.


394-412: Prefix matching may be redundant with glob.

The manual prefix check (lines 404-409) for patterns ending in * might overlap with filepath.Match behavior. For example, dev-* should already match dev-us-west-2 via glob. The manual check ensures dev-us-west-2* matches dev-us-west-2-vpc (trailing wildcard as substring prefix), which filepath.Match wouldn't catch. If that's the intent, a brief comment would clarify.

pkg/terraform/generate/file_generator.go (1)

66-84: Map iteration order is non-deterministic.

Iterating over generateSection produces files in undefined order. This is fine for correctness but may cause non-reproducible output logs. If ordering matters for users, consider sorting keys first.

pkg/terraform/clean/adapter.go (1)

47-67: Consider nil validation for defensive coding.

The constructor accepts function pointers without validation. If any delegate is nil, calling the corresponding method will panic. Since this is internal infrastructure, the risk is low if callers are disciplined, but a defensive nil check could prevent obscure runtime failures.

 func NewExecAdapter(
 	processStacks ExecProcessStacks,
 	executeDescribeStacks ExecDescribeStacks,
 	getGenerateFilenames ExecGetGenerateFilenames,
 	collectComponentsDirectoryObjs ExecCollectComponentsDirectoryObjects,
 	constructVarfileName ExecConstructVarfileName,
 	constructPlanfileName ExecConstructPlanfileName,
 	getAllStacksComponentsPaths ExecGetAllStacksComponentsPaths,
 ) *ExecAdapter {
 	defer perf.Track(nil, "clean.NewExecAdapter")()
+
+	if processStacks == nil || executeDescribeStacks == nil || getGenerateFilenames == nil ||
+		collectComponentsDirectoryObjs == nil || constructVarfileName == nil ||
+		constructPlanfileName == nil || getAllStacksComponentsPaths == nil {
+		panic("ExecAdapter: all delegate functions must be non-nil")
+	}

 	return &ExecAdapter{
pkg/terraform/clean/clean.go (2)

122-126: Consider wrapping the ProcessStacks error with context.

Per coding guidelines, errors should be wrapped with context using fmt.Errorf("context: %w", err). This helps with debugging.

 	if opts.Component != "" {
 		resolvedInfo, err := s.processor.ProcessStacks(atmosConfig, info)
 		if err != nil {
-			return err
+			return fmt.Errorf("processing stacks for component %q: %w", opts.Component, err)
 		}

281-285: Dead code: filterComponents condition is unreachable.

At line 269, if info.ComponentFromArg != "", the function returns early at line 278. Therefore, the check at line 283 will always be false when reached, making filterComponents always empty.

 	log.Debug("Clean: No component from arg, calling ExecuteDescribeStacks", "StackFromArg", info.StackFromArg)
-	var filterComponents []string
-	if info.ComponentFromArg != "" {
-		filterComponents = append(filterComponents, info.ComponentFromArg)
-	}
-	stacksMap, err := s.processor.ExecuteDescribeStacks(atmosConfig, info.StackFromArg, filterComponents)
+	stacksMap, err := s.processor.ExecuteDescribeStacks(atmosConfig, info.StackFromArg, nil)
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 23a658f and 3bd6dfb.

📒 Files selected for processing (23)
  • cmd/terraform/clean.go (2 hunks)
  • cmd/terraform/generate/files.go (1 hunks)
  • internal/exec/clean_adapter_funcs.go (1 hunks)
  • internal/exec/generate_adapter_funcs.go (1 hunks)
  • internal/exec/terraform_clean.go (0 hunks)
  • internal/exec/terraform_clean_e2e_test.go (2 hunks)
  • internal/exec/terraform_clean_integration_test.go (5 hunks)
  • internal/exec/terraform_clean_test.go (6 hunks)
  • internal/exec/terraform_clean_util.go (1 hunks)
  • pkg/generate/atmos.yaml (0 hunks)
  • pkg/terraform/clean/adapter.go (1 hunks)
  • pkg/terraform/clean/clean.go (1 hunks)
  • pkg/terraform/clean/collector.go (1 hunks)
  • pkg/terraform/clean/deleter.go (1 hunks)
  • pkg/terraform/clean/errors.go (1 hunks)
  • pkg/terraform/clean/types.go (1 hunks)
  • pkg/terraform/clean/validation.go (1 hunks)
  • pkg/terraform/generate/adapter.go (1 hunks)
  • pkg/terraform/generate/file_generator.go (1 hunks)
  • pkg/terraform/generate/file_generator_internal_test.go (1 hunks)
  • pkg/terraform/generate/file_generator_test.go (1 hunks)
  • pkg/terraform/generate/generate.go (1 hunks)
  • pkg/terraform/generate/generate_test.go (1 hunks)
💤 Files with no reviewable changes (2)
  • internal/exec/terraform_clean.go
  • pkg/generate/atmos.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/terraform/generate/files.go
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

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

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

**/*.go: NEVER use fmt.Fprintf(os.Stdout/Stderr) or fmt.Println(); use data.* or ui.* functions instead
All comments must end with periods (enforced by godot linter)
Organize imports in three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages; maintain aliases: cfg, log, u, errUtils
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions for performance tracking; use nil if no atmosConfig param
All errors MUST be wrapped using static errors defined in errors/errors.go; use errors.Join for combining multiple errors; use fmt.Errorf with %w for adding string context; use error builder for complex errors; use 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
Keep files small...

Files:

  • internal/exec/terraform_clean_integration_test.go
  • pkg/terraform/clean/validation.go
  • internal/exec/terraform_clean_e2e_test.go
  • pkg/terraform/clean/types.go
  • pkg/terraform/clean/deleter.go
  • pkg/terraform/generate/file_generator_test.go
  • internal/exec/terraform_clean_util.go
  • pkg/terraform/clean/errors.go
  • pkg/terraform/clean/collector.go
  • pkg/terraform/generate/adapter.go
  • pkg/terraform/generate/file_generator_internal_test.go
  • internal/exec/generate_adapter_funcs.go
  • cmd/terraform/clean.go
  • pkg/terraform/generate/generate.go
  • internal/exec/terraform_clean_test.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/clean/clean.go
  • pkg/terraform/generate/file_generator.go
  • pkg/terraform/clean/adapter.go
  • pkg/terraform/generate/generate_test.go
**/*_test.go

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

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

**/*_test.go: Prefer unit tests with mocks over integration tests; use interfaces + dependency injection for testability; generate mocks with go.uber.org/mock/mockgen; use table-driven tests; target >80% coverage
Test behavior, not implementation; never test stub functions; avoid tautological tests; make code testable via DI; no coverage theater; remove always-skipped tests; use errors.Is() for error checking

Files:

  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_e2e_test.go
  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/file_generator_internal_test.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/generate/generate_test.go
cmd/**/*.go

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

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

cmd/**/*.go: Commands MUST use flags.NewStandardParser() for command-specific flags; NEVER call viper.BindEnv() or viper.BindPFlag() directly (Forbidigo enforces this); see cmd/version/version.go for reference
Embed CLI examples from cmd/markdown/*_usage.md using //go:embed; render with utils.PrintfMarkdown()

Files:

  • cmd/terraform/clean.go
🧠 Learnings (59)
📓 Common learnings
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:37.766Z
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.
📚 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_clean_integration_test.go
  • pkg/terraform/clean/validation.go
  • internal/exec/terraform_clean_e2e_test.go
  • pkg/terraform/clean/types.go
  • pkg/terraform/clean/deleter.go
  • internal/exec/terraform_clean_util.go
  • pkg/terraform/clean/errors.go
  • pkg/terraform/clean/collector.go
  • cmd/terraform/clean.go
  • internal/exec/terraform_clean_test.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/clean/clean.go
  • pkg/terraform/clean/adapter.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_clean_integration_test.go
  • pkg/terraform/clean/validation.go
  • internal/exec/terraform_clean_e2e_test.go
  • pkg/terraform/clean/types.go
  • pkg/terraform/clean/deleter.go
  • internal/exec/terraform_clean_util.go
  • pkg/terraform/clean/errors.go
  • pkg/terraform/clean/collector.go
  • cmd/terraform/clean.go
  • internal/exec/terraform_clean_test.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/clean/clean.go
  • pkg/terraform/clean/adapter.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:

  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_e2e_test.go
  • pkg/terraform/clean/types.go
  • internal/exec/terraform_clean_util.go
  • cmd/terraform/clean.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/clean/clean.go
📚 Learning: 2024-10-27T04:28:40.966Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:155-175
Timestamp: 2024-10-27T04:28:40.966Z
Learning: In the `CollectDirectoryObjects` function in `internal/exec/terraform_clean.go`, recursive search through all subdirectories is not needed.

Applied to files:

  • internal/exec/terraform_clean_integration_test.go
  • pkg/terraform/clean/validation.go
  • internal/exec/terraform_clean_e2e_test.go
  • pkg/terraform/clean/types.go
  • pkg/terraform/clean/deleter.go
  • internal/exec/terraform_clean_util.go
  • pkg/terraform/clean/collector.go
  • cmd/terraform/clean.go
  • internal/exec/terraform_clean_test.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/clean/clean.go
  • pkg/terraform/clean/adapter.go
📚 Learning: 2025-04-26T15:54:10.506Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1195
File: internal/exec/terraform_clean.go:99-99
Timestamp: 2025-04-26T15:54:10.506Z
Learning: The error variable `ErrRelPath` is defined in `internal/exec/terraform_clean_util.go` and is used across files in the `exec` package, including in `terraform_clean.go`. This is part of an approach to standardize error handling in the codebase.

Applied to files:

  • internal/exec/terraform_clean_integration_test.go
  • pkg/terraform/clean/validation.go
  • internal/exec/terraform_clean_e2e_test.go
  • pkg/terraform/clean/types.go
  • pkg/terraform/clean/deleter.go
  • internal/exec/terraform_clean_util.go
  • pkg/terraform/clean/errors.go
  • pkg/terraform/clean/collector.go
  • cmd/terraform/clean.go
  • internal/exec/terraform_clean_test.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/clean/clean.go
  • pkg/terraform/clean/adapter.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_clean_integration_test.go
  • internal/exec/terraform_clean_e2e_test.go
  • pkg/terraform/clean/types.go
  • internal/exec/terraform_clean_util.go
  • pkg/terraform/clean/errors.go
  • pkg/terraform/clean/collector.go
  • pkg/terraform/generate/file_generator_internal_test.go
  • internal/exec/generate_adapter_funcs.go
  • cmd/terraform/clean.go
  • pkg/terraform/generate/generate.go
  • internal/exec/terraform_clean_test.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/clean/clean.go
  • pkg/terraform/generate/file_generator.go
  • pkg/terraform/clean/adapter.go
  • pkg/terraform/generate/generate_test.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_clean_integration_test.go
  • internal/exec/terraform_clean_e2e_test.go
  • internal/exec/terraform_clean_util.go
  • pkg/terraform/clean/errors.go
  • pkg/terraform/clean/collector.go
  • internal/exec/generate_adapter_funcs.go
  • cmd/terraform/clean.go
  • internal/exec/terraform_clean_test.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/clean/clean.go
  • pkg/terraform/clean/adapter.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_clean_integration_test.go
  • internal/exec/terraform_clean_e2e_test.go
  • pkg/terraform/clean/deleter.go
  • internal/exec/terraform_clean_util.go
  • pkg/terraform/clean/errors.go
  • pkg/terraform/clean/collector.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/clean/clean.go
  • pkg/terraform/clean/adapter.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:

  • internal/exec/terraform_clean_integration_test.go
  • pkg/terraform/clean/validation.go
  • internal/exec/terraform_clean_e2e_test.go
  • pkg/terraform/clean/types.go
  • pkg/terraform/clean/deleter.go
  • internal/exec/terraform_clean_util.go
  • pkg/terraform/clean/collector.go
  • cmd/terraform/clean.go
  • pkg/terraform/clean/clean.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:

  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_e2e_test.go
  • internal/exec/terraform_clean_test.go
📚 Learning: 2025-12-10T18:32:51.237Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1808
File: cmd/terraform/backend/backend_delete_test.go:9-23
Timestamp: 2025-12-10T18:32:51.237Z
Learning: In cmd subpackages (e.g., cmd/terraform/backend/), tests cannot use cmd.NewTestKit(t) due to Go's test visibility rules (NewTestKit is in a parent package test file). These tests only need TestKit if they execute commands through RootCmd or modify RootCmd state. Structural tests that only verify command structure/flags without touching RootCmd don't require TestKit cleanup.

Applied to files:

  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_e2e_test.go
  • pkg/terraform/generate/file_generator_internal_test.go
  • internal/exec/terraform_clean_test.go
📚 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:

  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_e2e_test.go
  • cmd/terraform/clean.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/clean/clean.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:

  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_e2e_test.go
📚 Learning: 2025-12-16T18:20:55.614Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.614Z
Learning: Applies to cmd/**/*_test.go : ALWAYS use cmd.NewTestKit(t) for cmd tests to auto-clean RootCmd state (flags, args)

Applied to files:

  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_e2e_test.go
  • internal/exec/terraform_clean_test.go
📚 Learning: 2025-12-16T18:20:55.614Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.614Z
Learning: Applies to **/*_test.go : Test behavior, not implementation; never test stub functions; avoid tautological tests; make code testable via DI; no coverage theater; remove always-skipped tests; use errors.Is() for error checking

Applied to files:

  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_e2e_test.go
  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/file_generator_internal_test.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/generate/generate_test.go
📚 Learning: 2024-10-27T04:54:32.397Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:314-319
Timestamp: 2024-10-27T04:54:32.397Z
Learning: When deleting empty folders in the `deleteFolders` function, handling errors from `os.Remove` are not required, as failures do not affect the process.

Applied to files:

  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_e2e_test.go
  • pkg/terraform/clean/deleter.go
  • pkg/terraform/clean/collector.go
  • internal/exec/terraform_clean_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: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests. This is implemented through custom testing framework extensions and is used consistently throughout the test suite.

Applied to files:

  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_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: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests.

Applied to files:

  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_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:

  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_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: In the atmos codebase, t.Chdir() is a valid method that can be called on *testing.T objects. This functionality is implemented through custom testing framework extensions and is used consistently throughout the test suite for changing working directories during tests.

Applied to files:

  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_test.go
📚 Learning: 2025-03-21T17:35:56.827Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 984
File: internal/exec/go_getter_utils.go:234-248
Timestamp: 2025-03-21T17:35:56.827Z
Learning: When removing symlinks in Go, using os.Remove(path) is sufficient as it removes the symlink reference itself without affecting the target. filepath.Walk doesn't follow symlinks by default, so there's no need for special handling of nested symlink structures.

Applied to files:

  • internal/exec/terraform_clean_integration_test.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:

  • internal/exec/terraform_clean_e2e_test.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/terraform/clean/types.go
  • internal/exec/terraform_clean_util.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/terraform/clean/types.go
  • internal/exec/generate_adapter_funcs.go
  • cmd/terraform/clean.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:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/file_generator_internal_test.go
  • pkg/terraform/generate/generate_test.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:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/file_generator_internal_test.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/generate/generate_test.go
📚 Learning: 2025-12-16T18:20:55.614Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.614Z
Learning: Applies to **/*_test.go : Prefer unit tests with mocks over integration tests; use interfaces + dependency injection for testability; generate mocks with go.uber.org/mock/mockgen; use table-driven tests; target >80% coverage

Applied to files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/file_generator_internal_test.go
  • pkg/terraform/generate/generate_test.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 : Use table-driven tests for testing multiple scenarios in Go

Applied to files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/file_generator_internal_test.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/generate/generate_test.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_clean_util.go
  • pkg/terraform/generate/adapter.go
  • internal/exec/generate_adapter_funcs.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/clean/adapter.go
  • pkg/terraform/generate/generate_test.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/terraform/clean/errors.go
📚 Learning: 2025-12-16T18:20:55.614Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.614Z
Learning: Applies to **/*.go : All errors MUST be wrapped using static errors defined in errors/errors.go; use errors.Join for combining multiple errors; use fmt.Errorf with %w for adding string context; use error builder for complex errors; use errors.Is() for error checking; NEVER use dynamic errors directly

Applied to files:

  • pkg/terraform/clean/errors.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:

  • pkg/terraform/clean/errors.go
📚 Learning: 2024-10-27T04:34:08.011Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:183-187
Timestamp: 2024-10-27T04:34:08.011Z
Learning: In the `getStackTerraformStateFolder` function, it's acceptable and not an error if no Terraform state folders are found for a stack.

Applied to files:

  • pkg/terraform/clean/collector.go
  • internal/exec/terraform_clean_test.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:

  • pkg/terraform/generate/adapter.go
  • internal/exec/generate_adapter_funcs.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/clean/adapter.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:

  • pkg/terraform/generate/adapter.go
  • internal/exec/generate_adapter_funcs.go
  • pkg/terraform/generate/generate.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/generate/generate_test.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:

  • pkg/terraform/generate/adapter.go
  • internal/exec/generate_adapter_funcs.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 interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations

Applied to files:

  • pkg/terraform/generate/file_generator_internal_test.go
  • pkg/terraform/generate/generate_test.go
📚 Learning: 2025-12-16T18:20:55.614Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.614Z
Learning: Applies to **/*.go : Keep files small and focused (<600 lines); one cmd/impl per file; co-locate tests; never use //revive:disable:file-length-limit

Applied to files:

  • pkg/terraform/generate/file_generator_internal_test.go
📚 Learning: 2025-12-16T18:20:55.614Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.614Z
Learning: Applies to **/*.go : Use go.uber.org/mock/mockgen with //go:generate directives for mock generation; never create manual mocks

Applied to files:

  • pkg/terraform/generate/file_generator_internal_test.go
  • pkg/terraform/generate/generate_test.go
📚 Learning: 2025-12-16T18:20:55.614Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.614Z
Learning: Define interfaces for all major functionality and use dependency injection for testability; generate mocks with go.uber.org/mock/mockgen

Applied to files:

  • pkg/terraform/generate/file_generator_internal_test.go
  • pkg/terraform/generate/generate_test.go
📚 Learning: 2025-01-25T03:49:03.951Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: internal/exec/template_utils.go:268-271
Timestamp: 2025-01-25T03:49:03.951Z
Learning: The `ProcessTmplWithDatasourcesGomplate` function in `internal/exec/template_utils.go` is used for documentation generation purposes, where simple environment variable handling is acceptable and thread-safety concerns are not critical.

Applied to files:

  • pkg/terraform/generate/file_generator_internal_test.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/generate_adapter_funcs.go
  • internal/exec/clean_adapter_funcs.go
📚 Learning: 2024-12-03T05:18:49.169Z
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.

Applied to files:

  • internal/exec/generate_adapter_funcs.go
  • internal/exec/clean_adapter_funcs.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/clean.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 initializing CLI config via cfg.InitCliConfig, always first populate the ConfigAndStacksInfo struct with global flag values by calling flags.ParseGlobalFlags(cmd, v) before LoadConfig. LoadConfig (pkg/config/load.go) reads config selection fields (AtmosConfigFilesFromArg, AtmosConfigDirsFromArg, BasePath, ProfilesFromArg) from the ConfigAndStacksInfo struct, not from Viper. Passing an empty struct causes the --base-path, --config, --config-path, and --profile flags to be ignored. Recommended pattern: parse flags → populate struct → call InitCliConfig. See cmd/terraform/plan_diff.go for reference implementation.

Applied to files:

  • cmd/terraform/clean.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/clean.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/clean.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/terraform/clean.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/clean.go
📚 Learning: 2025-12-13T06:10:25.156Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: internal/exec/workflow_utils.go:0-0
Timestamp: 2025-12-13T06:10:25.156Z
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:

  • internal/exec/terraform_clean_test.go
📚 Learning: 2025-12-13T03:21:35.786Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1813
File: cmd/terraform/shell.go:28-73
Timestamp: 2025-12-13T03:21:35.786Z
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:

  • internal/exec/terraform_clean_test.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:

  • internal/exec/terraform_clean_test.go
📚 Learning: 2025-08-16T23:33:07.477Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:651-652
Timestamp: 2025-08-16T23:33:07.477Z
Learning: In the cloudposse/atmos Go codebase, ExecuteDescribeDependents expects a pointer to AtmosConfiguration (*schema.AtmosConfiguration), so when calling it with a value returned by cfg.InitCliConfig (which returns schema.AtmosConfiguration), the address-of operator (&) is necessary: ExecuteDescribeDependents(&atmosConfig, ...).

Applied to files:

  • internal/exec/terraform_clean_test.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:

  • internal/exec/terraform_clean_test.go
📚 Learning: 2025-12-16T18:20:55.614Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.614Z
Learning: Applies to **/*.go : Organize imports in three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages; maintain aliases: cfg, log, u, errUtils

Applied to files:

  • internal/exec/terraform_clean_test.go
📚 Learning: 2025-12-13T04:37:25.223Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/root.go:0-0
Timestamp: 2025-12-13T04:37:25.223Z
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:

  • internal/exec/terraform_clean_test.go
📚 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:

  • internal/exec/terraform_clean_test.go
  • pkg/terraform/clean/clean.go
📚 Learning: 2024-12-25T20:28:47.526Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 887
File: internal/exec/stack_processor_utils.go:380-380
Timestamp: 2024-12-25T20:28:47.526Z
Learning: Windows path handling often requires `filepath.Join` to ensure correct separators and comparisons. Insufficient tests can break cross-platform compatibility, so migrating from `path.Join` to `filepath.Join` needs thorough testing on Windows before merging.

Applied to files:

  • internal/exec/terraform_clean_test.go
🧬 Code graph analysis (12)
internal/exec/terraform_clean_integration_test.go (1)
pkg/terraform/clean/deleter.go (1)
  • DeletePath (16-38)
internal/exec/terraform_clean_e2e_test.go (1)
pkg/terraform/clean/deleter.go (1)
  • DeletePath (16-38)
pkg/terraform/clean/types.go (1)
internal/exec/terraform_clean_util.go (1)
  • ObjectInfo (20-20)
pkg/terraform/generate/file_generator_test.go (2)
pkg/terraform/generate/file_generator.go (3)
  • GenerateConfig (27-32)
  • GenerateFiles (52-87)
  • GetGenerateFilenames (152-164)
cmd/cmd_utils.go (1)
  • Contains (1257-1264)
internal/exec/terraform_clean_util.go (2)
pkg/terraform/clean/types.go (2)
  • ObjectInfo (7-12)
  • Directory (15-20)
pkg/terraform/clean/errors.go (11)
  • ErrParseTerraformComponents (7-7)
  • ErrParseComponentsAttributes (8-8)
  • ErrEmptyPath (10-10)
  • ErrPathNotExist (11-11)
  • ErrFileStat (12-12)
  • ErrMatchPattern (13-13)
  • ErrRootPath (21-21)
  • ErrReadDir (14-14)
  • ErrFailedFoundStack (15-15)
  • ErrEmptyEnvDir (17-17)
  • ErrRefusingToDeleteDir (19-19)
pkg/terraform/generate/adapter.go (3)
pkg/schema/schema.go (2)
  • AtmosConfiguration (54-99)
  • ConfigAndStacksInfo (668-764)
pkg/perf/perf.go (1)
  • Track (121-138)
internal/exec/utils.go (2)
  • ProcessStacks (412-888)
  • FindStacksMap (274-324)
pkg/terraform/generate/file_generator_internal_test.go (3)
cmd/cmd_utils.go (1)
  • Contains (1257-1264)
errors/errors.go (2)
  • ErrUnsupportedInputType (53-53)
  • ErrInvalidConfig (49-49)
pkg/terraform/generate/file_generator.go (1)
  • GenerateResult (35-48)
cmd/terraform/clean.go (5)
pkg/terraform/clean/clean.go (2)
  • Options (73-80)
  • NewService (64-70)
pkg/terraform/clean/adapter.go (1)
  • NewExecAdapter (47-67)
internal/exec/clean_adapter_funcs.go (6)
  • ProcessStacksForClean (12-18)
  • ExecuteDescribeStacksForClean (21-33)
  • CollectComponentsDirectoryObjectsForClean (36-64)
  • ConstructTerraformComponentVarfileNameForClean (67-71)
  • ConstructTerraformComponentPlanfileNameForClean (74-78)
  • GetAllStacksComponentsPathsForClean (81-85)
internal/exec/generate_adapter_funcs.go (1)
  • GetGenerateFilenamesForComponent (46-50)
pkg/terraform/generate/generate.go (1)
  • NewService (51-57)
internal/exec/clean_adapter_funcs.go (3)
internal/exec/utils.go (1)
  • ProcessStacks (412-888)
internal/exec/terraform_clean_util.go (2)
  • Directory (21-21)
  • ObjectInfo (20-20)
pkg/terraform/clean/types.go (2)
  • Directory (15-20)
  • ObjectInfo (7-12)
pkg/terraform/clean/clean.go (7)
internal/exec/utils.go (1)
  • ProcessStacks (412-888)
internal/exec/generate_adapter_funcs.go (1)
  • GetGenerateFilenamesForComponent (46-50)
internal/exec/terraform_clean_util.go (2)
  • CollectComponentsDirectoryObjects (94-108)
  • Directory (21-21)
pkg/terraform/clean/types.go (2)
  • Directory (15-20)
  • EnvTFDataDir (4-4)
errors/errors.go (2)
  • ErrNilParam (564-564)
  • ErrInteractiveNotAvailable (243-243)
pkg/terraform/clean/errors.go (3)
  • ErrComponentNotFound (23-23)
  • ErrDescribeStack (9-9)
  • ErrUserAborted (22-22)
pkg/terraform/clean/collector.go (1)
  • GetStackTerraformStateFolder (180-210)
pkg/terraform/generate/file_generator.go (3)
pkg/auth/types/interfaces.go (1)
  • Path (31-53)
pkg/perf/perf.go (1)
  • Track (121-138)
errors/errors.go (2)
  • ErrInvalidConfig (49-49)
  • ErrUnsupportedInputType (53-53)
pkg/terraform/generate/generate_test.go (1)
pkg/terraform/generate/generate.go (9)
  • NewService (51-57)
  • GetGenerateSectionFromComponent (249-262)
  • GetFilenamesForComponent (266-274)
  • BuildTemplateContext (277-309)
  • BuildTemplateContextFromSection (313-335)
  • IsAbstractComponent (369-379)
  • GetComponentPath (382-392)
  • MatchesStackFilter (395-412)
  • ExtractTerraformSection (415-434)
⏰ 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 (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 17, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (7)
internal/exec/generate_adapter_funcs_test.go (1)

75-83: Good defensive test for invalid input.

Testing the invalid generate section type ensures the function handles malformed data gracefully. If you prefer, this could be added to the table-driven test above, but keeping it separate is perfectly fine.

Optional: consolidate into table-driven test

You could add this case to the table in TestGetGenerateFilenamesForComponent:

+		{
+			name: "Invalid generate section type",
+			componentSection: map[string]any{
+				"generate": "not a map",
+			},
+			expectedFiles: nil,
+		},

Then remove the separate test function. But the current structure is also clear.

cmd/terraform/clean_test.go (3)

10-15: Structural validation only.

This test verifies command metadata (Use, Short, Long) but doesn't exercise actual behavior. While useful for catching wiring issues, consider adding tests that execute the command with various inputs and verify outcomes.


17-27: Flag presence verified, behavior untested.

The test confirms flags are registered but doesn't validate parsing behavior, flag interactions, or how they affect command execution. Consider adding tests that set flag values and verify the resulting behavior.


1-61: Missing behavior and integration tests.

All tests validate structure (wiring, flag registration, attachment) but none exercise actual command behavior. Per coding guidelines, consider adding:

  1. Behavior tests: Execute the command with various flag combinations and verify outcomes (using mocks if needed for the underlying service).
  2. Integration tests: End-to-end tests with fixtures that validate the complete command flow.
  3. Error handling: Test how the command responds to invalid inputs or service errors.

Would you like me to generate example behavior tests showing how to mock the clean service and verify command execution?

pkg/terraform/clean/validation_test.go (1)

9-43: Solid validation tests, consider adding ".." path case.

The tests cover empty and root paths. Since IsValidDataDir also rejects paths containing "..", adding a test case for that would improve coverage.

🔎 Optional: Add ".." path test case
 		{
 			name:          "Valid TF_DATA_DIR",
 			tfDataDir:     "/valid/path",
 			expectedError: nil,
 		},
+		{
+			name:          "Path with parent traversal",
+			tfDataDir:     "/valid/../path",
+			expectedError: ErrRefusingToDelete,
+		},
 	}
internal/exec/terraform_clean_test.go (1)

41-49: Consider using t.Setenv for environment cleanup.

Per coding guidelines, tests should prefer t.Setenv for automatic setup/teardown instead of os.Unsetenv. This ensures proper cleanup even if the test fails.

🔎 Proposed fix
-	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", "")
internal/exec/clean_adapter_funcs.go (1)

35-61: Consider propagating atmosConfig for richer performance tracking.

The remaining wrappers use nil for atmosConfig in perf.Track() calls. While this is acceptable, if atmosConfig is available in the calling context (especially for CollectComponentsDirectoryObjectsForClean and the path collectors), consider propagating it for more contextual performance metrics.

This is a minor optimization and not required for correctness.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3bd6dfb and c38ff7f.

📒 Files selected for processing (18)
  • cmd/terraform/clean_test.go (1 hunks)
  • errors/errors.go (2 hunks)
  • internal/exec/clean_adapter_funcs.go (1 hunks)
  • internal/exec/clean_adapter_funcs_test.go (1 hunks)
  • internal/exec/generate_adapter_funcs_test.go (1 hunks)
  • internal/exec/terraform_clean_duplicate_test.go (0 hunks)
  • internal/exec/terraform_clean_e2e_test.go (0 hunks)
  • internal/exec/terraform_clean_integration_test.go (0 hunks)
  • internal/exec/terraform_clean_test.go (4 hunks)
  • internal/exec/terraform_clean_util.go (0 hunks)
  • internal/exec/terraform_clean_util_test.go (0 hunks)
  • pkg/config/const.go (1 hunks)
  • pkg/terraform/clean/adapter_test.go (1 hunks)
  • pkg/terraform/clean/clean_test.go (1 hunks)
  • pkg/terraform/clean/collector.go (1 hunks)
  • pkg/terraform/clean/collector_test.go (1 hunks)
  • pkg/terraform/clean/deleter_test.go (1 hunks)
  • pkg/terraform/clean/validation_test.go (1 hunks)
💤 Files with no reviewable changes (5)
  • internal/exec/terraform_clean_integration_test.go
  • internal/exec/terraform_clean_e2e_test.go
  • internal/exec/terraform_clean_util.go
  • internal/exec/terraform_clean_duplicate_test.go
  • internal/exec/terraform_clean_util_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/config/const.go
  • errors/errors.go
🧰 Additional context used
📓 Path-based instructions (4)
**/*.go

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

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

**/*.go: NEVER use fmt.Fprintf(os.Stdout/Stderr) or fmt.Println(); use data.* or ui.* functions instead
All comments must end with periods (enforced by godot linter)
Organize imports in three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages; maintain aliases: cfg, log, u, errUtils
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions for performance tracking; use nil if no atmosConfig param
All errors MUST be wrapped using static errors defined in errors/errors.go; use errors.Join for combining multiple errors; use fmt.Errorf with %w for adding string context; use error builder for complex errors; use 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
Keep files small...

Files:

  • internal/exec/generate_adapter_funcs_test.go
  • pkg/terraform/clean/adapter_test.go
  • internal/exec/clean_adapter_funcs_test.go
  • internal/exec/clean_adapter_funcs.go
  • cmd/terraform/clean_test.go
  • pkg/terraform/clean/deleter_test.go
  • pkg/terraform/clean/validation_test.go
  • pkg/terraform/clean/collector_test.go
  • pkg/terraform/clean/clean_test.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/clean/collector.go
**/*_test.go

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

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

**/*_test.go: Prefer unit tests with mocks over integration tests; use interfaces + dependency injection for testability; generate mocks with go.uber.org/mock/mockgen; use table-driven tests; target >80% coverage
Test behavior, not implementation; never test stub functions; avoid tautological tests; make code testable via DI; no coverage theater; remove always-skipped tests; use errors.Is() for error checking

Files:

  • internal/exec/generate_adapter_funcs_test.go
  • pkg/terraform/clean/adapter_test.go
  • internal/exec/clean_adapter_funcs_test.go
  • cmd/terraform/clean_test.go
  • pkg/terraform/clean/deleter_test.go
  • pkg/terraform/clean/validation_test.go
  • pkg/terraform/clean/collector_test.go
  • pkg/terraform/clean/clean_test.go
  • internal/exec/terraform_clean_test.go
cmd/**/*.go

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

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

cmd/**/*.go: Commands MUST use flags.NewStandardParser() for command-specific flags; NEVER call viper.BindEnv() or viper.BindPFlag() directly (Forbidigo enforces this); see cmd/version/version.go for reference
Embed CLI examples from cmd/markdown/*_usage.md using //go:embed; render with utils.PrintfMarkdown()

Files:

  • cmd/terraform/clean_test.go
cmd/**/*_test.go

📄 CodeRabbit inference engine (CLAUDE.md)

ALWAYS use cmd.NewTestKit(t) for cmd tests to auto-clean RootCmd state (flags, args)

Files:

  • cmd/terraform/clean_test.go
🧠 Learnings (51)
📓 Common learnings
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:37.766Z
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.
📚 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 : Use table-driven tests for testing multiple scenarios in Go

Applied to files:

  • internal/exec/generate_adapter_funcs_test.go
  • pkg/terraform/clean/adapter_test.go
  • pkg/terraform/clean/validation_test.go
  • internal/exec/terraform_clean_test.go
📚 Learning: 2025-12-16T18:20:55.630Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.630Z
Learning: Applies to **/*_test.go : Prefer unit tests with mocks over integration tests; use interfaces + dependency injection for testability; generate mocks with go.uber.org/mock/mockgen; use table-driven tests; target >80% coverage

Applied to files:

  • internal/exec/generate_adapter_funcs_test.go
  • pkg/terraform/clean/adapter_test.go
  • pkg/terraform/clean/clean_test.go
📚 Learning: 2025-12-16T18:20:55.630Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.630Z
Learning: Applies to **/*_test.go : Test behavior, not implementation; never test stub functions; avoid tautological tests; make code testable via DI; no coverage theater; remove always-skipped tests; use errors.Is() for error checking

Applied to files:

  • internal/exec/generate_adapter_funcs_test.go
  • pkg/terraform/clean/adapter_test.go
  • internal/exec/clean_adapter_funcs_test.go
  • cmd/terraform/clean_test.go
  • pkg/terraform/clean/deleter_test.go
  • pkg/terraform/clean/validation_test.go
  • pkg/terraform/clean/collector_test.go
  • pkg/terraform/clean/clean_test.go
  • internal/exec/terraform_clean_test.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:

  • internal/exec/generate_adapter_funcs_test.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:

  • internal/exec/generate_adapter_funcs_test.go
  • pkg/terraform/clean/adapter_test.go
  • internal/exec/clean_adapter_funcs_test.go
  • cmd/terraform/clean_test.go
  • pkg/terraform/clean/validation_test.go
  • pkg/terraform/clean/collector_test.go
  • pkg/terraform/clean/clean_test.go
  • internal/exec/terraform_clean_test.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:

  • internal/exec/generate_adapter_funcs_test.go
  • pkg/terraform/clean/adapter_test.go
  • cmd/terraform/clean_test.go
  • pkg/terraform/clean/validation_test.go
  • pkg/terraform/clean/collector_test.go
  • pkg/terraform/clean/clean_test.go
📚 Learning: 2025-12-16T18:20:55.630Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.630Z
Learning: Define interfaces for all major functionality and use dependency injection for testability; generate mocks with go.uber.org/mock/mockgen

Applied to files:

  • internal/exec/generate_adapter_funcs_test.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/generate_adapter_funcs_test.go
  • pkg/terraform/clean/adapter_test.go
  • internal/exec/clean_adapter_funcs_test.go
  • internal/exec/clean_adapter_funcs.go
  • cmd/terraform/clean_test.go
  • pkg/terraform/clean/clean_test.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/clean/collector.go
📚 Learning: 2025-12-10T18:32:51.237Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1808
File: cmd/terraform/backend/backend_delete_test.go:9-23
Timestamp: 2025-12-10T18:32:51.237Z
Learning: In cmd subpackages (e.g., cmd/terraform/backend/), tests cannot use cmd.NewTestKit(t) due to Go's test visibility rules (NewTestKit is in a parent package test file). These tests only need TestKit if they execute commands through RootCmd or modify RootCmd state. Structural tests that only verify command structure/flags without touching RootCmd don't require TestKit cleanup.

Applied to files:

  • pkg/terraform/clean/adapter_test.go
  • internal/exec/clean_adapter_funcs_test.go
  • pkg/terraform/clean/deleter_test.go
  • pkg/terraform/clean/validation_test.go
  • pkg/terraform/clean/collector_test.go
  • pkg/terraform/clean/clean_test.go
  • internal/exec/terraform_clean_test.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 interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations

Applied to files:

  • pkg/terraform/clean/adapter_test.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:

  • internal/exec/clean_adapter_funcs_test.go
  • internal/exec/clean_adapter_funcs.go
  • cmd/terraform/clean_test.go
  • pkg/terraform/clean/deleter_test.go
  • pkg/terraform/clean/validation_test.go
  • pkg/terraform/clean/collector_test.go
  • pkg/terraform/clean/clean_test.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/clean/collector.go
📚 Learning: 2024-10-27T04:28:40.966Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:155-175
Timestamp: 2024-10-27T04:28:40.966Z
Learning: In the `CollectDirectoryObjects` function in `internal/exec/terraform_clean.go`, recursive search through all subdirectories is not needed.

Applied to files:

  • internal/exec/clean_adapter_funcs_test.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/clean/deleter_test.go
  • pkg/terraform/clean/collector_test.go
  • pkg/terraform/clean/clean_test.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/clean/collector.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/clean_adapter_funcs_test.go
  • internal/exec/clean_adapter_funcs.go
  • cmd/terraform/clean_test.go
  • pkg/terraform/clean/deleter_test.go
  • pkg/terraform/clean/validation_test.go
  • pkg/terraform/clean/clean_test.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/clean/collector.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/clean_adapter_funcs_test.go
  • internal/exec/clean_adapter_funcs.go
  • cmd/terraform/clean_test.go
  • pkg/terraform/clean/collector_test.go
  • pkg/terraform/clean/clean_test.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/clean/collector.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/clean_adapter_funcs_test.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/clean/collector_test.go
  • pkg/terraform/clean/collector.go
📚 Learning: 2025-04-26T15:54:10.506Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1195
File: internal/exec/terraform_clean.go:99-99
Timestamp: 2025-04-26T15:54:10.506Z
Learning: The error variable `ErrRelPath` is defined in `internal/exec/terraform_clean_util.go` and is used across files in the `exec` package, including in `terraform_clean.go`. This is part of an approach to standardize error handling in the codebase.

Applied to files:

  • internal/exec/clean_adapter_funcs_test.go
  • internal/exec/clean_adapter_funcs.go
  • pkg/terraform/clean/deleter_test.go
  • pkg/terraform/clean/validation_test.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/clean/collector.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:

  • internal/exec/clean_adapter_funcs_test.go
  • pkg/terraform/clean/deleter_test.go
  • pkg/terraform/clean/validation_test.go
  • pkg/terraform/clean/collector_test.go
  • internal/exec/terraform_clean_test.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/clean_adapter_funcs.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/clean_adapter_funcs.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/clean_adapter_funcs.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:

  • internal/exec/clean_adapter_funcs.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:

  • internal/exec/clean_adapter_funcs.go
📚 Learning: 2024-12-03T05:18:49.169Z
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.

Applied to files:

  • internal/exec/clean_adapter_funcs.go
📚 Learning: 2025-12-10T18:32:43.260Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1808
File: cmd/terraform/backend/backend_delete_test.go:9-23
Timestamp: 2025-12-10T18:32:43.260Z
Learning: In cmd subpackages, tests should avoid using NewTestKit(t) unless tests actually interact with RootCmd (e.g., execute commands via RootCmd or modify RootCmd state). For structural tests that only verify command structure/flags without touching RootCmd, TestKit cleanup is unnecessary.

Applied to files:

  • cmd/terraform/clean_test.go
📚 Learning: 2025-12-16T18:20:55.630Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.630Z
Learning: Applies to cmd/**/*_test.go : ALWAYS use cmd.NewTestKit(t) for cmd tests to auto-clean RootCmd state (flags, args)

Applied to files:

  • cmd/terraform/clean_test.go
  • pkg/terraform/clean/deleter_test.go
  • pkg/terraform/clean/validation_test.go
  • pkg/terraform/clean/collector_test.go
  • pkg/terraform/clean/clean_test.go
  • internal/exec/terraform_clean_test.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/clean_test.go
📚 Learning: 2025-12-16T18:20:55.630Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.630Z
Learning: Applies to **/*.go : Keep files small and focused (<600 lines); one cmd/impl per file; co-locate tests; never use //revive:disable:file-length-limit

Applied to files:

  • cmd/terraform/clean_test.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/clean_test.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/clean_test.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/clean_test.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 initializing CLI config via cfg.InitCliConfig, always first populate the ConfigAndStacksInfo struct with global flag values by calling flags.ParseGlobalFlags(cmd, v) before LoadConfig. LoadConfig (pkg/config/load.go) reads config selection fields (AtmosConfigFilesFromArg, AtmosConfigDirsFromArg, BasePath, ProfilesFromArg) from the ConfigAndStacksInfo struct, not from Viper. Passing an empty struct causes the --base-path, --config, --config-path, and --profile flags to be ignored. Recommended pattern: parse flags → populate struct → call InitCliConfig. See cmd/terraform/plan_diff.go for reference implementation.

Applied to files:

  • cmd/terraform/clean_test.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/terraform/clean_test.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:

  • pkg/terraform/clean/deleter_test.go
  • internal/exec/terraform_clean_test.go
  • pkg/terraform/clean/collector.go
📚 Learning: 2024-10-27T04:54:32.397Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:314-319
Timestamp: 2024-10-27T04:54:32.397Z
Learning: When deleting empty folders in the `deleteFolders` function, handling errors from `os.Remove` are not required, as failures do not affect the process.

Applied to files:

  • pkg/terraform/clean/deleter_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: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests. This is implemented through custom testing framework extensions and is used consistently throughout the test suite.

Applied to files:

  • pkg/terraform/clean/deleter_test.go
  • pkg/terraform/clean/validation_test.go
  • pkg/terraform/clean/collector_test.go
  • internal/exec/terraform_clean_test.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/terraform/clean/deleter_test.go
  • internal/exec/terraform_clean_test.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/terraform/clean/deleter_test.go
  • internal/exec/terraform_clean_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: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests.

Applied to files:

  • pkg/terraform/clean/deleter_test.go
  • pkg/terraform/clean/validation_test.go
  • pkg/terraform/clean/collector_test.go
  • internal/exec/terraform_clean_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: In the atmos codebase, t.Chdir() is a valid method that can be called on *testing.T objects. This functionality is implemented through custom testing framework extensions and is used consistently throughout the test suite for changing working directories during tests.

Applied to files:

  • pkg/terraform/clean/validation_test.go
  • pkg/terraform/clean/collector_test.go
  • internal/exec/terraform_clean_test.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:

  • internal/exec/terraform_clean_test.go
  • pkg/terraform/clean/collector.go
📚 Learning: 2025-12-13T03:21:35.786Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1813
File: cmd/terraform/shell.go:28-73
Timestamp: 2025-12-13T03:21:35.786Z
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:

  • internal/exec/terraform_clean_test.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:

  • internal/exec/terraform_clean_test.go
📚 Learning: 2025-08-16T23:33:07.477Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:651-652
Timestamp: 2025-08-16T23:33:07.477Z
Learning: In the cloudposse/atmos Go codebase, ExecuteDescribeDependents expects a pointer to AtmosConfiguration (*schema.AtmosConfiguration), so when calling it with a value returned by cfg.InitCliConfig (which returns schema.AtmosConfiguration), the address-of operator (&) is necessary: ExecuteDescribeDependents(&atmosConfig, ...).

Applied to files:

  • internal/exec/terraform_clean_test.go
📚 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:

  • internal/exec/terraform_clean_test.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:

  • internal/exec/terraform_clean_test.go
📚 Learning: 2025-12-16T18:20:55.630Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.630Z
Learning: Applies to **/*.go : Organize imports in three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages; maintain aliases: cfg, log, u, errUtils

Applied to files:

  • internal/exec/terraform_clean_test.go
📚 Learning: 2025-12-13T04:37:25.223Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/root.go:0-0
Timestamp: 2025-12-13T04:37:25.223Z
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:

  • internal/exec/terraform_clean_test.go
📚 Learning: 2025-12-13T06:10:25.156Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: internal/exec/workflow_utils.go:0-0
Timestamp: 2025-12-13T06:10:25.156Z
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:

  • internal/exec/terraform_clean_test.go
📚 Learning: 2025-08-15T14:43:41.030Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1352
File: pkg/store/artifactory_store_test.go:108-113
Timestamp: 2025-08-15T14:43:41.030Z
Learning: In test files for the atmos project, it's acceptable to ignore errors from os.Setenv/Unsetenv operations during test environment setup and teardown, as these are controlled test scenarios.

Applied to files:

  • internal/exec/terraform_clean_test.go
📚 Learning: 2024-10-27T04:34:08.011Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:183-187
Timestamp: 2024-10-27T04:34:08.011Z
Learning: In the `getStackTerraformStateFolder` function, it's acceptable and not an error if no Terraform state folders are found for a stack.

Applied to files:

  • pkg/terraform/clean/collector.go
🧬 Code graph analysis (8)
internal/exec/generate_adapter_funcs_test.go (2)
internal/exec/generate_adapter_funcs.go (1)
  • GetGenerateFilenamesForComponent (46-50)
cmd/cmd_utils.go (1)
  • Contains (1257-1264)
pkg/terraform/clean/adapter_test.go (4)
pkg/terraform/clean/types.go (1)
  • Directory (15-20)
internal/exec/utils.go (1)
  • ProcessStacks (412-888)
internal/exec/generate_adapter_funcs.go (1)
  • GetGenerateFilenamesForComponent (46-50)
pkg/terraform/clean/collector.go (2)
  • CollectComponentsDirectoryObjects (315-347)
  • GetAllStacksComponentsPaths (256-277)
internal/exec/clean_adapter_funcs_test.go (3)
internal/exec/clean_adapter_funcs.go (4)
  • CollectComponentsDirectoryObjectsForClean (36-40)
  • GetAllStacksComponentsPathsForClean (57-61)
  • ConstructTerraformComponentVarfileNameForClean (43-47)
  • ConstructTerraformComponentPlanfileNameForClean (50-54)
cmd/cmd_utils.go (1)
  • Contains (1257-1264)
pkg/schema/schema.go (1)
  • ConfigAndStacksInfo (668-764)
internal/exec/clean_adapter_funcs.go (4)
pkg/schema/schema.go (2)
  • AtmosConfiguration (54-99)
  • ConfigAndStacksInfo (668-764)
pkg/perf/perf.go (1)
  • Track (121-138)
internal/exec/utils.go (1)
  • ProcessStacks (412-888)
pkg/terraform/clean/collector.go (2)
  • CollectComponentsDirectoryObjects (315-347)
  • GetAllStacksComponentsPaths (256-277)
pkg/terraform/clean/validation_test.go (2)
pkg/terraform/clean/errors.go (2)
  • ErrEmptyEnvDir (17-17)
  • ErrRefusingToDeleteDir (19-19)
pkg/terraform/clean/validation.go (1)
  • IsValidDataDir (12-37)
pkg/terraform/clean/collector_test.go (1)
pkg/terraform/clean/collector.go (5)
  • FindFoldersNamesWithPrefix (140-180)
  • CollectDirectoryObjects (19-134)
  • GetStackTerraformStateFolder (183-213)
  • CollectComponentsDirectoryObjects (315-347)
  • GetAllStacksComponentsPaths (256-277)
internal/exec/terraform_clean_test.go (3)
pkg/terraform/clean/clean.go (1)
  • Options (73-80)
pkg/terraform/clean/adapter.go (1)
  • NewExecAdapter (47-67)
internal/exec/clean_adapter_funcs.go (6)
  • ProcessStacksForClean (12-18)
  • ExecuteDescribeStacksForClean (21-33)
  • CollectComponentsDirectoryObjectsForClean (36-40)
  • ConstructTerraformComponentVarfileNameForClean (43-47)
  • ConstructTerraformComponentPlanfileNameForClean (50-54)
  • GetAllStacksComponentsPathsForClean (57-61)
pkg/terraform/clean/collector.go (3)
pkg/terraform/clean/types.go (2)
  • Directory (15-20)
  • ObjectInfo (7-12)
pkg/terraform/clean/errors.go (11)
  • ErrEmptyPath (10-10)
  • ErrPathNotExist (11-11)
  • ErrRelPath (24-24)
  • ErrFileStat (12-12)
  • ErrMatchPattern (13-13)
  • ErrReadDir (14-14)
  • ErrRootPath (21-21)
  • ErrFailedFoundStack (15-15)
  • ErrCollectFiles (16-16)
  • ErrParseTerraformComponents (7-7)
  • ErrParseComponentsAttributes (8-8)
pkg/terraform/clean/validation.go (1)
  • IsValidDataDir (12-37)
⏰ 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 (linux)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
🔇 Additional comments (32)
internal/exec/generate_adapter_funcs_test.go (2)

3-7: Import organization looks good.

The imports are correctly organized with stdlib and 3rd-party groups separated by a blank line.


9-73: Solid table-driven test with good coverage.

The test cases are comprehensive and correctly handle the unordered nature of map iteration by combining length assertions with containment checks. The nil vs. empty slice distinction is properly tested.

cmd/terraform/clean_test.go (1)

46-56: Validates command attachment.

Good structural check ensuring cleanCmd is properly registered as a subcommand of terraformCmd.

pkg/terraform/clean/deleter_test.go (5)

1-12: LGTM on imports and package structure.

Imports are properly organized into stdlib, third-party, and Atmos packages.


14-23: Good error handling test.

Clean verification that non-existent paths return os.IsNotExist errors.


70-95: Symlink test handles platform limitations well.

Using t.Skipf when symlink creation fails is the right approach for cross-platform compatibility.


115-164: Solid integration test for folder deletion.

Good coverage of the deleteFolders function with proper file/directory setup and verification.


271-279: Fix the comment: t.Setenv("") sets to empty string, not unsets.

The test works correctly, but the comment is misleading. t.Setenv(EnvTFDataDir, "") sets the environment variable to an empty string rather than unsetting it. The function uses os.Getenv with an == "" check, so both empty and unset produce the same behavior. Update the comment to clarify: "Ensure TF_DATA_DIR is empty or not set (both result in the same behavior with os.Getenv)."

pkg/terraform/clean/collector_test.go (4)

1-10: Clean package and imports.

Well-organized test file setup.


12-44: Table-driven error tests look good.

Uses require.ErrorIs correctly per coding guidelines for error checking.


465-617: Excellent end-to-end deduplication test.

This test validates the full flow from stack maps through deletion, ensuring files aren't deleted multiple times. Good use of tracking maps to verify uniqueness.


619-766: Thorough edge case coverage for GetAllStacksComponentsPaths.

Tests handle invalid structures, missing sections, and deduplication well.

pkg/terraform/clean/adapter_test.go (3)

14-32: Constructor test is appropriate.

Verifies NewExecAdapter returns a non-nil adapter with all dependencies wired.


34-63: Delegation test validates behavior correctly.

Confirms inputs are passed through and outputs are returned unchanged. The called flag ensures the delegate was actually invoked.


232-253: Interface compliance check is valuable.

The compile-time check var _ StackProcessor = adapter catches interface drift early.

internal/exec/terraform_clean_test.go (1)

85-105: Clean service wiring with real adapter functions.

Good integration test that exercises the full service layer with actual implementations.

internal/exec/clean_adapter_funcs_test.go (3)

1-12: Clean imports and package structure.

Properly organized for a test file in internal/exec.


14-34: Good filesystem-based delegation test.

Tests actual file collection behavior rather than just mocking, which provides meaningful coverage.


82-107: Varfile name construction tests validate expected format.

Tests confirm the naming convention follows the expected ContextPrefix-Component.terraform.tfvars.json pattern.

pkg/terraform/clean/clean_test.go (5)

14-73: Well-designed mock for testing.

The mock allows selective override of processor methods while providing sensible defaults. The nolint:gocritic directive is justified since the interface signature requires a value type.


131-201: Comprehensive path building tests.

Table-driven tests cover key scenarios: with/without base component, with stack, no component. Good use of filepath.Separator for cross-platform compatibility.


248-338: Thorough file initialization tests.

Tests verify correct pattern generation for various configurations including auto-generate settings and skip-lock-file flag.


584-625: Dry-run test correctly verifies no deletion.

Confirms files remain intact when DryRun: true is set.


627-668: Force flag test validates actual deletion.

Good end-to-end test that verifies files are actually deleted when the force flag is present.

internal/exec/clean_adapter_funcs.go (2)

9-18: LGTM - clean adapter wrapper.

The wrapper correctly derives shouldCheckStack from the presence of a stack name and delegates to the core ProcessStacks with appropriate defaults. Performance tracking and error propagation are properly implemented.


20-33: LGTM - straightforward delegation.

The wrapper provides a clean interface for the clean workflow by forwarding to ExecuteDescribeStacks with sensible defaults.

pkg/terraform/clean/collector.go (6)

16-134: LGTM - comprehensive directory collection with proper validation.

The function correctly handles recursive directory traversal with pattern matching, validates inputs, and uses cross-platform path operations. The complexity is acknowledged and inherent to the task. Error handling properly wraps errors with context.


136-180: LGTM - two-level prefix search with appropriate error handling.

The function performs a two-level directory search as intended (per learnings, recursive search not needed). The error handling is correct: level 1 errors are fatal, while level 2 errors are logged and skipped, allowing partial results.


182-213: LGTM - state folder collection with proper path handling.

The function correctly locates and collects Terraform state files, handles non-existent folders gracefully, and prefixes file names with folder context. Error wrapping is appropriate.


234-252: LGTM - proper TF_DATA_DIR handling with validation.

The function correctly uses os.Getenv with appropriate justification, validates the path before use, and handles errors gracefully. The nolint comment properly explains why direct environment variable access is needed here.


254-311: LGTM - component path extraction with proper deduplication.

Both functions correctly handle stack data parsing with type assertions, deduplicate component paths, and use static errors for consistent error handling. The public function includes performance tracking as required.


313-427: LGTM - well-structured component collection helpers.

The remaining functions provide a clean API for collecting component files with proper validation, deduplication, and error handling. Helper functions are appropriately factored, and all use cross-platform path operations.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 19, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Fix all issues with AI Agents 🤖
In @pkg/terraform/clean/validation_test.go:
- Around line 124-163: The test treats "C:\\" as valid unconditionally but
IsValidDataDir rejects Windows root paths on Windows; update
TestIsValidDataDir_WindowsRootPath to handle platform differences by inspecting
runtime.GOOS: if runtime.GOOS == "windows" expect an error for the "C:\\" case
(require.Error), otherwise expect no error (require.NoError), or alternatively
skip that subtest on Windows using t.Skipf; reference the IsValidDataDir
function and the Windows-root logic in validation.go when locating the change.
🧹 Nitpick comments (1)
docs/prd/code-generation.md (1)

156-163: Documentation style suggestions (optional for future cleanup).

LanguageTool flags several style preferences: em dashes in merge-behavior list items (lines 209–213), typographic quotation marks in the documentation updates table (lines 616–624), and a repeated word at line 600. These formatting refinements can be addressed in a separate documentation cleanup PR alongside any markdownlint fixes, following the pattern from prior PRDs. No content changes needed.

Also applies to: 209-213, 431-431, 600-600, 606-606, 616-624

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 37137b5 and b5f31f5.

📒 Files selected for processing (3)
  • docs/prd/code-generation.md
  • pkg/terraform/clean/validation_test.go
  • website/docs/cli/commands/terraform/workdir/workdir.mdx
🧰 Additional context used
📓 Path-based instructions (6)
docs/prd/**/*.md

📄 CodeRabbit inference engine (CLAUDE.md)

Place all Product Requirement Documents (PRDs) in docs/prd/ using kebab-case filenames

Files:

  • docs/prd/code-generation.md
**/*.go

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

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

**/*.go: All comments must end with periods (enforced by godot linter) in Go code
Organize imports into three groups separated by blank lines, sorted alphabetically: Go stdlib, 3rd-party (NOT cloudposse/atmos), then Atmos packages with maintained aliases (cfg, log, u, errUtils)
All errors MUST be wrapped using static errors defined in errors/errors.go - use errors.Join for combining errors, fmt.Errorf with %w for context, and errors.Is() for error checking
Never manually create mocks - use go.uber.org/mock/mockgen with //go:generate directives in Go code
Keep files small and focused - under 600 lines with one cmd/impl per file, co-locate tests, never use //revive:disable:file-length-limit
Use colors from pkg/ui/theme/colors.go for all UI theming in Go code
Code must be compatible with Linux, macOS, and Windows - use SDKs over binaries, use filepath.Join() instead of h...

Files:

  • pkg/terraform/clean/validation_test.go
**/*_test.go

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

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

Prefer unit tests with mocks over integration tests - use interfaces and dependency injection for testability, generate mocks with go.uber.org/mock/mockgen, use table-driven tests, target >80% coverage

Files:

  • pkg/terraform/clean/validation_test.go
**/{pkg,internal,cmd}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Add defer perf.Track(atmosConfig, "pkg.FuncName")() plus blank line to all public functions, using nil if no atmosConfig param - exceptions: trivial getters/setters, command constructors, simple factories, functions delegating to tracked functions

Files:

  • pkg/terraform/clean/validation_test.go
website/**

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

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

Files:

  • website/docs/cli/commands/terraform/workdir/workdir.mdx
website/docs/cli/commands/**/*.mdx

📄 CodeRabbit inference engine (CLAUDE.md)

All CLI command documentation MUST include: frontmatter, Intro component, Screengrab, Usage section, Arguments/Flags in <dl> format, and Examples section

Files:

  • website/docs/cli/commands/terraform/workdir/workdir.mdx
🧠 Learnings (35)
📓 Common learnings
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:37.766Z
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: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
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.
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.
📚 Learning: 2025-12-13T06:07:34.794Z
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: For docs in the cloudposse/atmos repository under docs/prd/, markdownlint issues MD040, MD010, and MD034 should be deferred to a separate documentation cleanup commit and must not block the current PR. If needed, address these issues in a follow-up PR dedicated to documentation improvements.

Applied to files:

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

Applied to files:

  • docs/prd/code-generation.md
📚 Learning: 2025-12-13T03:21:35.786Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1813
File: cmd/terraform/shell.go:28-73
Timestamp: 2025-12-13T03:21:35.786Z
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:

  • docs/prd/code-generation.md
📚 Learning: 2025-12-13T04:37:25.223Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/root.go:0-0
Timestamp: 2025-12-13T04:37:25.223Z
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:

  • docs/prd/code-generation.md
📚 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:

  • docs/prd/code-generation.md
📚 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:

  • docs/prd/code-generation.md
📚 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:

  • docs/prd/code-generation.md
  • website/docs/cli/commands/terraform/workdir/workdir.mdx
📚 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:

  • docs/prd/code-generation.md
📚 Learning: 2025-08-16T23:33:07.477Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:651-652
Timestamp: 2025-08-16T23:33:07.477Z
Learning: In the cloudposse/atmos Go codebase, ExecuteDescribeDependents expects a pointer to AtmosConfiguration (*schema.AtmosConfiguration), so when calling it with a value returned by cfg.InitCliConfig (which returns schema.AtmosConfiguration), the address-of operator (&) is necessary: ExecuteDescribeDependents(&atmosConfig, ...).

Applied to files:

  • docs/prd/code-generation.md
📚 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:

  • docs/prd/code-generation.md
📚 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:

  • docs/prd/code-generation.md
📚 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:

  • pkg/terraform/clean/validation_test.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 : Use table-driven tests for testing multiple scenarios in Go

Applied to files:

  • pkg/terraform/clean/validation_test.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:

  • pkg/terraform/clean/validation_test.go
📚 Learning: 2025-12-10T18:32:51.237Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1808
File: cmd/terraform/backend/backend_delete_test.go:9-23
Timestamp: 2025-12-10T18:32:51.237Z
Learning: In cmd subpackages (e.g., cmd/terraform/backend/), tests cannot use cmd.NewTestKit(t) due to Go's test visibility rules (NewTestKit is in a parent package test file). These tests only need TestKit if they execute commands through RootCmd or modify RootCmd state. Structural tests that only verify command structure/flags without touching RootCmd don't require TestKit cleanup.

Applied to files:

  • pkg/terraform/clean/validation_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:

  • pkg/terraform/clean/validation_test.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:

  • pkg/terraform/clean/validation_test.go
📚 Learning: 2026-01-04T00:55:21.698Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.698Z
Learning: Applies to cmd/**/*_test.go : Always use `cmd.NewTestKit(t)` for cmd tests to auto-clean RootCmd state

Applied to files:

  • pkg/terraform/clean/validation_test.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:

  • pkg/terraform/clean/validation_test.go
📚 Learning: 2025-04-26T15:54:10.506Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1195
File: internal/exec/terraform_clean.go:99-99
Timestamp: 2025-04-26T15:54:10.506Z
Learning: The error variable `ErrRelPath` is defined in `internal/exec/terraform_clean_util.go` and is used across files in the `exec` package, including in `terraform_clean.go`. This is part of an approach to standardize error handling in the codebase.

Applied to files:

  • pkg/terraform/clean/validation_test.go
📚 Learning: 2025-02-05T11:10:51.031Z
Learnt from: mss
Repo: cloudposse/atmos PR: 1024
File: internal/exec/go_getter_utils.go:31-33
Timestamp: 2025-02-05T11:10:51.031Z
Learning: The path traversal check in `ValidateURI` function in `internal/exec/go_getter_utils.go` is intentionally kept despite potentially blocking valid Git URLs, as this validation is planned to be addressed in a separate ticket.

Applied to files:

  • pkg/terraform/clean/validation_test.go
📚 Learning: 2024-12-25T20:28:47.526Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 887
File: internal/exec/stack_processor_utils.go:380-380
Timestamp: 2024-12-25T20:28:47.526Z
Learning: Windows path handling often requires `filepath.Join` to ensure correct separators and comparisons. Insufficient tests can break cross-platform compatibility, so migrating from `path.Join` to `filepath.Join` needs thorough testing on Windows before merging.

Applied to files:

  • pkg/terraform/clean/validation_test.go
📚 Learning: 2024-12-25T20:28:19.618Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 887
File: internal/exec/workflow_utils.go:167-169
Timestamp: 2024-12-25T20:28:19.618Z
Learning: The user plans to revert the change from `path.Join` to `filepath.Join` in this PR due to testing gaps and will open a new PR to safely handle the migration without breaking `main`.

Applied to files:

  • pkg/terraform/clean/validation_test.go
📚 Learning: 2024-10-23T20:13:23.054Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 731
File: pkg/utils/file_utils.go:198-202
Timestamp: 2024-10-23T20:13:23.054Z
Learning: In `pkg/utils/file_utils.go`, the current implementation of the `IsURL` function is considered sufficient; avoid suggesting more complex URL validation in future reviews.

Applied to files:

  • pkg/terraform/clean/validation_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: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests. This is implemented through custom testing framework extensions and is used consistently throughout the test suite.

Applied to files:

  • pkg/terraform/clean/validation_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: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests.

Applied to files:

  • pkg/terraform/clean/validation_test.go
📚 Learning: 2025-12-21T04:10:29.030Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: internal/exec/describe_affected.go:468-468
Timestamp: 2025-12-21T04:10:29.030Z
Learning: In Go, package-level declarations (constants, variables, types, and functions) are visible to all files in the same package without imports. During reviews in cloudposse/atmos (and similar Go codebases), before suggesting to declare a new identifier, first check if it already exists in another file of the same package. If it exists, you can avoid adding a new declaration; if not, proceed with a proper package-level declaration. 

Applied to files:

  • pkg/terraform/clean/validation_test.go
📚 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/workdir/workdir.mdx
📚 Learning: 2026-01-04T00:55:21.698Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.698Z
Learning: Applies to website/docs/cli/commands/**/*.mdx : All CLI command documentation MUST include: frontmatter, Intro component, Screengrab, Usage section, Arguments/Flags in `<dl>` format, and Examples section

Applied to files:

  • website/docs/cli/commands/terraform/workdir/workdir.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/workdir/workdir.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/workdir/workdir.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/docs/cli/commands/terraform/workdir/workdir.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 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:

  • website/docs/cli/commands/terraform/workdir/workdir.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/workdir/workdir.mdx
🧬 Code graph analysis (1)
pkg/terraform/clean/validation_test.go (2)
pkg/terraform/clean/errors.go (3)
  • ErrEmptyEnvDir (17-17)
  • ErrRefusingToDeleteDir (19-19)
  • ErrRefusingToDelete (20-20)
pkg/terraform/clean/validation.go (1)
  • IsValidDataDir (12-37)
🪛 LanguageTool
docs/prd/code-generation.md

[typographical] ~209-~209: To join two clauses or introduce examples, consider using an em dash.
Context: ...obal level** (generate: at stack root) - lowest priority 2. **Component type leve...

(DASH_RULE)


[typographical] ~210-~210: To join two clauses or introduce examples, consider using an em dash.
Context: ...ent type level** (terraform.generate:) - applies to all terraform components 3. *...

(DASH_RULE)


[typographical] ~211-~211: To join two clauses or introduce examples, consider using an em dash.
Context: ...ponent level** (via metadata.inherits) - inherited from parent components 4. **Co...

(DASH_RULE)


[typographical] ~212-~212: To join two clauses or introduce examples, consider using an em dash.
Context: ...** (components.terraform.vpc.generate) - component-specific 5. *Overrides level...

(DASH_RULE)


[typographical] ~213-~213: To join two clauses or introduce examples, consider using an em dash.
Context: ...evel** (terraform.overrides.generate:) - highest priority, file-scoped Files mer...

(DASH_RULE)


[grammar] ~431-~431: Please add a punctuation mark at the end of paragraph.
Context: ... via GenerateCmd.AddCommand(filesCmd) in init() 2. **Update GenerateCmd help ...

(PUNCTUATION_PARAGRAPH_END)


[typographical] ~433-~433: Consider using typographic quotation marks here.
Context: .... Update GenerateCmd help text: Add "files" to the list in `cmd/terraform/generate/...

(EN_QUOTES)


[style] ~600-~600: This word has been used in one of the immediately preceding sentences. Using a synonym could make your text more interesting to read, unless the repetition is intentional.
Context: ... return files } ``` No separate flag needed - this follows the existing pattern w...

(EN_REPEATEDWORDS_NEED)


[typographical] ~605-~605: Consider using typographic quotation marks here.
Context: ... The terraform clean command accesses info.ComponentSection["generate"] to get the list of filenames - Cleanu...

(EN_QUOTES)


[grammar] ~606-~606: Please add a punctuation mark at the end of paragraph.
Context: ...e configured filenames in the component directory ## Documentation Updates Required Whe...

(PUNCTUATION_PARAGRAPH_END)


[typographical] ~616-~616: Consider using a typographic opening quote here.
Context: ...site/docs/intro/faq.mdx` (line 95-97) | "Atmos does not promote code generation f...

(EN_QUOTES)


[typographical] ~616-~616: Consider using a typographic close quote here.
Context: ...promote code generation for root modules" | Clarify: Atmos now supports declarati...

(EN_QUOTES)


[typographical] ~617-~617: Consider using a typographic opening quote here.
Context: ...te/docs/intro/features.mdx` (line 72) | "No code generation — configuration stays...

(EN_QUOTES)


[typographical] ~617-~617: Consider using a typographic close quote here.
Context: ...iguration stays in YAML, HCL stays clean" | Update to reflect generate section ...

(EN_QUOTES)


[typographical] ~618-~618: Consider using a typographic opening quote here.
Context: ...bsite/docs/intro/index.mdx` (line 97) | "No code generation, no templates" | Upda...

(EN_QUOTES)


[typographical] ~618-~618: Consider using a typographic close quote here.
Context: ... 97) | "No code generation, no templates" | Update messaging to distinguish from ...

(EN_QUOTES)


[typographical] ~619-~619: Consider using a typographic opening quote here.
Context: ...e/docs/learn/why-atmos.mdx` (line 39) | "No code generation or messy templating" ...

(EN_QUOTES)


[typographical] ~619-~619: Consider using a typographic close quote here.
Context: ... "No code generation or messy templating" | Clarify the declarative generation ap...

(EN_QUOTES)


[typographical] ~620-~620: Consider using a typographic opening quote here.
Context: ...cs/learn/stacks/stacks.mdx` (line 26) | "without any code generation" | Update to...

(EN_QUOTES)


[typographical] ~620-~620: Consider using a typographic close quote here.
Context: ...(line 26) | "without any code generation" | Update to reflect new capability | | ...

(EN_QUOTES)


[typographical] ~621-~621: Consider using a typographic opening quote here.
Context: ...ite/docs/learn/mindset.mdx` (line 19) | "without the need to write any code or me...

(EN_QUOTES)


[typographical] ~621-~621: Consider using a typographic close quote here.
Context: ...e or messy templates for code generation" | Refine messaging | | `website/docs/be...

(EN_QUOTES)


[typographical] ~622-~622: Consider using a typographic opening quote here.
Context: ...ctices/components.mdx` (line 146-157) | "Reserve Code Generation as an Escape Hat...

(EN_QUOTES)


[typographical] ~622-~622: Consider using a typographic close quote here.
Context: ...ation as an Escape Hatch for Emergencies" | Distinguish between arbitrary HCL cod...

(EN_QUOTES)


[typographical] ~623-~623: Consider using a typographic opening quote here.
Context: ...st-practices/stacks.mdx` (line 69-75) | "Reserve Code Generation for Stack Config...

(EN_QUOTES)


[typographical] ~623-~623: Consider using a typographic close quote here.
Context: ... Code Generation for Stack Configuration" | Add reference to new generate secti...

(EN_QUOTES)


[typographical] ~624-~624: Consider using a typographic opening quote here.
Context: .../migration/terragrunt.mdx` (line 309) | "Atmos intentionally does not provide...

(EN_QUOTES)


[typographical] ~624-~624: Consider using a typographic close quote here.
Context: ...e full-fledged arbitrary file generation" | Update to document the new generate...

(EN_QUOTES)

website/docs/cli/commands/terraform/workdir/workdir.mdx

[uncategorized] ~61-~61: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...* - Components are fetched and prepared on demand - Clean separation - Each stack's c...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[style] ~62-~62: Since ownership is already implied, this phrasing may be redundant.
Context: ...* - Each stack's component instance has its own working directory ## Examples ### Lis...

(PRP_OWN)


[typographical] ~99-~99: To join two clauses or introduce examples, consider using an em dash.
Context: ...sioning](/cli/commands/terraform/source) - Just-in-time component fetching - [Terra...

(DASH_RULE)


[typographical] ~100-~100: To join two clauses or introduce examples, consider using an em dash.
Context: ...rm Clean](/cli/commands/terraform/clean) - Clean component directories

(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). (3)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
🔇 Additional comments (6)
website/docs/cli/commands/terraform/workdir/workdir.mdx (2)

1-48: Arguments/Flags section successfully added.

The documentation now includes all required sections per coding guidelines: frontmatter, Intro, Screengrab, Usage, Arguments (in <dl> format), Flags, and Examples. This addresses the previous review feedback.


44-44: Change the global flags link to the correct destination.

The link should point to /cli/global-flags instead of /cli/configuration. The statement references "global flags" but currently links to the Configuration Overview page, which covers different types of configuration files rather than CLI flags.

docs/prd/code-generation.md (2)

313-427: Example code correctly demonstrates flag parsing pattern.

The command implementation example properly populates the ConfigAndStacksInfo struct with global flags before calling InitCliConfig (lines 385–387). This follows the correct precedence pattern and ensures config-selection flags are respected.


1-648: Comprehensive PRD with clear structure and implementation guidance.

The document thoroughly covers feature design, configuration semantics, user-facing commands, and internal implementation touchpoints. The five-level merge model is well-explained with examples, and the documentation updates section explicitly identifies what existing docs need refreshing. Implementation notes are precise about the subcommand registration pattern and lifecycle hook integration.

pkg/terraform/clean/validation_test.go (2)

9-73: Solid coverage of basic validation scenarios.

The test cases cover empty paths, root paths, and various valid path formats. Error checking with require.ErrorIs properly validates sentinel errors.


75-122: Nice fix addressing the previous feedback.

The renamed test and updated comment clearly explain filepath.Abs normalization behavior. Test cases now properly distinguish between:

  • Embedded ".." in filenames (rejected)
  • Path traversal ".." resolved during normalization (accepted)

This resolves the past review concern about misleading parent reference checks.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 5, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Fix all issues with AI Agents 🤖
In @pkg/terraform/generate/file_generator_test.go:
- Around line 1-727: The test file pkg/terraform/generate/file_generator_test.go
is 727 lines, exceeding the 600-line guideline; split or refactor the many
TestGenerateFiles_* tests into smaller, focused units (e.g.,
file_generator_extensions_test.go for
YAML/JSON/HCL/HCLExtension/YMLExtension/UnknownExtensionDefaultsToJSON,
file_generator_modes_test.go for DryRun/Clean/CleanDryRun/CleanNonExistentFile,
file_generator_templates_test.go for
TemplateInMapValue/NestedArrayTemplates/TemplateError/NestedArraysInHCL/NestedArraysInHCL
etc.) or convert repetitive cases (TestGenerateFiles_StringContent, JSONContent,
YAMLContent, HCLContent, JSONPrettyPrinted, YAMLPrettyPrinted,
JSONPrettyPrinted, MultipleFiles, EmptyMap, NilValue, Int64Value, EmptySlice)
into table-driven tests against GenerateFiles/GenerateConfig to reduce
duplication; ensure each new file contains only related TestGenerateFiles_*
cases and keep helper setup (tempDir, common generateSection/templateContext)
shared via small helper functions to stay under 600 lines.
- Around line 1-727: The tests in file_generator_test.go contain many
near-duplicate TestGenerateFiles_* functions; refactor them into table-driven
tests that iterate test cases and use t.Run to cover extensions, modes
(dry-run/clean), content types, template behaviors, and edge cases while
preserving existing assertions and use of GenerateFiles and
GetGenerateFilenames. Create case structs that include name, generateSection,
templateContext, config (GenerateConfig), expected flags
(Created/Skipped/Deleted), and expected content checks; for each case call
t.TempDir(), invoke GenerateFiles, then run the same require/assert checks per
case (including reading files when needed) so behavior is identical. Group
related cases into separate table-driven test functions (e.g.,
TestGenerateFiles_Extensions, TestGenerateFiles_Modes,
TestGenerateFiles_ContentTypes, TestGenerateFiles_Templates,
TestGenerateFiles_EdgeCases) to keep tests readable, and use helper functions
inside the test file for repeated validation logic to avoid duplication. Ensure
error scenarios (template error, unsupported type) remain asserted per-case and
that nil input case still checks nil results from GenerateFiles.

In @pkg/terraform/generate/generate_test.go:
- Around line 15-46: The manual MockStackProcessor implementation (methods
ProcessStacks and FindStacksMap) should be replaced with a mock generated by
mockgen: add a //go:generate directive referencing the StackProcessor interface
and point it to mock_stack_processor_test.go, run mockgen to produce the
generated mock, then update tests to use the generated mock type instead of
MockStackProcessor and remove the manual type and its methods; ensure the
generated mock lives in package generate and matches the StackProcessor
interface signature.
🧹 Nitpick comments (2)
tests/fixtures/scenarios/terraform-generate-files/README.md (1)

7-7: Specify language for fenced code block.

The fenced code block lacks a language identifier. Add a language specifier (e.g., `` text ) for markdownlint compliance.

🔎 Proposed fix
-```
+```text
 terraform-generate-files/
pkg/terraform/generate/file_generator_test.go (1)

46-47: Consider constants for file extensions.

File extensions like .json, .yaml, .tf, .hcl are repeated throughout the tests. While acceptable in test code for clarity, extracting them as package-level constants would improve maintainability and align with the DRY principle.

const (
    extJSON = ".json"
    extYAML = ".yaml"
    extYML  = ".yml"
    extTF   = ".tf"
    extHCL  = ".hcl"
)

Also applies to: 77-78, 246-247, 467-468

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d240bfe and 3e7942f.

📒 Files selected for processing (5)
  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate.go
  • pkg/terraform/generate/generate_test.go
  • tests/fixtures/scenarios/terraform-generate-files/README.md
  • tests/fixtures/scenarios/terraform-generate-files/atmos.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/fixtures/scenarios/terraform-generate-files/atmos.yaml
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

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

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

**/*.go: All comments must end with periods (enforced by godot linter) in Go code
Organize imports into three groups separated by blank lines, sorted alphabetically: Go stdlib, 3rd-party (NOT cloudposse/atmos), then Atmos packages with maintained aliases (cfg, log, u, errUtils)
All errors MUST be wrapped using static errors defined in errors/errors.go - use errors.Join for combining errors, fmt.Errorf with %w for context, and errors.Is() for error checking
Never manually create mocks - use go.uber.org/mock/mockgen with //go:generate directives in Go code
Keep files small and focused - under 600 lines with one cmd/impl per file, co-locate tests, never use //revive:disable:file-length-limit
Use colors from pkg/ui/theme/colors.go for all UI theming in Go code
Code must be compatible with Linux, macOS, and Windows - use SDKs over binaries, use filepath.Join() instead of h...

Files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate.go
  • pkg/terraform/generate/generate_test.go
**/*_test.go

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

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

Prefer unit tests with mocks over integration tests - use interfaces and dependency injection for testability, generate mocks with go.uber.org/mock/mockgen, use table-driven tests, target >80% coverage

Files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate_test.go
**/{pkg,internal,cmd}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Add defer perf.Track(atmosConfig, "pkg.FuncName")() plus blank line to all public functions, using nil if no atmosConfig param - exceptions: trivial getters/setters, command constructors, simple factories, functions delegating to tracked functions

Files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate.go
  • pkg/terraform/generate/generate_test.go
🧠 Learnings (19)
📓 Common learnings
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:37.766Z
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: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
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.
📚 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:

  • pkg/terraform/generate/file_generator_test.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 : Use table-driven tests for testing multiple scenarios in Go

Applied to files:

  • pkg/terraform/generate/file_generator_test.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:

  • pkg/terraform/generate/file_generator_test.go
📚 Learning: 2026-01-04T00:55:21.698Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.698Z
Learning: Applies to **/*_test.go : Prefer unit tests with mocks over integration tests - use interfaces and dependency injection for testability, generate mocks with `go.uber.org/mock/mockgen`, use table-driven tests, target >80% coverage

Applied to files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate_test.go
📚 Learning: 2026-01-04T00:55:21.698Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.698Z
Learning: Applies to **/*.go : Never manually create mocks - use `go.uber.org/mock/mockgen` with `//go:generate` directives in Go code

Applied to files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate_test.go
📚 Learning: 2026-01-04T00:55:21.698Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.698Z
Learning: Applies to **/*.go : Keep files small and focused - under 600 lines with one cmd/impl per file, co-locate tests, never use `//revive:disable:file-length-limit`

Applied to files:

  • pkg/terraform/generate/file_generator_test.go
📚 Learning: 2025-12-21T04:10:29.030Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: internal/exec/describe_affected.go:468-468
Timestamp: 2025-12-21T04:10:29.030Z
Learning: In Go, package-level declarations (constants, variables, types, and functions) are visible to all files in the same package without imports. During reviews in cloudposse/atmos (and similar Go codebases), before suggesting to declare a new identifier, first check if it already exists in another file of the same package. If it exists, you can avoid adding a new declaration; if not, proceed with a proper package-level declaration. 

Applied to files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate.go
  • pkg/terraform/generate/generate_test.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:

  • pkg/terraform/generate/generate.go
  • pkg/terraform/generate/generate_test.go
📚 Learning: 2025-12-24T04:29:23.938Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: pkg/ci/terraform/templates/apply.md:17-17
Timestamp: 2025-12-24T04:29:23.938Z
Learning: In the cloudposse/atmos repository, Terraform CI templates (pkg/ci/terraform/templates/*.md) are rendered using TerraformTemplateContext (defined in pkg/ci/terraform/context.go), not the base ci.TemplateContext. TerraformTemplateContext provides top-level fields: .Resources (ci.ResourceCounts), .HasChanges() method, and .HasDestroy field, which are correctly accessed directly in templates without a .Result prefix.

Applied to files:

  • pkg/terraform/generate/generate.go
  • tests/fixtures/scenarios/terraform-generate-files/README.md
📚 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:

  • pkg/terraform/generate/generate.go
  • pkg/terraform/generate/generate_test.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 interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations

Applied to files:

  • pkg/terraform/generate/generate_test.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:

  • pkg/terraform/generate/generate_test.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:

  • pkg/terraform/generate/generate_test.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:

  • pkg/terraform/generate/generate_test.go
📚 Learning: 2025-01-25T03:44:52.619Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md:14-23
Timestamp: 2025-01-25T03:44:52.619Z
Learning: Test fixtures under `tests/fixtures/` should not be modified unless the test case itself needs to change, as they are deliberately set up to represent specific scenarios for testing purposes.

Applied to files:

  • tests/fixtures/scenarios/terraform-generate-files/README.md
📚 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/fixtures/scenarios/terraform-generate-files/README.md
📚 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/fixtures/scenarios/terraform-generate-files/README.md
📚 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/fixtures/scenarios/terraform-generate-files/README.md
🧬 Code graph analysis (1)
pkg/terraform/generate/file_generator_test.go (3)
pkg/terraform/generate/file_generator.go (3)
  • GenerateConfig (36-41)
  • GenerateFiles (61-96)
  • GetGenerateFilenames (161-173)
pkg/provisioner/workdir/clean.go (1)
  • Clean (96-123)
cmd/cmd_utils.go (1)
  • Contains (1303-1310)
🪛 LanguageTool
tests/fixtures/scenarios/terraform-generate-files/README.md

[typographical] ~61-~61: To join two clauses or introduce examples, consider using an em dash.
Context: ... - components/terraform/vpc/locals.tf - HCL locals block - `components/terraform...

(DASH_RULE)

🪛 markdownlint-cli2 (0.18.1)
tests/fixtures/scenarios/terraform-generate-files/README.md

7-7: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

⏰ 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 (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
🔇 Additional comments (12)
tests/fixtures/scenarios/terraform-generate-files/README.md (1)

1-62: Good test fixture documentation.

The README clearly documents the fixture structure, scenarios, commands, and expected outputs. This provides helpful context for understanding and extending the test suite. The layout is well-organized and aligns with the terraform-generate feature implementation.

pkg/terraform/generate/file_generator_test.go (1)

12-727: Comprehensive test coverage—well done.

The test suite thoroughly covers the generate functionality with excellent scenario coverage: multiple formats (JSON, YAML, HCL), modes (dry-run, clean), edge cases (nil values, empty maps, nested arrays), templates, and error conditions. The use of require for critical assertions and assert for non-blocking checks is appropriate.

pkg/terraform/generate/generate.go (10)

16-43: LGTM!

Good use of constants for magic strings and a well-defined interface with proper documentation. The StackProcessor interface enables effective dependency injection and testing.


45-57: LGTM!

Clean service pattern with proper dependency injection and performance tracking.


59-116: LGTM!

Well-structured method with proper error handling, early returns for edge cases, and good logging. Performance tracking and cross-platform path handling are correctly implemented.


118-154: LGTM!

The method correctly iterates through stacks with filtering support. The design choice to not propagate errors from processStackForGenerate is intentional—it maximizes successful file generation across components by logging errors and continuing (see line 244-246 comment).


156-183: LGTM!

Clean implementation of auto-generation support with proper guard clauses and appropriate hard-coded config for automatic execution.


185-247: LGTM!

These helper functions implement a resilient processing strategy—they log errors and continue rather than failing fast. This maximizes successful file generation across components, as documented in the comment on line 244-245.


249-275: LGTM!

Clean helper functions with proper nil handling and performance tracking. Good separation of concerns.


277-310: Verify that sensitive data exposure in template context is acceptable.

The template context includes backend configuration, provider settings, and environment variables (lines 303-306), which may contain sensitive data like credentials or API keys. While Go templates provide powerful data access, exposing the full component context could be a security concern if templates are sourced from untrusted locations or if generated files are committed to version control.

Consider whether sensitive fields should be filtered or if additional documentation/warnings are needed for users about template security practices.

Based on PR objectives: "Template context security: rendering exposes full component context (including backend/provider/auth); consider filtering sensitive fields."


338-440: LGTM!

These helper functions implement safe type assertions, clear logic, and good documentation. The MatchesStackFilter function's support for both full paths and basenames provides user-friendly filtering.


1-3: Add period to complete package documentation.

The second line of the package comment is missing a trailing period.

🔎 Proposed fix
 // Package generate provides functionality to generate files for Terraform components
-// from the generate section in Atmos stack configuration.
+// from the generate section in Atmos stack configuration.
 package generate

As per coding guidelines: "All comments must end with periods (enforced by godot linter) in Go code."

⛔ Skipped due to learnings
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.698Z
Learning: Applies to **/*.go : All comments must end with periods (enforced by `godot` linter) in Go code
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.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.698Z
Learning: Applies to **/{pkg,internal,cmd}/**/*.go : Add `defer perf.Track(atmosConfig, "pkg.FuncName")()` plus blank line to all public functions, using `nil` if no atmosConfig param - exceptions: trivial getters/setters, command constructors, simple factories, functions delegating to tracked functions
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.698Z
Learning: Applies to **/*.go : Organize imports into three groups separated by blank lines, sorted alphabetically: Go stdlib, 3rd-party (NOT cloudposse/atmos), then Atmos packages with maintained aliases (`cfg`, `log`, `u`, `errUtils`)
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 all exported functions, types, and methods following Go's documentation conventions
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
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`.
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
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: internal/exec/describe_affected.go:468-468
Timestamp: 2025-12-21T04:10:39.086Z
Learning: In Go, package-level constants, variables, types, and functions declared in any file within a package are automatically accessible to all other files in the same package without imports or redeclaration. When reviewing Go code in the cloudposse/atmos repository (or any Go codebase), verify whether a seemingly undefined identifier exists in other files within the same package before suggesting to add it.
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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Fix all issues with AI Agents 🤖
In @tests/fixtures/scenarios/terraform-generate-files/README.md:
- Around line 57-63: Update the "Generated Files" list in README.md to include
the missing YAML artifact: add an entry for
`components/terraform/vpc/config.yaml` (or whichever YAML filename the "File
Type Generation" section specifies) alongside `locals.tf`, `metadata.json`, and
`README.md` so the Generated Files section documents all four output types (HCL,
JSON, YAML, Markdown) consistently.
🧹 Nitpick comments (3)
tests/fixtures/scenarios/terraform-generate-files/README.md (2)

61-61: Minor: Use em dash instead of hyphen for clarity.

Line 61 uses a hyphen to separate the file path from its description. Per the grammar rule DASH_RULE, consider using an em dash (—) to better join the two related clauses:

- `components/terraform/vpc/locals.tf` — HCL locals block
- `components/terraform/vpc/metadata.json` — JSON metadata
- `components/terraform/vpc/README.md` — Markdown documentation

1-63: Consider documenting cleanup strategy for generated test artifacts.

This fixture generates files into the component directories. To prevent generated files from polluting the test fixture state or version control, clarify whether:

  • A .gitignore entry should ignore generated files in this fixture, or
  • The --clean command is expected to remove them after tests complete, or
  • Tests clean up artifacts explicitly.

This is especially relevant if integration tests run repeatedly against the same fixture.

pkg/terraform/generate/generate_test.go (1)

1-14: File exceeds the 600-line guideline.

At 888 lines, this test file is well over the limit. Consider splitting into focused test files:

  • generate_helpers_test.go for helper function tests (GetGenerateSectionFromComponent, BuildTemplateContext, IsAbstractComponent, etc.)
  • generate_service_test.go for Service method tests (ExecuteForComponent, ExecuteForAll, GenerateFilesForComponent)

This would improve maintainability and align with the coding guidelines.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3e7942f and ad99e3b.

📒 Files selected for processing (5)
  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate.go
  • pkg/terraform/generate/generate_test.go
  • pkg/terraform/generate/mock_stack_processor_test.go
  • tests/fixtures/scenarios/terraform-generate-files/README.md
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

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

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

**/*.go: All comments must end with periods (enforced by godot linter) in Go code
Organize imports into three groups separated by blank lines, sorted alphabetically: Go stdlib, 3rd-party (NOT cloudposse/atmos), then Atmos packages with maintained aliases (cfg, log, u, errUtils)
All errors MUST be wrapped using static errors defined in errors/errors.go - use errors.Join for combining errors, fmt.Errorf with %w for context, and errors.Is() for error checking
Never manually create mocks - use go.uber.org/mock/mockgen with //go:generate directives in Go code
Keep files small and focused - under 600 lines with one cmd/impl per file, co-locate tests, never use //revive:disable:file-length-limit
Use colors from pkg/ui/theme/colors.go for all UI theming in Go code
Code must be compatible with Linux, macOS, and Windows - use SDKs over binaries, use filepath.Join() instead of h...

Files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate_test.go
  • pkg/terraform/generate/generate.go
  • pkg/terraform/generate/mock_stack_processor_test.go
**/*_test.go

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

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

Prefer unit tests with mocks over integration tests - use interfaces and dependency injection for testability, generate mocks with go.uber.org/mock/mockgen, use table-driven tests, target >80% coverage

Files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate_test.go
  • pkg/terraform/generate/mock_stack_processor_test.go
**/{pkg,internal,cmd}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Add defer perf.Track(atmosConfig, "pkg.FuncName")() plus blank line to all public functions, using nil if no atmosConfig param - exceptions: trivial getters/setters, command constructors, simple factories, functions delegating to tracked functions

Files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate_test.go
  • pkg/terraform/generate/generate.go
  • pkg/terraform/generate/mock_stack_processor_test.go
🧠 Learnings (19)
📓 Common learnings
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:37.766Z
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: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
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.
📚 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:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate_test.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 : Use table-driven tests for testing multiple scenarios in Go

Applied to files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate_test.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:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate_test.go
📚 Learning: 2026-01-04T00:55:21.698Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.698Z
Learning: Applies to **/*_test.go : Prefer unit tests with mocks over integration tests - use interfaces and dependency injection for testability, generate mocks with `go.uber.org/mock/mockgen`, use table-driven tests, target >80% coverage

Applied to files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate_test.go
  • pkg/terraform/generate/mock_stack_processor_test.go
📚 Learning: 2026-01-04T00:55:21.698Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.698Z
Learning: Applies to **/*.go : Keep files small and focused - under 600 lines with one cmd/impl per file, co-locate tests, never use `//revive:disable:file-length-limit`

Applied to files:

  • pkg/terraform/generate/file_generator_test.go
📚 Learning: 2026-01-04T00:55:21.698Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.698Z
Learning: Applies to **/*.go : Never manually create mocks - use `go.uber.org/mock/mockgen` with `//go:generate` directives in Go code

Applied to files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate_test.go
  • pkg/terraform/generate/mock_stack_processor_test.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/terraform/generate/file_generator_test.go
📚 Learning: 2025-12-21T04:10:29.030Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: internal/exec/describe_affected.go:468-468
Timestamp: 2025-12-21T04:10:29.030Z
Learning: In Go, package-level declarations (constants, variables, types, and functions) are visible to all files in the same package without imports. During reviews in cloudposse/atmos (and similar Go codebases), before suggesting to declare a new identifier, first check if it already exists in another file of the same package. If it exists, you can avoid adding a new declaration; if not, proceed with a proper package-level declaration. 

Applied to files:

  • pkg/terraform/generate/file_generator_test.go
  • pkg/terraform/generate/generate_test.go
  • pkg/terraform/generate/generate.go
  • pkg/terraform/generate/mock_stack_processor_test.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 interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations

Applied to files:

  • pkg/terraform/generate/generate_test.go
  • pkg/terraform/generate/mock_stack_processor_test.go
📚 Learning: 2025-12-10T18:32:51.237Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1808
File: cmd/terraform/backend/backend_delete_test.go:9-23
Timestamp: 2025-12-10T18:32:51.237Z
Learning: In cmd subpackages (e.g., cmd/terraform/backend/), tests cannot use cmd.NewTestKit(t) due to Go's test visibility rules (NewTestKit is in a parent package test file). These tests only need TestKit if they execute commands through RootCmd or modify RootCmd state. Structural tests that only verify command structure/flags without touching RootCmd don't require TestKit cleanup.

Applied to files:

  • pkg/terraform/generate/generate_test.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:

  • pkg/terraform/generate/generate_test.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:

  • pkg/terraform/generate/generate_test.go
  • pkg/terraform/generate/generate.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:

  • pkg/terraform/generate/generate.go
📚 Learning: 2025-12-24T04:29:23.938Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: pkg/ci/terraform/templates/apply.md:17-17
Timestamp: 2025-12-24T04:29:23.938Z
Learning: In the cloudposse/atmos repository, Terraform CI templates (pkg/ci/terraform/templates/*.md) are rendered using TerraformTemplateContext (defined in pkg/ci/terraform/context.go), not the base ci.TemplateContext. TerraformTemplateContext provides top-level fields: .Resources (ci.ResourceCounts), .HasChanges() method, and .HasDestroy field, which are correctly accessed directly in templates without a .Result prefix.

Applied to files:

  • pkg/terraform/generate/generate.go
  • tests/fixtures/scenarios/terraform-generate-files/README.md
📚 Learning: 2025-01-25T03:44:52.619Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md:14-23
Timestamp: 2025-01-25T03:44:52.619Z
Learning: Test fixtures under `tests/fixtures/` should not be modified unless the test case itself needs to change, as they are deliberately set up to represent specific scenarios for testing purposes.

Applied to files:

  • tests/fixtures/scenarios/terraform-generate-files/README.md
📚 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/fixtures/scenarios/terraform-generate-files/README.md
📚 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/fixtures/scenarios/terraform-generate-files/README.md
📚 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/fixtures/scenarios/terraform-generate-files/README.md
🧬 Code graph analysis (4)
pkg/terraform/generate/file_generator_test.go (1)
pkg/terraform/generate/file_generator.go (3)
  • GenerateConfig (36-41)
  • GenerateFiles (61-96)
  • GetGenerateFilenames (161-173)
pkg/terraform/generate/generate_test.go (2)
pkg/terraform/generate/generate.go (8)
  • GetGenerateSectionFromComponent (252-265)
  • GetFilenamesForComponent (269-277)
  • BuildTemplateContext (280-312)
  • BuildTemplateContextFromSection (316-338)
  • IsAbstractComponent (372-382)
  • GetComponentPath (385-395)
  • MatchesStackFilter (401-420)
  • ExtractTerraformSection (423-442)
pkg/terraform/generate/adapter.go (1)
  • NewExecAdapter (30-37)
pkg/terraform/generate/generate.go (4)
pkg/perf/perf.go (1)
  • Track (121-138)
pkg/terraform/generate/file_generator.go (3)
  • GenerateConfig (36-41)
  • GenerateFiles (61-96)
  • GetGenerateFilenames (161-173)
pkg/utils/slice_utils.go (1)
  • SliceContainsString (12-21)
pkg/config/const.go (1)
  • TerraformSectionName (83-83)
pkg/terraform/generate/mock_stack_processor_test.go (2)
internal/exec/utils.go (2)
  • FindStacksMap (275-325)
  • ProcessStacks (413-889)
pkg/schema/schema.go (2)
  • AtmosConfiguration (54-100)
  • ConfigAndStacksInfo (727-824)
🪛 LanguageTool
tests/fixtures/scenarios/terraform-generate-files/README.md

[typographical] ~61-~61: To join two clauses or introduce examples, consider using an em dash.
Context: ... - components/terraform/vpc/locals.tf - HCL locals block - `components/terraform...

(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). (3)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
🔇 Additional comments (14)
pkg/terraform/generate/file_generator_test.go (1)

1-515: Good refactoring work on the test structure.

The file now uses table-driven tests consistently and stays under the 600-line guideline. Coverage looks comprehensive across extensions, modes, content types, templates, HCL edge cases, and the helper function.

pkg/terraform/generate/generate_test.go (3)

114-152: Solid coverage on template context building.

Tests verify all expected context keys are populated correctly from ConfigAndStacksInfo. Good.


410-452: Good integration test with proper mock expectations.

The test correctly sets up mock expectations with DoAndReturn, creates the component directory, and verifies the generated file content. Clean approach.


863-888: Clean adapter wiring test.

Verifies both ProcessStacks and FindStacksMap are properly delegated through the adapter. Straightforward.

pkg/terraform/generate/mock_stack_processor_test.go (1)

1-10: Generated mock looks correct.

This is a properly generated gomock file per the //go:generate directive in generate.go. The previous feedback about manual mocks has been addressed.

pkg/terraform/generate/generate.go (9)

1-27: Well-organized file header and constants.

Good use of package-level constants for section and context keys. The //go:generate directive for mockgen is properly placed.


29-59: Clean interface-based design.

StackProcessor interface enables proper dependency injection and testability. The Service struct follows the pattern well.


61-118: Solid single-component execution flow.

Uses filepath.Join for cross-platform paths, propagates errors correctly, and logs appropriately when no generate section exists.


120-156: Reasonable error-tolerance strategy.

The method continues processing remaining stacks/components even when individual generation fails. This is logged at error level in processComponentForGenerate. For batch operations, this is sensible.


158-185: Appropriate auto-generation behavior.

Hardcoding DryRun: false and Clean: false makes sense for automatic file generation during terraform execution.


209-249: Handles abstract components and metadata paths correctly.

Skips abstract components and uses GetComponentPath to respect metadata.component overrides for shared components.


340-369: Clean extraction helpers.

extractVarsContext, extractSectionAsMap, and extractSectionAsString are focused utilities. Good separation.


397-420: User-friendly stack filtering.

Matching against both full path and basename gives flexibility. Using filepath.Match ensures cross-platform glob support.


422-442: Defensive extraction with proper constant usage.

Uses cfg.TerraformSectionName instead of a magic string. Type assertions handle malformed input gracefully.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
pkg/terraform/generate/generate_helpers_test.go (1)

64-100: Solid test coverage.

The test covers nil and valid scenarios well. Optionally, consider adding a test case for an empty generate section (i.e., "generate": map[string]any{}).

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ad99e3b and 2f1ac06.

📒 Files selected for processing (3)
  • pkg/terraform/generate/generate_helpers_test.go
  • pkg/terraform/generate/generate_service_test.go
  • tests/fixtures/scenarios/terraform-generate-files/README.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/fixtures/scenarios/terraform-generate-files/README.md
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

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

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

**/*.go: All comments must end with periods (enforced by godot linter) in Go code
Organize imports into three groups separated by blank lines, sorted alphabetically: Go stdlib, 3rd-party (NOT cloudposse/atmos), then Atmos packages with maintained aliases (cfg, log, u, errUtils)
All errors MUST be wrapped using static errors defined in errors/errors.go - use errors.Join for combining errors, fmt.Errorf with %w for context, and errors.Is() for error checking
Never manually create mocks - use go.uber.org/mock/mockgen with //go:generate directives in Go code
Keep files small and focused - under 600 lines with one cmd/impl per file, co-locate tests, never use //revive:disable:file-length-limit
Use colors from pkg/ui/theme/colors.go for all UI theming in Go code
Code must be compatible with Linux, macOS, and Windows - use SDKs over binaries, use filepath.Join() instead of h...

Files:

  • pkg/terraform/generate/generate_helpers_test.go
  • pkg/terraform/generate/generate_service_test.go
**/*_test.go

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

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

Prefer unit tests with mocks over integration tests - use interfaces and dependency injection for testability, generate mocks with go.uber.org/mock/mockgen, use table-driven tests, target >80% coverage

Files:

  • pkg/terraform/generate/generate_helpers_test.go
  • pkg/terraform/generate/generate_service_test.go
**/{pkg,internal,cmd}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Add defer perf.Track(atmosConfig, "pkg.FuncName")() plus blank line to all public functions, using nil if no atmosConfig param - exceptions: trivial getters/setters, command constructors, simple factories, functions delegating to tracked functions

Files:

  • pkg/terraform/generate/generate_helpers_test.go
  • pkg/terraform/generate/generate_service_test.go
🧠 Learnings (16)
📓 Common learnings
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:37.766Z
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: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: pkg/ci/terraform/templates/apply.md:17-17
Timestamp: 2025-12-24T04:29:23.938Z
Learning: In the cloudposse/atmos repository, Terraform CI templates (pkg/ci/terraform/templates/*.md) are rendered using TerraformTemplateContext (defined in pkg/ci/terraform/context.go), not the base ci.TemplateContext. TerraformTemplateContext provides top-level fields: .Resources (ci.ResourceCounts), .HasChanges() method, and .HasDestroy field, which are correctly accessed directly in templates without a .Result prefix.
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.
📚 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:

  • pkg/terraform/generate/generate_helpers_test.go
  • pkg/terraform/generate/generate_service_test.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:

  • pkg/terraform/generate/generate_helpers_test.go
  • pkg/terraform/generate/generate_service_test.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 : Use table-driven tests for testing multiple scenarios in Go

Applied to files:

  • pkg/terraform/generate/generate_helpers_test.go
  • pkg/terraform/generate/generate_service_test.go
📚 Learning: 2026-01-04T00:55:21.698Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.698Z
Learning: Applies to **/*_test.go : Prefer unit tests with mocks over integration tests - use interfaces and dependency injection for testability, generate mocks with `go.uber.org/mock/mockgen`, use table-driven tests, target >80% coverage

Applied to files:

  • pkg/terraform/generate/generate_helpers_test.go
  • pkg/terraform/generate/generate_service_test.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:

  • pkg/terraform/generate/generate_helpers_test.go
  • pkg/terraform/generate/generate_service_test.go
📚 Learning: 2025-12-17T20:55:47.884Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1874
File: internal/exec/describe_affected_utils_test.go:436-468
Timestamp: 2025-12-17T20:55:47.884Z
Learning: In the Atmos codebase, there are two different paths for the `locked` flag: (1) filtering logic in `internal/exec/component_utils.go` (`isComponentLocked()`) reads from `componentSection["metadata"]["locked"]` to determine which components to include/exclude, and (2) extraction/rendering logic in `pkg/list/extract/affected.go` reads from `settings.metadata.locked` to display the locked status in output. Tests for filtering behavior should use `metadata.locked`.

Applied to files:

  • pkg/terraform/generate/generate_helpers_test.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:

  • pkg/terraform/generate/generate_helpers_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:

  • pkg/terraform/generate/generate_helpers_test.go
📚 Learning: 2025-12-24T04:29:23.938Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: pkg/ci/terraform/templates/apply.md:17-17
Timestamp: 2025-12-24T04:29:23.938Z
Learning: In the cloudposse/atmos repository, Terraform CI templates (pkg/ci/terraform/templates/*.md) are rendered using TerraformTemplateContext (defined in pkg/ci/terraform/context.go), not the base ci.TemplateContext. TerraformTemplateContext provides top-level fields: .Resources (ci.ResourceCounts), .HasChanges() method, and .HasDestroy field, which are correctly accessed directly in templates without a .Result prefix.

Applied to files:

  • pkg/terraform/generate/generate_helpers_test.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/terraform/generate/generate_helpers_test.go
📚 Learning: 2025-12-21T04:10:29.030Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: internal/exec/describe_affected.go:468-468
Timestamp: 2025-12-21T04:10:29.030Z
Learning: In Go, package-level declarations (constants, variables, types, and functions) are visible to all files in the same package without imports. During reviews in cloudposse/atmos (and similar Go codebases), before suggesting to declare a new identifier, first check if it already exists in another file of the same package. If it exists, you can avoid adding a new declaration; if not, proceed with a proper package-level declaration. 

Applied to files:

  • pkg/terraform/generate/generate_helpers_test.go
  • pkg/terraform/generate/generate_service_test.go
📚 Learning: 2026-01-04T00:55:21.698Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.698Z
Learning: Applies to **/*.go : Never manually create mocks - use `go.uber.org/mock/mockgen` with `//go:generate` directives in Go code

Applied to files:

  • pkg/terraform/generate/generate_service_test.go
📚 Learning: 2025-12-10T18:32:51.237Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1808
File: cmd/terraform/backend/backend_delete_test.go:9-23
Timestamp: 2025-12-10T18:32:51.237Z
Learning: In cmd subpackages (e.g., cmd/terraform/backend/), tests cannot use cmd.NewTestKit(t) due to Go's test visibility rules (NewTestKit is in a parent package test file). These tests only need TestKit if they execute commands through RootCmd or modify RootCmd state. Structural tests that only verify command structure/flags without touching RootCmd don't require TestKit cleanup.

Applied to files:

  • pkg/terraform/generate/generate_service_test.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 interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations

Applied to files:

  • pkg/terraform/generate/generate_service_test.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:

  • pkg/terraform/generate/generate_service_test.go
🧬 Code graph analysis (1)
pkg/terraform/generate/generate_helpers_test.go (2)
pkg/terraform/generate/generate.go (7)
  • GetGenerateSectionFromComponent (252-265)
  • GetFilenamesForComponent (269-277)
  • BuildTemplateContext (280-312)
  • BuildTemplateContextFromSection (316-338)
  • IsAbstractComponent (372-382)
  • MatchesStackFilter (401-420)
  • ExtractTerraformSection (423-442)
pkg/schema/schema.go (1)
  • ConfigAndStacksInfo (727-824)
⏰ 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 (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
🔇 Additional comments (20)
pkg/terraform/generate/generate_helpers_test.go (7)

11-62: LGTM!

Comprehensive table-driven test covering nil inputs, missing sections, valid data, and type mismatches. Good coverage of edge cases.


102-140: LGTM!

Thorough validation of template context construction with all expected fields verified.


142-167: LGTM!

Good validation of context extraction from component sections.


169-215: LGTM!

Complete coverage of abstract component detection logic with all edge cases.


217-258: LGTM!

Good coverage of component path resolution including fallback behavior.


260-341: LGTM!

Excellent comprehensive test coverage of stack filtering logic including glob patterns, basename matching, and edge cases.


343-396: LGTM!

Comprehensive edge case coverage for Terraform section extraction including nil handling and type validation.

pkg/terraform/generate/generate_service_test.go (13)

16-21: LGTM!

Basic but necessary test validating service construction.


23-65: LGTM!

Well-structured test using mocks and filesystem isolation. Properly verifies file generation and content.


67-90: LGTM!

Good negative test case validating graceful handling when generate section is absent.


92-138: LGTM!

Good test of bulk generation across stacks with proper filesystem verification.


140-160: LGTM!

Tests stack filtering behavior appropriately.


162-182: LGTM!

Good test validating early return when auto-generation is disabled.


184-208: LGTM!

Good negative test validating graceful handling when generate section is absent but auto-generation is enabled.


210-249: LGTM!

Good positive test case validating successful auto-generation with content verification.


251-305: LGTM!

Excellent test validating component filtering with both positive and negative verification.


307-352: LGTM!

Important test validating that abstract components are properly skipped during generation.


354-399: LGTM!

Important test validating metadata-based component path resolution for shared components.


401-447: LGTM!

Good edge case tests validating graceful handling of missing or invalid stack sections.


449-501: LGTM!

Good edge case test for invalid component sections and proper adapter pattern validation.

@aknysh aknysh merged commit 80c7937 into main Jan 5, 2026
57 checks passed
@aknysh aknysh deleted the osterman/generate-section-prd branch January 5, 2026 19:40
@github-actions
Copy link

github-actions bot commented Jan 6, 2026

These changes were released in v1.204.0-rc.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor New features that do not break anything size/xl Extra large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants