-
-
Notifications
You must be signed in to change notification settings - Fork 135
refactor: Replace CSV-based YAML function argument parsing #1834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…ar-aware parser
Eliminated painful CSV-based quote escaping in !terraform.state and
!terraform.output functions by implementing a simple, purpose-built parser that
exploits the grammar structure: component names and stack names never contain
spaces, while expressions always start with specific characters (., |, [, {, ",
').
The new parser:
- Removes need for double-quote escaping
- Handles any amount of whitespace (spaces, tabs, newlines)
- Maintains backward compatibility for simple syntax
- Reduces code complexity (~30 lines vs complex switch logic)
- Enables cleaner, more readable expressions
Updated documentation with clean syntax examples and YAML block scalar
demonstrations for complex multi-line expressions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Dependency Review✅ No vulnerabilities or license issues found.Scanned FilesNone |
|
Warning Changelog Entry RequiredThis PR is labeled Action needed: Add a new blog post in Example filename: Alternatively: If this change doesn't require a changelog entry, remove the |
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Relocated ParseArgs from pkg/utils to pkg/function for better organization. Renamed ParseFunctionArgs to ParseArgs since the package name provides context. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR refactors YAML function resolution to propagate errors as explicit return values instead of using exit-style error handling. A new argument parser in Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Areas requiring extra attention:
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Warning Rate limit exceeded@osterman has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 24 minutes and 19 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (10)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… exits Replaces CheckErrorPrintAndExit calls with proper error returns, allowing callers to handle errors gracefully. This improves testability and follows Go best practices for error propagation. Changes: - processTagTerraformState/Output now return (any, error) - processContextAwareTags/processSimpleTags now return (any, bool, error) - processCustomTags/processCustomTagsWithContext now return (any, error) - processNodes/processNodesWithContext now return (map[string]any, error) - Updated all tests to handle new error return values 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Codecov Report❌ Patch coverage is ❌ Your patch check has failed because the patch coverage (71.87%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #1834 +/- ##
==========================================
- Coverage 72.63% 72.61% -0.02%
==========================================
Files 521 522 +1
Lines 49598 49608 +10
==========================================
- Hits 36025 36024 -1
- Misses 10829 10831 +2
- Partials 2744 2753 +9
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this 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
🧹 Nitpick comments (1)
tests/fixtures/scenarios/atmos-terraform-output-yaml-function/stacks/deploy/nonprod.yaml (1)
38-41: Optional: Mirror the pipe-expression example from state fixtureThese three cases are good coverage for fallback behavior; if you want perfect symmetry with the
!terraform.statefixture, you could add atest_val-style YQ pipe example here as well, but it's 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.
📒 Files selected for processing (17)
internal/exec/yaml_func_resolution_context_bench_test.go(1 hunks)internal/exec/yaml_func_terraform_output.go(3 hunks)internal/exec/yaml_func_terraform_output_test.go(2 hunks)internal/exec/yaml_func_terraform_state.go(5 hunks)internal/exec/yaml_func_terraform_state_test.go(2 hunks)internal/exec/yaml_func_utils.go(9 hunks)internal/exec/yaml_func_utils_context_test.go(7 hunks)internal/exec/yaml_func_utils_test.go(3 hunks)internal/exec/yaml_processor.go(1 hunks)pkg/function/parser.go(1 hunks)pkg/function/parser_test.go(1 hunks)tests/fixtures/scenarios/atmos-terraform-output-yaml-function/stacks/deploy/nonprod.yaml(1 hunks)tests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/nonprod.yaml(1 hunks)tests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/prod.yaml(1 hunks)website/blog/2025-12-03-yaml-function-clean-syntax.mdx(1 hunks)website/docs/functions/yaml/terraform.output.mdx(3 hunks)website/docs/functions/yaml/terraform.state.mdx(3 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
tests/**/*.yaml
📄 CodeRabbit inference engine (CLAUDE.md)
NEVER modify
tests/test-cases/ortests/testdata/unless explicitly instructed. Golden snapshots are sensitive to minor changes. Use fixtures intests/test-cases/:atmos.yaml,stacks/,components/
Files:
tests/fixtures/scenarios/atmos-terraform-output-yaml-function/stacks/deploy/nonprod.yamltests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/prod.yamltests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/nonprod.yaml
**/*.go
📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context usingfmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: usegofmtandgoimportsto format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging
**/*.go: All comments must end with periods (enforced bygodotlinter)
Import organization: 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
Adddefer perf.Track(atmosConfig, "pkg.FuncName")()+ blank line to all public functions. Usenilif no atmosConfig param
Keep files small and focused (<600 lines). One cmd/impl per file. Co-locate tests. Never use//revive:disable:file-length-limit
Use sentinel errors fromerrors/errors.gowith ErrorBuilder for all user-facing errors. Useerrors.Is()for checking errors, never string comparison.WithCause()preserves underlying error messages,WithExplanation()adds context,WithHint()provides guidance,WithContext()adds key-value pairs
Usecontext.Contextas first parameter for: cancellation signals (prop...
Files:
internal/exec/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gopkg/function/parser.gointernal/exec/yaml_func_terraform_state_test.gointernal/exec/yaml_func_utils_context_test.gointernal/exec/yaml_func_resolution_context_bench_test.gopkg/function/parser_test.gointernal/exec/yaml_func_utils.gointernal/exec/yaml_processor.gointernal/exec/yaml_func_terraform_output_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: Useassert.ErrorIs(t, err, ErrSentinel)for checking our own errors and stdlib errors. Only use string matching for third-party errors
NEVER useassert.Contains(err.Error(), ...)for error checking. ALWAYS useassert.ErrorIs()instead. NEVER use string comparison:err.Error() == "..."orstrings.Contains(err.Error(), ...)
Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoidos.Exit,CheckErrorPrintAndExit, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios
Usego.uber.org/mock/mockgenwith//go:generatedirectives for mock generation. Never create manual mocks. Pattern://go:generate go run go.uber.org/mock/mockgen@latest -source=filename.go -destination=mock_filename_test.go
Use table-driven tests for comprehensive coverage. Tests must call actual production code, never duplicate logic. Target >80% test coverage (enforced by CodeCov)
Files:
internal/exec/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_state_test.gointernal/exec/yaml_func_utils_context_test.gointernal/exec/yaml_func_resolution_context_bench_test.gopkg/function/parser_test.gointernal/exec/yaml_func_terraform_output_test.go
pkg/**/*.go
📄 CodeRabbit inference engine (CLAUDE.md)
pkg/**/*.go: Business logic packages must follow the Service-Oriented Architecture pattern with: one Service struct per domain, Provider interfaces for classes of problems, default implementations, mock implementations, and dependency injection for testability
Use interface-driven design: define interfaces for all major functionality, use dependency injection for testability, generate mocks withgo.uber.org/mock/mockgenwith//go:generatedirectives, avoid integration tests by mocking external dependencies
Create focused purpose-built packages inpkg/for new functionality, each with clear responsibility. DO NOT add new functions topkg/utils/orinternal/exec/. Each package should have focused business logic with tests
Implement registry pattern for extensibility and plugin-like architecture. Define interfaces for provider implementations, register implementations in registry, generate mocks with mockgen. Examples: Command Registry incmd/internal/registry.go, Store Registry inpkg/store/registry.go
Files:
pkg/function/parser.gopkg/function/parser_test.go
website/**
📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
website/**: Update website documentation in thewebsite/directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in thewebsite/directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases
Files:
website/docs/functions/yaml/terraform.output.mdxwebsite/docs/functions/yaml/terraform.state.mdxwebsite/blog/2025-12-03-yaml-function-clean-syntax.mdx
website/blog/*.mdx
📄 CodeRabbit inference engine (CLAUDE.md)
Blog posts require YAML front matter with slug, title, authors, and tags. Use
<!--truncate-->after intro. ONLY use existing tags fromwebsite/blog/*.mdx- check before writing. Author field must be GitHub username, added towebsite/blog/authors.yml. Filename format:YYYY-MM-DD-feature-name.mdx. PRs labeledminor/majorMUST include blog post
Files:
website/blog/2025-12-03-yaml-function-clean-syntax.mdx
🧠 Learnings (59)
📓 Common learnings
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.
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.
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning the error instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions.
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1185
File: internal/exec/yaml_func_store.go:71-72
Timestamp: 2025-04-04T02:03:21.906Z
Learning: The codebase currently uses `log.Fatal` for error handling in library functions, which terminates the program. There is a plan to refactor this approach in a separate PR to improve API design by returning error messages instead of terminating execution.
📚 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/atmos-terraform-output-yaml-function/stacks/deploy/nonprod.yamlinternal/exec/yaml_func_terraform_output.gotests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/prod.yamlwebsite/docs/functions/yaml/terraform.output.mdxwebsite/docs/functions/yaml/terraform.state.mdxwebsite/blog/2025-12-03-yaml-function-clean-syntax.mdxinternal/exec/yaml_func_terraform_output_test.gotests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/nonprod.yaml
📚 Learning: 2025-12-06T19:24:49.329Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.329Z
Learning: Applies to tests/**/*.yaml : NEVER modify `tests/test-cases/` or `tests/testdata/` unless explicitly instructed. Golden snapshots are sensitive to minor changes. Use fixtures in `tests/test-cases/`: `atmos.yaml`, `stacks/`, `components/`
Applied to files:
tests/fixtures/scenarios/atmos-terraform-output-yaml-function/stacks/deploy/nonprod.yamltests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/prod.yamltests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/nonprod.yaml
📚 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:
tests/fixtures/scenarios/atmos-terraform-output-yaml-function/stacks/deploy/nonprod.yamltests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/prod.yamlwebsite/docs/functions/yaml/terraform.output.mdxwebsite/docs/functions/yaml/terraform.state.mdxwebsite/blog/2025-12-03-yaml-function-clean-syntax.mdxtests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/nonprod.yaml
📚 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/atmos-terraform-output-yaml-function/stacks/deploy/nonprod.yamltests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/prod.yamltests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/nonprod.yaml
📚 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:
tests/fixtures/scenarios/atmos-terraform-output-yaml-function/stacks/deploy/nonprod.yamlinternal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gowebsite/docs/functions/yaml/terraform.output.mdxinternal/exec/yaml_func_terraform_output_test.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:
tests/fixtures/scenarios/atmos-terraform-output-yaml-function/stacks/deploy/nonprod.yamlinternal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gopkg/function/parser.gotests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/prod.yamlinternal/exec/yaml_func_utils_context_test.gowebsite/docs/functions/yaml/terraform.output.mdxwebsite/docs/functions/yaml/terraform.state.mdxwebsite/blog/2025-12-03-yaml-function-clean-syntax.mdxinternal/exec/yaml_processor.gointernal/exec/yaml_func_terraform_output_test.gotests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/nonprod.yaml
📚 Learning: 2024-12-03T03:49:30.395Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: website/docs/core-concepts/stacks/yaml-functions/terraform.output.mdx:104-110
Timestamp: 2024-12-03T03:49:30.395Z
Learning: In the documentation for `!terraform.output`, warnings about template variable availability are already covered in other sections, so no need to suggest adding them here.
Applied to files:
tests/fixtures/scenarios/atmos-terraform-output-yaml-function/stacks/deploy/nonprod.yamlwebsite/docs/functions/yaml/terraform.output.mdxwebsite/docs/functions/yaml/terraform.state.mdx
📚 Learning: 2024-12-17T07:08:41.288Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 863
File: internal/exec/yaml_func_terraform_output.go:34-38
Timestamp: 2024-12-17T07:08:41.288Z
Learning: In the `processTagTerraformOutput` function within `internal/exec/yaml_func_terraform_output.go`, parameters are separated by spaces and do not contain spaces. Therefore, using `strings.Fields()` for parsing is acceptable, and there's no need to handle parameters with spaces.
Applied to files:
internal/exec/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_terraform_state_test.gointernal/exec/yaml_func_utils_context_test.gointernal/exec/yaml_func_utils.gointernal/exec/yaml_processor.gointernal/exec/yaml_func_terraform_output_test.go
📚 Learning: 2024-11-30T22:07:08.610Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: internal/exec/yaml_func_terraform_output.go:35-40
Timestamp: 2024-11-30T22:07:08.610Z
Learning: In the Go function `processTagTerraformOutput` in `internal/exec/yaml_func_terraform_output.go`, parameters cannot contain spaces. The code splits the input by spaces, and if the parameters contain spaces, `len(parts) != 3` will fail and show an error to the user.
Applied to files:
internal/exec/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_terraform_state_test.gointernal/exec/yaml_func_utils_context_test.gointernal/exec/yaml_func_utils.gointernal/exec/yaml_processor.gointernal/exec/yaml_func_terraform_output_test.go
📚 Learning: 2025-04-24T01:40:13.576Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1202
File: pkg/config/process_yaml.go:0-0
Timestamp: 2025-04-24T01:40:13.576Z
Learning: When processing YAML nodes with custom directives in Go using gopkg.in/yaml.v3, setting node.Tag = "" is sufficient to prevent re-processing of the node. It's not necessary to also clear node.Value after updating the configuration store (e.g., Viper), as the original value doesn't affect subsequent operations once the tag is removed.
Applied to files:
internal/exec/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_terraform_state_test.gointernal/exec/yaml_func_utils_context_test.gointernal/exec/yaml_func_resolution_context_bench_test.gointernal/exec/yaml_func_utils.gointernal/exec/yaml_processor.go
📚 Learning: 2025-12-06T19:24:49.329Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.329Z
Learning: Applies to **/*_test.go : Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoid `os.Exit`, `CheckErrorPrintAndExit`, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios
Applied to files:
internal/exec/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_state_test.gointernal/exec/yaml_func_utils_context_test.gointernal/exec/yaml_func_resolution_context_bench_test.gopkg/function/parser_test.gointernal/exec/yaml_func_terraform_output_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:
internal/exec/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_state.gopkg/function/parser.gointernal/exec/yaml_func_utils.gointernal/exec/yaml_processor.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/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_terraform_state_test.gointernal/exec/yaml_func_utils_context_test.gointernal/exec/yaml_func_terraform_output_test.go
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.
Applied to files:
internal/exec/yaml_func_utils_test.gointernal/exec/yaml_func_utils.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/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_terraform_state_test.gointernal/exec/yaml_func_utils_context_test.gointernal/exec/yaml_func_terraform_output_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/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_terraform_state_test.gointernal/exec/yaml_func_utils_context_test.gointernal/exec/yaml_func_terraform_output_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/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_terraform_state_test.gointernal/exec/yaml_func_terraform_output_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/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_terraform_state_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/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_terraform_state_test.gointernal/exec/yaml_func_utils_context_test.gointernal/exec/yaml_func_utils.gointernal/exec/yaml_func_terraform_output_test.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:
internal/exec/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state_test.go
📚 Learning: 2024-10-31T19:23:45.538Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform.go:65-66
Timestamp: 2024-10-31T19:23:45.538Z
Learning: The variable `shouldCheckStack` in `ExecuteTerraform` controls whether validation is performed.
Applied to files:
internal/exec/yaml_func_utils_test.gointernal/exec/yaml_func_terraform_state_test.gointernal/exec/yaml_func_terraform_output_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:
internal/exec/yaml_func_terraform_output.go
📚 Learning: 2024-12-07T16:19:01.683Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.
Applied to files:
internal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_utils_context_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/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_utils_context_test.gointernal/exec/yaml_func_utils.gointernal/exec/yaml_func_terraform_output_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/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_output_test.go
📚 Learning: 2025-12-06T19:24:49.329Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.329Z
Learning: Applies to **/*.go : Import organization: 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/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_utils.go
📚 Learning: 2025-09-13T18:06:07.674Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/list.go:39-42
Timestamp: 2025-09-13T18:06:07.674Z
Learning: In the cloudposse/atmos repository, for UI messages in the toolchain package, use utils.PrintfMessageToTUI instead of log.Error or fmt.Fprintln(os.Stderr, ...). Import pkg/utils with alias "u" to follow the established pattern.
Applied to files:
internal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_utils.go
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.
Applied to files:
internal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_utils_context_test.gointernal/exec/yaml_func_utils.go
📚 Learning: 2025-10-22T14:55:44.014Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1695
File: pkg/auth/manager.go:169-171
Timestamp: 2025-10-22T14:55:44.014Z
Learning: Go 1.20+ supports multiple %w verbs in fmt.Errorf, which returns an error implementing Unwrap() []error. This is valid and does not panic. Atmos uses Go 1.24.8 and configures errorlint with errorf-multi: true to validate this pattern.
Applied to files:
internal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_utils.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/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_utils.go
📚 Learning: 2025-11-09T19:06:58.470Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1752
File: pkg/profile/list/formatter_table.go:27-29
Timestamp: 2025-11-09T19:06:58.470Z
Learning: In the cloudposse/atmos repository, performance tracking with `defer perf.Track()` is enforced on all functions via linting, including high-frequency utility functions, formatters, and renderers. This is a repository-wide policy to maintain consistency and avoid making case-by-case judgment calls about which functions should have profiling.
Applied to files:
internal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_utils.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:
internal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.go
📚 Learning: 2025-12-06T19:24:49.329Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.329Z
Learning: Applies to **/*.go : Add `defer perf.Track(atmosConfig, "pkg.FuncName")()` + blank line to all public functions. Use `nil` if no atmosConfig param
Applied to files:
internal/exec/yaml_func_terraform_output.gointernal/exec/yaml_func_terraform_state.gointernal/exec/yaml_func_utils.go
📚 Learning: 2024-12-05T22:33:40.955Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 820
File: cmd/list_components.go:53-54
Timestamp: 2024-12-05T22:33:40.955Z
Learning: In the Atmos CLI Go codebase, using `u.LogErrorAndExit` within completion functions is acceptable because it logs the error and exits the command execution.
Applied to files:
internal/exec/yaml_func_terraform_state.go
📚 Learning: 2025-12-06T19:24:49.329Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.329Z
Learning: Applies to pkg/**/*.go : Create focused purpose-built packages in `pkg/` for new functionality, each with clear responsibility. DO NOT add new functions to `pkg/utils/` or `internal/exec/`. Each package should have focused business logic with tests
Applied to files:
pkg/function/parser.gopkg/function/parser_test.go
📚 Learning: 2025-12-06T19:24:49.329Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.329Z
Learning: Applies to **/*.go : New configs support Go templating with `FuncMap()` from `internal/exec/template_funcs.go`. Implement template functions in `internal/exec/template_funcs.go`, register them, add tests, and update documentation
Applied to files:
pkg/function/parser.gointernal/exec/yaml_func_utils_context_test.gopkg/function/parser_test.gointernal/exec/yaml_func_terraform_output_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 : Document complex logic with inline comments in Go code
Applied to files:
pkg/function/parser.go
📚 Learning: 2025-01-19T22:30:27.600Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-01-19T22:30:27.600Z
Learning: The Atmos YAML function `!env` is used to retrieve environment variables and assign them to sections in stack manifests. It supports both simple types (string, number, boolean) and complex types (JSON-encoded lists, maps, objects).
Applied to files:
tests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/prod.yamlinternal/exec/yaml_func_utils_context_test.gowebsite/docs/functions/yaml/terraform.output.mdxwebsite/docs/functions/yaml/terraform.state.mdxtests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/nonprod.yaml
📚 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/yaml_func_utils_context_test.gopkg/function/parser_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:
internal/exec/yaml_func_utils_context_test.gopkg/function/parser_test.gointernal/exec/yaml_func_terraform_output_test.go
📚 Learning: 2025-12-06T19:24:49.329Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.329Z
Learning: Applies to **/*_test.go : Use table-driven tests for comprehensive coverage. Tests must call actual production code, never duplicate logic. Target >80% test coverage (enforced by CodeCov)
Applied to files:
internal/exec/yaml_func_utils_context_test.gopkg/function/parser_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 : 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:
internal/exec/yaml_func_utils_context_test.gointernal/exec/yaml_func_utils.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/yaml_func_utils_context_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/yaml_func_utils_context_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:
internal/exec/yaml_func_utils_context_test.go
📚 Learning: 2024-11-16T17:30:52.893Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 786
File: internal/exec/shell_utils.go:159-162
Timestamp: 2024-11-16T17:30:52.893Z
Learning: For the `atmos terraform shell` command in `internal/exec/shell_utils.go`, input validation for the custom shell prompt is not required, as users will use this as a CLI tool and any issues will impact themselves.
Applied to files:
internal/exec/yaml_func_utils_context_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:
internal/exec/yaml_func_utils_context_test.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/yaml_func_resolution_context_bench_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:
pkg/function/parser_test.go
📚 Learning: 2025-12-06T19:24:49.329Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.329Z
Learning: Applies to pkg/**/*.go : Use interface-driven design: define interfaces for all major functionality, use dependency injection for testability, generate mocks with `go.uber.org/mock/mockgen` with `//go:generate` directives, avoid integration tests by mocking external dependencies
Applied to files:
pkg/function/parser_test.go
📚 Learning: 2024-12-03T05:29:07.718Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: internal/exec/terraform_utils.go:145-146
Timestamp: 2024-12-03T05:29:07.718Z
Learning: In the Atmos project, a 5-minute timeout in the `execTerraformOutput` function is acceptable for retrieving `terraform output` for a component in a stack.
Applied to files:
website/docs/functions/yaml/terraform.output.mdx
📚 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:
internal/exec/yaml_func_utils.gointernal/exec/yaml_processor.go
📚 Learning: 2025-04-24T01:06:15.259Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1202
File: pkg/config/process_yaml.go:0-0
Timestamp: 2025-04-24T01:06:15.259Z
Learning: When processing YAML structures with gopkg.in/yaml.v3, the Value field of a Node is only meant for scalar values. Complex data types like maps and arrays are represented through child nodes in the YAML tree structure.
Applied to files:
internal/exec/yaml_func_utils.go
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning the error instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions.
Applied to files:
internal/exec/yaml_func_utils.go
📚 Learning: 2025-11-30T04:16:24.155Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1821
File: pkg/merge/deferred.go:34-48
Timestamp: 2025-11-30T04:16:24.155Z
Learning: In the cloudposse/atmos repository, the `defer perf.Track()` guideline applies to functions that perform meaningful work (I/O, computation, external calls), but explicitly excludes trivial accessors/mutators (e.g., simple getters, setters with single integer increments, string joins, or map appends) where the tracking overhead would exceed the actual method cost and provide no actionable performance data. Hot-path methods called in tight loops should especially avoid perf.Track() if they perform only trivial operations.
Applied to files:
internal/exec/yaml_func_utils.go
📚 Learning: 2025-07-05T20:59:02.914Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1363
File: internal/exec/template_utils.go:18-18
Timestamp: 2025-07-05T20:59:02.914Z
Learning: In the Atmos project, gomplate v4 is imported with a blank import (`_ "github.com/hairyhenderson/gomplate/v4"`) alongside v3 imports to resolve AWS SDK version conflicts. V3 uses older AWS SDK versions that conflict with newer AWS modules used by Atmos. A full migration to v4 requires extensive refactoring due to API changes and should be handled in a separate PR.
Applied to files:
internal/exec/yaml_func_utils.go
📚 Learning: 2025-02-06T13:38:07.216Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 984
File: internal/exec/copy_glob.go:0-0
Timestamp: 2025-02-06T13:38:07.216Z
Learning: The `u.LogTrace` function in the `cloudposse/atmos` repository accepts `atmosConfig` as its first parameter, followed by the message string.
Applied to files:
internal/exec/yaml_func_utils.go
📚 Learning: 2025-12-06T19:24:49.329Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.329Z
Learning: Applies to website/blog/*.mdx : Blog posts require YAML front matter with slug, title, authors, and tags. Use `<!--truncate-->` after intro. ONLY use existing tags from `website/blog/*.mdx` - check before writing. Author field must be GitHub username, added to `website/blog/authors.yml`. Filename format: `YYYY-MM-DD-feature-name.mdx`. PRs labeled `minor`/`major` MUST include blog post
Applied to files:
website/blog/2025-12-03-yaml-function-clean-syntax.mdx
🧬 Code graph analysis (2)
internal/exec/yaml_func_terraform_state.go (3)
pkg/utils/yaml_utils.go (1)
AtmosYamlFuncTerraformState(27-27)pkg/function/parser.go (1)
ParseArgs(39-77)errors/errors.go (1)
ErrYamlFuncInvalidArguments(89-89)
pkg/function/parser_test.go (1)
pkg/function/parser.go (1)
ParseArgs(39-77)
🪛 LanguageTool
website/docs/functions/yaml/terraform.output.mdx
[grammar] ~199-~199: Please add a punctuation mark at the end of paragraph.
Context: ...een provisioned yet, return the default value ["mock-subnet1", "mock-subnet2"] ```...
(PUNCTUATION_PARAGRAPH_END)
[grammar] ~207-~207: Please add a punctuation mark at the end of paragraph.
Context: ...een provisioned yet, return the default value `{"api_endpoint": "localhost:3000", "us...
(PUNCTUATION_PARAGRAPH_END)
website/docs/functions/yaml/terraform.state.mdx
[grammar] ~194-~194: Please add a punctuation mark at the end of paragraph.
Context: ...een provisioned yet, return the default value ["mock-subnet1", "mock-subnet2"] ```...
(PUNCTUATION_PARAGRAPH_END)
[grammar] ~202-~202: Please add a punctuation mark at the end of paragraph.
Context: ...een provisioned yet, return the default value `{"api_endpoint": "localhost:3000", "us...
(PUNCTUATION_PARAGRAPH_END)
⏰ 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). (2)
- GitHub Check: Acceptance Tests (windows)
- GitHub Check: Summary
🔇 Additional comments (28)
tests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/nonprod.yaml (1)
35-39: Nice coverage of new clean syntax in state fixtureThis block does a good job exercising the new parser with string, list, map, and YQ pipe cases using the cleaner single-quoted syntax; looks solid as a regression fixture for the refactor.
tests/fixtures/scenarios/atmos-terraform-state-yaml-function/stacks/deploy/prod.yaml (1)
35-39: Prod fixture correctly mirrors new clean syntaxThe prod stack fixture mirrors the nonprod examples for the new single-quoted argument style, which is helpful for catching stack-specific regressions; no changes needed.
internal/exec/yaml_processor.go (1)
51-58: ProcessYAMLFunctionString now correctly propagates errorsWiring this method to return the
(any, error)fromprocessCustomTagsWithContextmatches the new error-propagation design and keeps the perf tracking intact; looks good.internal/exec/yaml_func_resolution_context_bench_test.go (1)
120-121: Benchmark updated for new processNodes signatureCapturing and discarding the error in the benchmark keeps the focus on performance while adapting to the new
(value, error)return; fine given correctness is validated elsewhere.website/blog/2025-12-03-yaml-function-clean-syntax.mdx (1)
1-83: Blog post cleanly documents the new YAML function syntaxFront matter, truncate marker, and the before/after examples all look consistent with the new parser behavior, including the block-scalar guidance and backward-compatibility notes; this should make the change very discoverable for users. As per coding guidelines, just ensure
enhancementanddxare existing tags in the blog taxonomy.internal/exec/yaml_func_terraform_state_test.go (1)
64-75: Tests now correctly assert on the new (value, error) state helperUpdating
processTagTerraformStateusages to capture(d, err)and assertNoErrorkeeps the existing behavioral checks while exercising the new error-return path; the coverage for normal and fallback behavior remains intact.Also applies to: 108-119
internal/exec/yaml_func_utils_test.go (1)
282-293: YAML function utility tests updated to track value + error correctlyAdapting the
processTagTerraformStateandprocessNodescall sites to the(value, error)signatures, with explicitassert.NoErrorchecks, keeps the existing behavior assertions while making the new error surface part of the test contract—this looks aligned with the broader refactor.Also applies to: 326-337, 480-483
internal/exec/yaml_func_terraform_output_test.go (2)
64-74: LGTM on error handling updates.The test correctly captures the error return from
processTagTerraformOutputand asserts no error. This aligns with the function signature change to(any, error).
108-118: Consistent error handling for component-2 tests.Same pattern applied correctly for the second batch of tests. Good consistency.
pkg/function/parser_test.go (5)
9-28: Well-structured table-driven test helper.Clean implementation. The
runTestCaseshelper promotes reuse across test functions.
30-41: Good backward compatibility coverage.Tests verify existing formats continue to work: simple cases, hyphenated/underscored names, mixed case. This ensures the refactor doesn't break existing users.
43-78: Comprehensive new syntax test coverage.Tests cover the key parsing heuristics from the PR:
- Dot expressions (
.output,.foo.bar.baz)- JSON fallbacks with
//operator- Pipe expressions
- Array/bracket access
- Expression-starting characters (
.,|,{,",')This validates the grammar-aware parser behavior.
80-112: Thorough edge case and whitespace handling tests.Good coverage of:
- Empty/minimal inputs
- Leading/trailing whitespace
- Multiple spaces and tabs between tokens
- Newlines from YAML block scalars
- CRLF handling
- Expression with internal spaces preserved
114-130: YAML block scalar simulation tests.Validates behavior after YAML parsing folds newlines. Useful for ensuring real-world YAML usage works correctly.
internal/exec/yaml_func_terraform_state.go (4)
7-7: Import alias follows conventions.Using
fnforpkg/functionis reasonable and consistent with the output file.
43-54: Good validation with sentinel errors.Proper use of
errUtils.ErrYamlFuncInvalidArgumentswith%wwrapping. Error messages include the input for debugging context.
65-81: Cycle detection properly integrated.The Push/Pop pattern with deferred cleanup ensures the dependency stack is maintained even on error paths.
91-96: Clean error propagation from state retrieval.Errors from
GetStateare returned directly. The finalreturn value, nilis explicit and clear.internal/exec/yaml_func_terraform_output.go (2)
43-54: Consistent validation pattern.Same validation approach as
terraform_state.go. Good consistency across the codebase.
91-104: Good error context and backward compatibility.The error on line 93 wraps with component/stack/output context for debugging. The
(nil, nil)return on line 100 preserves backward compatibility for missing outputs.website/docs/functions/yaml/terraform.output.mdx (3)
179-185: Clear syntax guidance.The "Clean Syntax" tip effectively explains the new approach: wrap in single quotes, use normal JSON inside. Practical example included.
213-225: Helpful block scalar documentation.Good addition explaining folded block scalars (
>-) for complex expressions. The equivalence note on line 224 clarifies behavior.
253-267: Pipe expression examples updated.The single-quote wrapping and block scalar alternative are well documented. Consistent with the new syntax approach.
website/docs/functions/yaml/terraform.state.mdx (1)
174-262: Documentation updates look great!The new "Clean Syntax" approach is well-explained with clear examples. The progression from single quotes to YAML block scalars for complex expressions provides good guidance for users. The examples effectively demonstrate the improved readability compared to the old CSV-based escaping.
internal/exec/yaml_func_utils_context_test.go (1)
88-199: Test updates properly handle new error returns.All test functions correctly capture and validate errors using
require.NoError(t, err)before asserting results. The pattern is consistent and follows Go testing best practices.pkg/function/parser.go (1)
1-77: Solid parser implementation!The heuristic approach is clearly documented and the implementation handles all the edge cases cleanly. The examples in the comments are helpful for understanding the expected behavior. Good use of
strings.TrimSpaceandstrings.TrimLeftto handle arbitrary whitespace.internal/exec/yaml_func_utils.go (2)
61-104: Clean error propagation pattern.The
firstErrtracking with short-circuit logic provides good error handling without cascading failures. Returning the partial map allows callers to inspect what was successfully processed before the error occurred. This aligns with the codebase pattern of returning errors instead of exiting.
123-168: Well-structured tag processing helpers.The separation between context-aware tags (cycle detection) and simple tags is clear. The
(any, bool, error)return pattern cleanly indicates whether a tag was handled and propagates errors appropriately. Each helper properly returns its error state.
| - Specify a list default value. | ||
| Read the `private_subnet_ids` output from the `vpc` component in the current stack. | ||
| If the `vpc` component has not been provisioned yet, return the default value `["mock-subnet1", "mock-subnet2"]` | ||
|
|
||
| ```yaml | ||
| subnet_ids: !terraform.output vpc ".private_subnet_ids // [""mock-subnet1"", ""mock-subnet2""]" | ||
| subnet_ids: !terraform.output 'vpc .private_subnet_ids // ["mock-subnet1", "mock-subnet2"]' | ||
| ``` | ||
|
|
||
| - Specify a map default value. | ||
| Read the `config_map` output from the `config` component in the current stack. | ||
| If the `config` component has not been provisioned yet, return the default value `{"api_endpoint": "localhost:3000", "user": "test"}` | ||
|
|
||
| ```yaml | ||
| config_map: !terraform.output 'config ".config_map // {""api_endpoint"": ""localhost:3000"", ""user"": ""test""}"' | ||
| config_map: !terraform.output 'config .config_map // {"api_endpoint": "localhost:3000", "user": "test"}' | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add punctuation at end of paragraphs.
Per static analysis, lines 199 and 207 need punctuation marks at the end.
Read the `private_subnet_ids` output from the `vpc` component in the current stack.
- If the `vpc` component has not been provisioned yet, return the default value `["mock-subnet1", "mock-subnet2"]`
+ If the `vpc` component has not been provisioned yet, return the default value `["mock-subnet1", "mock-subnet2"]`.
```yaml
subnet_ids: !terraform.output 'vpc .private_subnet_ids // ["mock-subnet1", "mock-subnet2"]'- Specify a map default value.
Read theconfig_mapoutput from theconfigcomponent in the current stack. - If the
configcomponent has not been provisioned yet, return the default value{"api_endpoint": "localhost:3000", "user": "test"}
- If the
configcomponent has not been provisioned yet, return the default value{"api_endpoint": "localhost:3000", "user": "test"}.
<details>
<summary>🧰 Tools</summary>
<details>
<summary>🪛 LanguageTool</summary>
[grammar] ~199-~199: Please add a punctuation mark at the end of paragraph.
Context: ...een provisioned yet, return the default value `["mock-subnet1", "mock-subnet2"]` ```...
(PUNCTUATION_PARAGRAPH_END)
---
[grammar] ~207-~207: Please add a punctuation mark at the end of paragraph.
Context: ...een provisioned yet, return the default value `{"api_endpoint": "localhost:3000", "us...
(PUNCTUATION_PARAGRAPH_END)
</details>
</details>
<details>
<summary>🤖 Prompt for AI Agents</summary>
In website/docs/functions/yaml/terraform.output.mdx around lines 197 to 211, two
paragraph sentences are missing terminal punctuation: add a period at the end of
the paragraph on line ~199 ("If the vpc component has not been provisioned
yet, return the default value [\"mock-subnet1\", \"mock-subnet2\"].") and add
a period at the end of the paragraph on line ~207 ("If the config component
has not been provisioned yet, return the default value {\"api_endpoint\": \"localhost:3000\", \"user\": \"test\".") — update those lines to end with a
period so both paragraphs end with proper punctuation.
</details>
<!-- fingerprinting:phantom:medusa:ocelot -->
<!-- This is an auto-generated comment by CodeRabbit -->
what
!terraform.stateand!terraform.outputfunctionswhy
The CSV parser was the wrong tool for this job. It required double-quote escaping (
"") to include JSON literals in expressions, creating ugly, hard-to-read YAML. The new parser uses a lightweight heuristic: component and stack names never contain spaces and never start with special characters (.,|,[,{,",'), while expressions always do. This enables clean, readable syntax without escaping.references
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.