Skip to content

Conversation

@osterman
Copy link
Member

@osterman osterman commented Oct 21, 2025

Summary

This PR introduces comprehensive toolchain management for Atmos, enabling users to manage third-party tools alongside Atmos version management. It also refactors the terraform commands to use the registry pattern for better code organization.

Key Features

🔧 Atmos Toolchain for 3rd Party Tools

  • Tool Management: Install, uninstall, list, and execute versioned tools from configurable registries
  • Multi-Registry Support: Configure multiple tool registries (Atmos, Aqua) with search and listing capabilities
  • Lock File Support: atmos.lock.hcl for reproducible, multi-platform dependency locking
  • Tool Dependencies: Workflows and commands can declare tool dependencies with automatic installation
  • Aliases: Configure tool aliases for convenient command execution
  • Version Constraints: Support for semantic versioning constraints

📦 Atmos Version Management

  • atmos version list: List available Atmos versions with active/installed indicators
  • atmos version install/uninstall: Install and manage multiple Atmos versions
  • --use-version Flag: Run any command with a specific Atmos version via re-exec mechanism

🏗️ Terraform Command Registry Migration

  • Migrated all terraform commands to the registry pattern (cmd/terraform/)
  • Implemented CommandProvider interface for consistent command registration
  • Added comprehensive compatibility flag support for terraform/tofu pass-through
  • Interactive prompts for component and stack selection
  • Better flag handling with pkg/flags/StandardParser

🌍 Global Environment Configuration

  • atmos env Command: Output environment variables in bash, JSON, dotenv, or GitHub Actions format
  • env Section in atmos.yaml: Configure global environment variables with template support

📝 Stack Configuration Enhancements

  • File-Scoped Locals: Define locals: at the top level of stack files for file-specific templating
  • !literal YAML Function: Preserve template syntax for deferred evaluation

📚 Documentation

  • Comprehensive documentation for toolchain features, registries, and lock file management
  • Updated configuration docs for new features
  • New how-to guides for version management

Changes

New Commands

  • atmos toolchain (add, clean, du, env, exec, get, info, install, list, path, remove, search, set, uninstall, versions, which)
  • atmos version list, atmos version install, atmos version uninstall
  • atmos env

New Packages

  • toolchain/ - Core toolchain business logic (install, registry, progress, etc.)
  • pkg/toolchain/filemanager/ - Lock file and .tool-versions management
  • pkg/toolchain/lockfile/ - Lock file parsing and generation
  • cmd/toolchain/ - Toolchain CLI commands using registry pattern
  • cmd/terraform/ - Terraform commands migrated to registry pattern
  • cmd/env/ - Environment variable output command

Architectural Improvements

  • Command registry pattern for all new commands
  • Unified flag parsing infrastructure in pkg/flags/
  • Static error wrapping with sentinel errors from errors/errors.go
  • Test improvements using t.Setenv and t.TempDir

Testing

  • Comprehensive unit tests for all toolchain packages
  • Golden snapshot tests for CLI output
  • Mock-based testing for external dependencies

Breaking Changes

None - all new features are additive.


🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

Summary by CodeRabbit

  • New Features

    • Built-in Toolchain CLI to manage tools (add/clean/du/env/install/uninstall/list/get/info/path/which/set/remove/exec) and registry search/list.
    • Automatic tool dependency resolution with on-demand installs and per-command PATH injection.
    • Version management: install/uninstall specific Atmos versions.
  • Documentation

    • Many new user guides, PRDs, examples, and READMEs for toolchain, registries, lockfiles, and dependency workflows.
  • Other

    • CLI help now lists Toolchain commands; telemetry notice removed.

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

@osterman osterman requested review from a team as code owners October 21, 2025 03:28
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 21, 2025

📝 Walkthrough

Walkthrough

Adds a native Atmos toolchain subsystem: CLI command group with many subcommands, schema fields for toolchain and dependencies, a dependency resolver and installer (with PATH construction), file-manager and lockfile implementations, atomic filesystem helpers, GitHub/HTTP utilities, exec-time tool PATH injection for component runs, extensive tests, docs, and snapshots.

Changes

Cohort / File(s) Summary
CLI root & entrypoint
cmd/root.go, main.go, cmd/version/*.go
Early --use-version parsing, --version/--use-version conflict detection, run()-based entrypoint, re-exec wiring, and version install/list/uninstall commands.
Toolchain command group & providers
cmd/toolchain/*, cmd/markdown/*, cmd/toolchain/registry/*
New toolchain root command and many subcommands (add, remove, install, uninstall, list, get, info, exec, path, env, which, du, clean, set, search, registry) implemented as CommandProvider types with parsers, docs and tests.
Dependency resolver & constraints
pkg/dependencies/resolver.go, pkg/dependencies/constraint.go, pkg/dependencies/*_test.go
New Resolver for multi-scope dependency resolution; ValidateConstraint and MergeDependencies enforce/merge semver constraints with tests and sentinel errors.
Installer & PATH management
pkg/dependencies/installer.go, pkg/dependencies/installer_test.go
Installer type with EnsureTools, isToolInstalled, BuildToolchainPATH, functional options and tests; exposes UpdatePath/BuildToolchainPATH for subprocess PATH injection.
File managers & lockfile
pkg/toolchain/filemanager/*, pkg/toolchain/lockfile/*, pkg/toolchain/filemanager/*_test.go, pkg/toolchain/filemanager/mock_interface_test.go
FileManager interface, ToolVersions and LockFile managers, Registry aggregator, lockfile model (New/Load/Save/Verify), mocks, error sentinels and tests.
Installer integration into exec flows
cmd/cmd_utils.go, internal/exec/{helmfile,packer,terraform,utils}.go
Resolve/install component dependencies prior to exec, build toolchain PATH, and inject it into subprocess env without mutating global process env; propagate dependencies sections through stack/component processing.
Filesystem & atomic I/O
pkg/filesystem/*, pkg/downloader/atomic_*.go, pkg/downloader/file_downloader*.go
FileSystem.WriteFileAtomic abstraction, OS-specific implementations/bridges, downloader.FetchAtomic and atomic-writer injection, plus mocks and tests.
HTTP & GitHub utilities
pkg/http/client.go, pkg/github/*, pkg/github/url_test.go, pkg/github/releases.go
HTTP client options (WithTimeout/WithGitHubToken/WithTransport), GitHubAuthenticatedTransport, GetGitHubTokenFromEnv, ConvertToRawURL, GetReleaseVersions and tests.
I/O, UI, pager, data
pkg/ui/formatter.go, pkg/ui/markdown/renderer.go, pkg/io/global.go, pkg/io/streams.go, pkg/pager/*, pkg/data/data.go
UI Hint API, TrimLinesRight, formatter Reset/Hint, markdown trimming, dynamic writers for test capture, pager Writer abstraction and mocks, data.Reset and IO Reset helpers.
Schema & command dependency fields
pkg/schema/schema.go, pkg/schema/dependencies.go, pkg/schema/command.go, pkg/schema/workflow.go, pkg/schema/version.go
Add Toolchain to AtmosConfiguration; Dependencies type and attach to Command/WorkflowDefinition; StackSection and BaseComponentDependencies fields; Version.Use added.
Registry UI, search & list
cmd/toolchain/registry/*, cmd/toolchain/registry/*_test.go
Registry list/search commands with parsers, table/json/yaml output, conditional styling, pagination/limits, terminal-aware rendering and tests.
File-manager registry & sentinels
pkg/toolchain/filemanager/errors.go, pkg/toolchain/filemanager/registry.go
Error sentinels (ErrUpdateFailed/ErrVerificationFailed) and Registry coordinating multiple FileManagers with aggregated error reporting.
YAML include / GitHub integration
pkg/utils/yaml_include_by_extension.go, pkg/utils/yaml_include_github_test.go
Detect GitHub includes, convert to raw URLs via github.ConvertToRawURL, treat github:// as remote; tests added.
Errors & formatting
errors/errors.go, errors/formatter.go, errors/builder.go
Many new sentinel errors for toolchain flows; context section now shown only in verbose error output; builder comment tweak.
Global flags & parsers
pkg/flags/*, cmd/cmd_utils.go
Added global UseVersion flag / ATMOS_USE_VERSION env var, guarded isVersionManagementCommand to avoid re-exec loops, parser wiring for toolchain commands.
Tests, fixtures & snapshots
cmd/toolchain/*_test.go, pkg/*_test.go, tests/fixtures/**, tests/snapshots/*
Wide coverage added for resolver, installer, file managers, lockfile, downloader, registry; many snapshot updates (help output additions/removals, telemetry removal, formatting changes).
Docs & examples
docs/prd/*, examples/toolchain/*, CLAUDE.md
Multiple PRDs (toolchain, registries, lockfile, file-management), command docs, examples, fixture configs, and contributor notes.
Misc & utilities
pkg/config/cache.go, pkg/config/const.go, .gitignore, internal/exec/*
Atomic write integration in cache, DependenciesSectionName constant, .gitignore updates, stack/component dependencies extraction/propagation, and other helper tweaks.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor User as CLI User
    participant Cobra as Cobra (CLI)
    participant ToolchainCmd as toolchain command
    participant Resolver as dependencies.Resolver
    participant Installer as dependencies.Installer
    participant FileMgr as FileManager(s)
    participant FS as Filesystem
    participant Subproc as Component subprocess

    User->>Cobra: run "atmos <component|toolchain> ..."
    Cobra->>ToolchainCmd: invoke subcommand RunE
    ToolchainCmd->>Resolver: ResolveComponentDependencies(stack, component)
    Resolver-->>ToolchainCmd: dependencies map
    alt dependencies found
        ToolchainCmd->>Installer: EnsureTools(dependencies)
        Installer->>FileMgr: AddTool / Verify (tool-versions / lockfile)
        FileMgr->>FS: WriteFileAtomic(...) (persist metadata)
        Installer-->>ToolchainCmd: built PATH entries
    end
    ToolchainCmd->>Subproc: start subprocess with injected PATH (env)
    Subproc-->>User: command output
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.27% 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 'Support Atmos Toolchain for 3rd Party Tools' clearly summarizes the primary feature addition in this comprehensive changeset.
✨ 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 tools-experiment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 456b0c2 and d24ce5f.

📒 Files selected for processing (3)
  • LICENSE
  • cmd/toolchain/exec.go
  • pkg/github/client.go
✅ Files skipped from review due to trivial changes (1)
  • LICENSE
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/github/client.go
  • cmd/toolchain/exec.go
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary

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

❤️ Share

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

@github-actions github-actions bot added the size/xl Extra large size PR label Oct 21, 2025
@mergify mergify bot added the triage Needs triage label Oct 21, 2025
@mergify
Copy link

mergify bot commented Oct 21, 2025

Important

Cloud Posse Engineering Team Review Required

This pull request modifies files that require Cloud Posse's review. Please be patient, and a core maintainer will review your changes.

To expedite this process, reach out to us on Slack in the #pr-reviews channel.

@mergify mergify bot added the needs-cloudposse Needs Cloud Posse assistance label Oct 21, 2025
@mergify
Copy link

mergify bot commented Oct 21, 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.

@codecov
Copy link

codecov bot commented Oct 21, 2025

Codecov Report

❌ Patch coverage is 71.78330% with 500 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.70%. Comparing base (8dafe30) to head (e0621e3).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
cmd/toolchain/registry/list.go 67.07% 78 Missing and 2 partials ⚠️
cmd/toolchain/registry/search.go 82.45% 37 Missing and 3 partials ⚠️
cmd/toolchain/toolchain.go 63.15% 24 Missing and 4 partials ⚠️
main.go 19.23% 20 Missing and 1 partial ⚠️
pkg/github/releases.go 0.00% 21 Missing ⚠️
cmd/root.go 41.37% 12 Missing and 5 partials ⚠️
cmd/toolchain/du.go 0.00% 16 Missing ⚠️
internal/exec/helmfile.go 0.00% 16 Missing ⚠️
cmd/toolchain/env.go 57.14% 13 Missing and 2 partials ⚠️
cmd/cmd_utils.go 35.00% 9 Missing and 4 partials ⚠️
... and 34 more
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1686      +/-   ##
==========================================
- Coverage   73.78%   73.70%   -0.09%     
==========================================
  Files         659      736      +77     
  Lines       61106    67269    +6163     
==========================================
+ Hits        45088    49580    +4492     
- Misses      12974    14317    +1343     
- Partials     3044     3372     +328     
Flag Coverage Δ
unittests 73.70% <71.78%> (-0.09%) ⬇️

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

Files with missing lines Coverage Δ
cmd/auth_whoami.go 71.05% <100.00%> (+0.98%) ⬆️
cmd/help_template.go 68.22% <100.00%> (+0.14%) ⬆️
cmd/toolchain/registry/styling.go 100.00% <100.00%> (ø)
errors/builder.go 100.00% <ø> (ø)
errors/errors.go 100.00% <ø> (ø)
errors/formatter.go 89.40% <100.00%> (+0.04%) ⬆️
internal/exec/describe_component.go 69.04% <100.00%> (+0.10%) ⬆️
...nal/exec/stack_processor_process_stacks_helpers.go 73.33% <ø> (ø)
...ck_processor_process_stacks_helpers_inheritance.go 95.08% <100.00%> (+0.08%) ⬆️
internal/exec/utils.go 80.24% <100.00%> (+0.03%) ⬆️
... and 66 more

... and 48 files with indirect coverage changes

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

@cfsb-jrose
Copy link

Hi @osterman - any idea when this would potentially be released?

@mergify
Copy link

mergify bot commented Oct 23, 2025

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

@mergify mergify bot added the conflict This PR has conflicts label Oct 23, 2025
@osterman
Copy link
Member Author

osterman commented Oct 23, 2025

Hi @osterman - any idea when this would potentially be released?

The primary hold up is lack of validation (and some precipitation with enhancing atmos auth). Since you are already using go install any testing/validation using this branch would be super helpful and accelerate the release.

Docs are at https://pr-1686.atmos-docs.ue2.dev.plat.cloudposse.org/

@cfsb-jrose
Copy link

Hi @osterman - any idea when this would potentially be released?

The primary hold up is lack of validation (and some precipitation with enhancing atmos auth). Since you are already using go install any testing/validation using this branch would be super helpful and accelerate the release.

Docs are at https://pr-1686.atmos-docs.ue2.dev.plat.cloudposse.org/

$ go install github.com/cloudposse/atmos@tools-experiment
go: downloading github.com/cloudposse/atmos v1.195.1-0.20251021041042-aee2829241c0
go: github.com/cloudposse/[email protected] requires go >= 1.24.8; switching to go1.24.9
go: github.com/cloudposse/atmos@tools-experiment (in github.com/cloudposse/[email protected]):
        The go.mod file for the module providing named packages contains one or
        more replace directives. It must not contain directives that would cause
        it to be interpreted differently than if it were the main module.

Just FYI. In the meantime, I will see what I can find out :)

@cfsb-jrose
Copy link

cfsb-jrose commented Oct 23, 2025

/atmos $ atmos toolchain list

 Notice: Telemetry Enabled - Atmos now collects anonymous telemetry regarding usage. This information is used to shape the Atmos roadmap and prioritize features. You can learn more, including how to opt out if you'd prefer not to participate in this anonymous program, by visiting: https://atmos.tools/cli/telemetry
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x41f5d1e]

goroutine 1 [running]:
github.com/cloudposse/atmos/toolchain.GetToolsDirPath(...)
        /go/src/toolchain/setup.go:36
github.com/cloudposse/atmos/toolchain.NewInstallerWithResolver({0x65b51e0, 0x9630340})
        /go/src/toolchain/installer.go:70 +0x13e
github.com/cloudposse/atmos/toolchain.NewInstaller(...)
        /go/src/toolchain/installer.go:86
github.com/cloudposse/atmos/toolchain.RunList()
        /go/src/toolchain/list.go:30 +0x39
github.com/cloudposse/atmos/cmd/toolchain.init.func6(0x941bd40?, {0x526c75b?, 0x4?, 0x526c753?})
        /go/src/cmd/toolchain/list.go:14 +0xf
github.com/spf13/cobra.(*Command).execute(0x941bd40, {0x9630340, 0x0, 0x0})
        /go/pkg/mod/github.com/spf13/[email protected]/command.go:1015 +0xaaa
github.com/spf13/cobra.(*Command).ExecuteC(0x9417560)
        /go/pkg/mod/github.com/spf13/[email protected]/command.go:1148 +0x46f
github.com/cloudposse/atmos/cmd.Execute()
        /go/src/cmd/root.go:535 +0x2e8
main.main()
        /go/src/main.go:37 +0x15e
/atmos $ atmos toolchain install hashicorp/[email protected]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x41f5d1e]

goroutine 1 [running]:
github.com/cloudposse/atmos/toolchain.GetToolsDirPath(...)
        /go/src/toolchain/setup.go:36
github.com/cloudposse/atmos/toolchain.NewInstallerWithResolver({0x65b51e0, 0x9630340})
        /go/src/toolchain/installer.go:70 +0x13e
github.com/cloudposse/atmos/toolchain.NewInstaller(...)
        /go/src/toolchain/installer.go:86
github.com/cloudposse/atmos/toolchain.RunInstall({0x7fffff7cdef6, 0x19}, 0x0, 0x0?)
        /go/src/toolchain/install.go:97 +0x285
github.com/cloudposse/atmos/cmd/toolchain.runInstall(0x941ba60?, {0xc000d88280?, 0x4?, 0x526c753?})
        /go/src/cmd/toolchain/install.go:30 +0x3f
github.com/spf13/cobra.(*Command).execute(0x941ba60, {0xc000d88250, 0x1, 0x1})
        /go/pkg/mod/github.com/spf13/[email protected]/command.go:1015 +0xaaa
github.com/spf13/cobra.(*Command).ExecuteC(0x9417560)
        /go/pkg/mod/github.com/spf13/[email protected]/command.go:1148 +0x46f
github.com/cloudposse/atmos/cmd.Execute()
        /go/src/cmd/root.go:535 +0x2e8
main.main()
        /go/src/main.go:37 +0x15e

@mergify mergify bot removed the conflict This PR has conflicts label Oct 23, 2025
@github-actions
Copy link

github-actions bot commented Oct 23, 2025

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@cfsb-jrose
Copy link

/atmos $ atmos toolchain list

 Notice: Telemetry Enabled - Atmos now collects anonymous telemetry regarding usage. This information is used to shape the Atmos roadmap and prioritize features. You can learn more, including how to opt out if you'd prefer not to participate in this anonymous program, by visiting: https://atmos.tools/cli/telemetry
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x41f5d1e]

goroutine 1 [running]:
github.com/cloudposse/atmos/toolchain.GetToolsDirPath(...)
        /go/src/toolchain/setup.go:36
github.com/cloudposse/atmos/toolchain.NewInstallerWithResolver({0x65b51e0, 0x9630340})
        /go/src/toolchain/installer.go:70 +0x13e
github.com/cloudposse/atmos/toolchain.NewInstaller(...)
        /go/src/toolchain/installer.go:86
github.com/cloudposse/atmos/toolchain.RunList()
        /go/src/toolchain/list.go:30 +0x39
github.com/cloudposse/atmos/cmd/toolchain.init.func6(0x941bd40?, {0x526c75b?, 0x4?, 0x526c753?})
        /go/src/cmd/toolchain/list.go:14 +0xf
github.com/spf13/cobra.(*Command).execute(0x941bd40, {0x9630340, 0x0, 0x0})
        /go/pkg/mod/github.com/spf13/[email protected]/command.go:1015 +0xaaa
github.com/spf13/cobra.(*Command).ExecuteC(0x9417560)
        /go/pkg/mod/github.com/spf13/[email protected]/command.go:1148 +0x46f
github.com/cloudposse/atmos/cmd.Execute()
        /go/src/cmd/root.go:535 +0x2e8
main.main()
        /go/src/main.go:37 +0x15e
/atmos $ atmos toolchain install hashicorp/[email protected]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x41f5d1e]

goroutine 1 [running]:
github.com/cloudposse/atmos/toolchain.GetToolsDirPath(...)
        /go/src/toolchain/setup.go:36
github.com/cloudposse/atmos/toolchain.NewInstallerWithResolver({0x65b51e0, 0x9630340})
        /go/src/toolchain/installer.go:70 +0x13e
github.com/cloudposse/atmos/toolchain.NewInstaller(...)
        /go/src/toolchain/installer.go:86
github.com/cloudposse/atmos/toolchain.RunInstall({0x7ffd14532ef6, 0x19}, 0x0, 0x0?)
        /go/src/toolchain/install.go:97 +0x285
github.com/cloudposse/atmos/cmd/toolchain.runInstall(0x941ba60?, {0xc000126500?, 0x4?, 0x526c753?})
        /go/src/cmd/toolchain/install.go:30 +0x3f
github.com/spf13/cobra.(*Command).execute(0x941ba60, {0xc0001264a0, 0x1, 0x1})
        /go/pkg/mod/github.com/spf13/[email protected]/command.go:1015 +0xaaa
github.com/spf13/cobra.(*Command).ExecuteC(0x9417560)
        /go/pkg/mod/github.com/spf13/[email protected]/command.go:1148 +0x46f
github.com/cloudposse/atmos/cmd.Execute()
        /go/src/cmd/root.go:535 +0x2e8
main.main()
        /go/src/main.go:37 +0x15e

@cfsb-jrose
Copy link

$ go install github.com/cloudposse/atmos@tools-experiment
go: downloading github.com/cloudposse/atmos v1.196.0-rc.1.0.20251023192958-bd051ffb2e6b
go: github.com/cloudposse/[email protected] requires go >= 1.25.0; switching to go1.25.3
go: downloading go1.25.3 (linux/amd64)
go: github.com/cloudposse/atmos@tools-experiment (in github.com/cloudposse/[email protected]):
        The go.mod file for the module providing named packages contains one or
        more exclude directives. It must not contain directives that would cause
        it to be interpreted differently than if it were the main module.

@osterman osterman added the minor New features that do not break anything label Oct 23, 2025
@github-actions
Copy link

github-actions bot commented Oct 23, 2025

Warning

Changelog Entry Required

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

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

Example filename: website/blog/2025-11-09-feature-name.mdx

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
docs/prd/toolchain-implementation.md (1)

141-141: Correct documented XDG cache paths to match implementation.

The XDG cache paths are documented with a nested directory structure (${XDG_CACHE_HOME}/atmos/toolchain), but per learnings from prior work, the actual implementation uses a single hyphenated directory (${XDG_CACHE_HOME}/atmos-toolchain). This discrepancy will confuse users looking for cache contents on disk. Update all three occurrences to the canonical path.

🔎 Proposed fixes

Line 141:

-Caches registry metadata in `${XDG_CACHE_HOME}/atmos/toolchain` (fallback: `~/.cache/atmos/toolchain`, replacing the old `/tmp/tools-cache/`)
+Caches registry metadata in `${XDG_CACHE_HOME}/atmos-toolchain` (fallback: `~/.cache/atmos-toolchain`, replacing the old `/tmp/tools-cache/`)

Line 697:

-Registry metadata persisted in `${XDG_CACHE_HOME}/atmos/toolchain` (fallback: `~/.cache/atmos/toolchain`)
+Registry metadata persisted in `${XDG_CACHE_HOME}/atmos-toolchain` (fallback: `~/.cache/atmos-toolchain`)

Line 808:

-    dir: ~/.cache/atmos/toolchain
+    dir: ~/.cache/atmos-toolchain

Also applies to: 697-697, 808-808

🧹 Nitpick comments (2)
examples/toolchain/custom-registry/README.md (2)

131-156: Testing section is actionable.

The atmos.yaml configuration example and install commands provide a clear path for readers to validate their setup. Consider adding a note about expected error messages or troubleshooting if tool installation fails (e.g., registry not found, asset pattern mismatch).


212-221: Best practices are sensible, but prioritization note could be clearer.

Line 217 mentions "Set appropriate priority (higher = checked first)" — consider a brief example showing how priority ordering works across multiple registries (e.g., custom registry priority 100, aqua-public priority 1) so readers understand precedence intuitively.

📜 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 e0b3923 and f778a2c.

📒 Files selected for processing (6)
  • cmd/toolchain/du.go
  • docs/prd/toolchain-implementation.md
  • examples/toolchain/custom-registry/README.md
  • main.go
  • tests/fixtures/scenarios/toolchain-terraform-integration/stacks/deploy/dev.yaml
  • tests/fixtures/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json
🧰 Additional context used
📓 Path-based instructions (5)
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

NEVER call viper.BindEnv() or viper.BindPFlag() directly. Commands MUST use flags.NewStandardParser() for command-specific flags. See cmd/version/version.go for reference implementation

Files:

  • cmd/toolchain/du.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: Use context.Context only for cancellation signals, deadlines/timeouts, and request-scoped values (sparingly). DO NOT use context for configuration, dependencies, or avoiding proper function parameters. Context should be first parameter in functions that accept it
All comments must end with periods (enforced by godot linter)
NEVER delete existing comments without a very strong reason. Preserve helpful comments explaining why/how/what/where. Update comments to match code when refactoring
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. Use nil if no atmosConfig param. Exceptions: trivial getters/setters, command constructors, simple factories, functions that onl...

Files:

  • cmd/toolchain/du.go
  • main.go
{cmd,internal}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

{cmd,internal}/**/*.go: Use I/O layer (pkg/io/) for stream access and UI layer (pkg/ui/) for formatting. Output data via data.Write/Writef/Writeln/WriteJSON/WriteYAML to stdout. Output UI messages via ui.Write/Writef/Writeln/Success/Error/Warning/Info/Markdown to stderr. DO NOT use fmt.Fprintf, fmt.Println, os.Stdout, or os.Stderr
Assume full TTY when writing output code. System automatically handles color degradation, width adaptation, TTY detection, CI detection, markdown rendering, icon support, secret masking, and format-aware masking
Telemetry is auto-enabled via RootCmd.ExecuteC(). Non-standard paths use telemetry.CaptureCmd(). Never capture user data

Files:

  • cmd/toolchain/du.go
{cmd,internal,pkg/ui}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Use colors from pkg/ui/theme/colors.go for styling output

Files:

  • cmd/toolchain/du.go
docs/prd/**/*.md

📄 CodeRabbit inference engine (CLAUDE.md)

Place all Product Requirement Documents in docs/prd/ with kebab-case filenames

Files:

  • docs/prd/toolchain-implementation.md
🧠 Learnings (46)
📓 Common learnings
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.
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: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).
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: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).
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: 768
File: internal/exec/vendor_utils.go:496-513
Timestamp: 2024-11-22T12:38:33.132Z
Learning: In the Atmos project, continue to flag path traversal issues in code reviews but acknowledge when they are expected and acceptable in specific cases.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain should follow XDG Base Directory Specification like the rest of atmos core, using XDG_CACHE_HOME environment variable when available and falling back to ~/.cache when not set, instead of hardcoding ~/.cache/tools-cache paths.
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.
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.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.
📚 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/toolchain/du.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/toolchain/du.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/toolchain/du.go
📚 Learning: 2025-09-05T14:57:37.360Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 1448
File: cmd/ansible.go:26-28
Timestamp: 2025-09-05T14:57:37.360Z
Learning: The Atmos codebase uses a consistent pattern for commands that delegate to external tools: `PersistentFlags().Bool("", false, doubleDashHint)` where doubleDashHint provides help text about using double dashes to separate Atmos options from native command arguments. This pattern is used across terraform, packer, helmfile, atlantis, aws, and ansible commands.

Applied to files:

  • cmd/toolchain/du.go
  • main.go
  • docs/prd/toolchain-implementation.md
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).

Applied to files:

  • cmd/toolchain/du.go
  • docs/prd/toolchain-implementation.md
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).

Applied to files:

  • cmd/toolchain/du.go
  • docs/prd/toolchain-implementation.md
📚 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:

  • cmd/toolchain/du.go
  • main.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:

  • main.go
📚 Learning: 2025-04-04T02:03:21.906Z
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.

Applied to files:

  • main.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.mod,go.sum} : Manage dependencies with Go modules and keep dependencies up to date while minimizing external dependencies

Applied to files:

  • main.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:

  • main.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:

  • main.go
📚 Learning: 2024-11-07T20:16:15.381Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 766
File: cmd/cmd_utils.go:177-178
Timestamp: 2024-11-07T20:16:15.381Z
Learning: In 'cmd/cmd_utils.go', using `os.Exit(1)` directly is acceptable in this context, and wrapping it with deferred cleanup is considered unnecessary.

Applied to files:

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

Applied to files:

  • main.go
📚 Learning: 2025-01-18T15:18:35.475Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/root.go:172-178
Timestamp: 2025-01-18T15:18:35.475Z
Learning: The `showUsageAndExit` function in `cmd/cmd_utils.go` terminates the program with `os.Exit(1)` and never returns to the caller, making error handling unnecessary for calls to this function.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • main.go
📚 Learning: 2025-12-30T20:13:29.819Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T20:13:29.819Z
Learning: Applies to cmd/**/*.go : NEVER call viper.BindEnv() or viper.BindPFlag() directly. Commands MUST use flags.NewStandardParser() for command-specific flags. See cmd/version/version.go for reference implementation

Applied to files:

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

Applied to files:

  • main.go
📚 Learning: 2025-12-13T04:37:45.831Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/toolchain/get.go:23-40
Timestamp: 2025-12-13T04:37:45.831Z
Learning: In cmd/toolchain/get.go, the get subcommand intentionally uses cobra.MaximumNArgs(1) so it works with zero args (list all tools) or one arg (a specific tool). Flags are defined via flags.NewStandardParser() with --all (bool) and --limit (int); no direct viper.BindEnv/BindPFlag calls are used.

Applied to files:

  • main.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:

  • main.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:

  • main.go
📚 Learning: 2025-11-10T23:23:39.771Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/registry/aqua/aqua_test.go:417-442
Timestamp: 2025-11-10T23:23:39.771Z
Learning: In Atmos toolchain AquaRegistry, tests should not hit real GitHub. Use the options pattern via WithGitHubBaseURL to inject an httptest server URL and make GetLatestVersion/GetAvailableVersions deterministic.

Applied to files:

  • examples/toolchain/custom-registry/README.md
  • docs/prd/toolchain-implementation.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:

  • examples/toolchain/custom-registry/README.md
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.

Applied to files:

  • examples/toolchain/custom-registry/README.md
  • docs/prd/toolchain-implementation.md
📚 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/toolchain-implementation.md
📚 Learning: 2025-01-25T03:51:57.689Z
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.

Applied to files:

  • docs/prd/toolchain-implementation.md
📚 Learning: 2025-12-30T20:13:29.819Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T20:13:29.819Z
Learning: Applies to docs/prd/**/*.md : Place all Product Requirement Documents in docs/prd/ with kebab-case filenames

Applied to files:

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

  • docs/prd/toolchain-implementation.md
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.

Applied to files:

  • docs/prd/toolchain-implementation.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 **/*.go : Document complex logic with inline comments in Go code

Applied to files:

  • docs/prd/toolchain-implementation.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 **/*.go : Follow standard Go coding style: use `gofmt` and `goimports` to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables

Applied to files:

  • docs/prd/toolchain-implementation.md
📚 Learning: 2025-12-30T20:13:29.819Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T20:13:29.819Z
Learning: Applies to **/*.go : NEVER delete existing comments without a very strong reason. Preserve helpful comments explaining why/how/what/where. Update comments to match code when refactoring

Applied to files:

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

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

Applied to files:

  • docs/prd/toolchain-implementation.md
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain should follow XDG Base Directory Specification like the rest of atmos core, using XDG_CACHE_HOME environment variable when available and falling back to ~/.cache when not set, instead of hardcoding ~/.cache/tools-cache paths.

Applied to files:

  • docs/prd/toolchain-implementation.md
📚 Learning: 2024-12-13T15:33:34.159Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: pkg/config/cache.go:17-31
Timestamp: 2024-12-13T15:33:34.159Z
Learning: In `pkg/config/cache.go`, when `XDG_CACHE_HOME` is not set, falling back to `.` (current directory) is acceptable and aligns with the requirement to primarily use `XDG_CACHE_HOME` for the cache directory.

Applied to files:

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

Applied to files:

  • docs/prd/toolchain-implementation.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:

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

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

  • docs/prd/toolchain-implementation.md
🧬 Code graph analysis (1)
main.go (5)
errors/error_funcs.go (1)
  • OsExit (25-25)
pkg/utils/log_utils.go (1)
  • OsExit (18-18)
cmd/root.go (2)
  • ExecuteVersion (1219-1227)
  • Execute (1274-1364)
errors/sentry.go (1)
  • CaptureError (69-109)
errors/exit_code.go (1)
  • GetExitCode (60-96)
🪛 LanguageTool
examples/toolchain/custom-registry/README.md

[uncategorized] ~80-~80: The official name of this software platform is spelled with a capital “H”.
Context: ...ier (owner/repo) - type: Source type (github_release, http, etc.) - asset: GitHub ...

(GITHUB)

docs/prd/toolchain-implementation.md

[style] ~46-~46: Since ownership is already implied, this phrasing may be redundant.
Context: ...Self-Managed Atmos*: Atmos can manage its own version and auto-upgrade/downgrade 4. *...

(PRP_OWN)


[typographical] ~121-~121: To join two clauses or introduce examples, consider using an em dash.
Context: ...- toolchain install [tool@version] - Install tools from registry - **`toolcha...

(DASH_RULE)


[grammar] ~249-~249: Please add a punctuation mark at the end of paragraph.
Context: ...4. Required version executes the actual command Current Gap: The self-exec wrapper...

(PUNCTUATION_PARAGRAPH_END)


[typographical] ~302-~302: To join two clauses or introduce examples, consider using an em dash.
Context: ...d ``` #### Component-Level Dependencies - Component-Specific Requirements **Compo...

(DASH_RULE)


[style] ~743-~743: ‘first priority’ might be wordy. Consider a shorter alternative.
Context: ...tion**: - Local tools.yaml overrides (first priority) - Registry URL abstraction (future: al...

(EN_WORDINESS_PREMIUM_FIRST_PRIORITY)


[typographical] ~759-~759: Consider using a typographic opening quote here.
Context: ...cted**: Name collisions (e.g., multiple "cli" tools) ### 4. Process Replacement ...

(EN_QUOTES)


[typographical] ~759-~759: Consider using a typographic close quote here.
Context: ...**: Name collisions (e.g., multiple "cli" tools) ### 4. Process Replacement vs W...

(EN_QUOTES)


[typographical] ~761-~761: In American English, use a period after an abbreviation.
Context: ...cli" tools) ### 4. Process Replacement vs Wrapper Script Decision: Use `sysc...

(MISSING_PERIOD_AFTER_ABBREVIATION)


[grammar] ~763-~763: Please add a punctuation mark at the end of paragraph.
Context: ...Decision**: Use syscall.Exec for tool execution Rationale: - True process replacem...

(PUNCTUATION_PARAGRAPH_END)


[style] ~768-~768: This adverb was used twice in the sentence. Consider removing one of them or replacing them with a synonym.
Context: ...codes correctly - Signal handling works correctly - Minimal performance impact **Trade-o...

(ADVERB_REPETITION_PREMIUM)


[typographical] ~983-~983: In American English, use a period after an abbreviation.
Context: ...% of tool invocations that auto-install vs manual - Error Rate: Tool-related e...

(MISSING_PERIOD_AFTER_ABBREVIATION)


[typographical] ~1007-~1007: To join two clauses or introduce examples, consider using an em dash.
Context: ...registry backends Recommendation: D - Support multiple registries with local a...

(DASH_RULE)


[typographical] ~1019-~1019: To join two clauses or introduce examples, consider using an em dash.
Context: ...n .tool-versions Recommendation: C - Support all formats, use SemVer library ...

(DASH_RULE)


[typographical] ~1378-~1378: To join two clauses or introduce examples, consider using an em dash.
Context: ...al Libraries - github.com/spf13/cobra - CLI framework - `github.com/Masterminds/...

(DASH_RULE)


[typographical] ~1425-~1425: To join two clauses or introduce examples, consider using an em dash.
Context: ...ver.org/) - CLAUDE.md - Atmos development guidelines ### File L...

(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). (40)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
🔇 Additional comments (9)
examples/toolchain/custom-registry/README.md (4)

1-30: Clear structure and excellent pattern explanation.

The introduction and registry patterns section effectively distinguish the two approaches. The detection logic (lines 27, 43) is practical and helps readers choose the right pattern.


49-84: Registry format example is solid, but verify field alignment with implementation.

The YAML structure and field descriptions look comprehensive. Confirm that replacements, version_constraint, and other fields match the actual toolchain registry schema, especially if this example will be widely referenced.


85-130: Use cases are practical and well-motivated.

The progression from corporate tools → version pinning → custom patterns → air-gapped mirrors covers real scenarios. This section effectively shows when and why readers would use custom registries.


187-211: Hosting options are comprehensive.

Good coverage of file://, HTTP/HTTPS, GitHub, and generic Git repository patterns. The GitHub → raw.githubusercontent.com conversion note (lines 202–204) is helpful context.

cmd/toolchain/du.go (3)

1-10: Import organization looks good.

The imports are correctly organized: 3rd-party (Cobra) separated from Atmos packages. All imports are used appropriately.


12-24: Command definition and delegation pattern are solid.

The command correctly uses cobra.NoArgs, has appropriate help text, and delegates to toolchain.DuExec(). The RunE wrapper follows the established pattern for simple delegating functions.


26-66: Provider implementation follows the established pattern correctly.

The DuCommandProvider properly implements the CommandProvider interface with all required methods. Returning nil for flags, args, compat flags, and aliases is appropriate for this simple command. The compile-time assertion ensures interface compliance, and all godoc comments are present and properly formatted.

main.go (2)

51-60: Well-structured early flag conflict detection.

The conflict check for --version and --use-version is clean, with clear error messaging and hints. Writing directly to stderr is appropriate here since formatters aren't yet initialized.


86-102: Clean helper functions for flag detection.

Both hasVersionFlag and hasUseVersionFlag are focused and correct. The intentional limitation of hasVersionFlag to args[1] is well-documented and appropriate for catching the simple "atmos --version" case early.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 31, 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 (2)
cmd/toolchain/exec.go (1)

18-18: Consider adding usage examples to the Long description.

Per coding guidelines, command help should include examples. Adding a few usage examples would improve discoverability and usability.

💡 Example enhancement
-	Long:         `Execute a tool with a specific version, installing it if necessary.`,
+	Long:         `Execute a tool with a specific version, installing it if necessary.
+
+Examples:
+  # Execute terraform with version 1.5.0
+  atmos toolchain exec [email protected] -- version
+
+  # Execute kubectl with version 1.28.0, passing additional arguments
+  atmos toolchain exec [email protected] -- get pods -n default`,
main.go (1)

3-13: Minor: Group the log import with other Atmos packages.

The log import should be in the third group alongside cmd and errUtils per the import organization guideline (stdlib, 3rd-party non-Atmos, Atmos packages).

🔎 Proposed import reorg
 import (
 	"os"
 	"os/signal"
 	"strings"
 	"syscall"
 
-	log "github.com/cloudposse/atmos/pkg/logger"
-
 	"github.com/cloudposse/atmos/cmd"
 	errUtils "github.com/cloudposse/atmos/errors"
+	log "github.com/cloudposse/atmos/pkg/logger"
 )
📜 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 f778a2c and 61de449.

📒 Files selected for processing (3)
  • cmd/toolchain/exec.go
  • examples/toolchain/custom-registry/README.md
  • main.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: Use context.Context only for cancellation signals, deadlines/timeouts, and request-scoped values (sparingly). DO NOT use context for configuration, dependencies, or avoiding proper function parameters. Context should be first parameter in functions that accept it
All comments must end with periods (enforced by godot linter)
NEVER delete existing comments without a very strong reason. Preserve helpful comments explaining why/how/what/where. Update comments to match code when refactoring
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. Use nil if no atmosConfig param. Exceptions: trivial getters/setters, command constructors, simple factories, functions that onl...

Files:

  • main.go
  • cmd/toolchain/exec.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

NEVER call viper.BindEnv() or viper.BindPFlag() directly. Commands MUST use flags.NewStandardParser() for command-specific flags. See cmd/version/version.go for reference implementation

Files:

  • cmd/toolchain/exec.go
{cmd,internal}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

{cmd,internal}/**/*.go: Use I/O layer (pkg/io/) for stream access and UI layer (pkg/ui/) for formatting. Output data via data.Write/Writef/Writeln/WriteJSON/WriteYAML to stdout. Output UI messages via ui.Write/Writef/Writeln/Success/Error/Warning/Info/Markdown to stderr. DO NOT use fmt.Fprintf, fmt.Println, os.Stdout, or os.Stderr
Assume full TTY when writing output code. System automatically handles color degradation, width adaptation, TTY detection, CI detection, markdown rendering, icon support, secret masking, and format-aware masking
Telemetry is auto-enabled via RootCmd.ExecuteC(). Non-standard paths use telemetry.CaptureCmd(). Never capture user data

Files:

  • cmd/toolchain/exec.go
{cmd,internal,pkg/ui}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Use colors from pkg/ui/theme/colors.go for styling output

Files:

  • cmd/toolchain/exec.go
🧠 Learnings (30)
📓 Common learnings
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).
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.
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: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.
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: 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: 768
File: internal/exec/vendor_utils.go:496-513
Timestamp: 2024-11-22T12:38:33.132Z
Learning: In the Atmos project, continue to flag path traversal issues in code reviews but acknowledge when they are expected and acceptable in specific cases.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain should follow XDG Base Directory Specification like the rest of atmos core, using XDG_CACHE_HOME environment variable when available and falling back to ~/.cache when not set, instead of hardcoding ~/.cache/tools-cache paths.
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.
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.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.
Learnt from: 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.
📚 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:

  • main.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.mod,go.sum} : Manage dependencies with Go modules and keep dependencies up to date while minimizing external dependencies

Applied to files:

  • main.go
📚 Learning: 2025-01-17T00:21:32.987Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:3-3
Timestamp: 2025-01-17T00:21:32.987Z
Learning: The project uses Go version 1.23.0 which has been confirmed by the maintainer to be working in production for months. Do not flag this as an invalid Go version.

Applied to files:

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

Applied to files:

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

Applied to files:

  • main.go
📚 Learning: 2024-11-07T20:16:15.381Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 766
File: cmd/cmd_utils.go:177-178
Timestamp: 2024-11-07T20:16:15.381Z
Learning: In 'cmd/cmd_utils.go', using `os.Exit(1)` directly is acceptable in this context, and wrapping it with deferred cleanup is considered unnecessary.

Applied to files:

  • main.go
📚 Learning: 2025-04-04T02:03:21.906Z
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.

Applied to files:

  • main.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:

  • main.go
📚 Learning: 2025-01-18T15:18:35.475Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/root.go:172-178
Timestamp: 2025-01-18T15:18:35.475Z
Learning: The `showUsageAndExit` function in `cmd/cmd_utils.go` terminates the program with `os.Exit(1)` and never returns to the caller, making error handling unnecessary for calls to this function.

Applied to files:

  • main.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:

  • main.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:

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

Applied to files:

  • main.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:

  • main.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:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • main.go
📚 Learning: 2025-12-30T20:13:29.819Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T20:13:29.819Z
Learning: Applies to cmd/**/*.go : NEVER call viper.BindEnv() or viper.BindPFlag() directly. Commands MUST use flags.NewStandardParser() for command-specific flags. See cmd/version/version.go for reference implementation

Applied to files:

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

Applied to files:

  • main.go
📚 Learning: 2025-12-13T04:37:45.831Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/toolchain/get.go:23-40
Timestamp: 2025-12-13T04:37:45.831Z
Learning: In cmd/toolchain/get.go, the get subcommand intentionally uses cobra.MaximumNArgs(1) so it works with zero args (list all tools) or one arg (a specific tool). Flags are defined via flags.NewStandardParser() with --all (bool) and --limit (int); no direct viper.BindEnv/BindPFlag calls are used.

Applied to files:

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

Applied to files:

  • main.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:

  • main.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:

  • main.go
  • cmd/toolchain/exec.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/toolchain/exec.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/toolchain/exec.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/toolchain/exec.go
📚 Learning: 2025-12-30T20:13:29.819Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T20:13:29.819Z
Learning: Use registry pattern for extensibility. All new commands MUST use command registry pattern with CommandProvider interface. See existing implementations in cmd/internal/registry.go and pkg/store/registry.go

Applied to files:

  • cmd/toolchain/exec.go
📚 Learning: 2025-11-10T23:23:39.771Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/registry/aqua/aqua_test.go:417-442
Timestamp: 2025-11-10T23:23:39.771Z
Learning: In Atmos toolchain AquaRegistry, tests should not hit real GitHub. Use the options pattern via WithGitHubBaseURL to inject an httptest server URL and make GetLatestVersion/GetAvailableVersions deterministic.

Applied to files:

  • examples/toolchain/custom-registry/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:

  • examples/toolchain/custom-registry/README.md
🧬 Code graph analysis (1)
cmd/toolchain/exec.go (2)
pkg/flags/positional_args_builder.go (1)
  • PositionalArgsBuilder (52-54)
pkg/flags/compat/compatibility_flags.go (1)
  • CompatibilityFlag (33-37)
🪛 LanguageTool
examples/toolchain/custom-registry/README.md

[uncategorized] ~80-~80: The official name of this software platform is spelled with a capital “H”.
Context: ...ier (owner/repo) - type: Source type (github_release, http, etc.) - asset: GitHub ...

(GITHUB)

⏰ 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 (8)
examples/toolchain/custom-registry/README.md (1)

1-257: Comprehensive and well-structured documentation for custom Aqua-format registries.

This README effectively guides users through creating and managing custom registries. The progression from patterns → format → use cases → implementation is clear, and the practical examples (corporate tools, version pinning, mirroring, air-gapped environments) cover real-world scenarios. The troubleshooting table and best practices section are especially helpful.

The distinction between single index file and per-package directory patterns is clearly explained, with the recommendation to use single index file appropriately emphasized. YAML examples are consistent and syntactically sound, and the reference links to Aqua and Atmos documentation provide good external validation.

cmd/toolchain/exec.go (2)

15-34: Command structure and error handling look solid.

The use of MinimumNArgs(1) correctly requires the tool specification while allowing additional args to be passed through. The special case handling for exec.ExitError appropriately preserves the executed tool's exit code, and SilenceUsage: true avoids redundant output.


36-61: Provider implementation is correct and consistent.

The ExecCommandProvider properly implements the CommandProvider interface, returning nil for all builder methods since this command doesn't require custom flag handling. The simple getter methods are appropriately exempt from performance tracking per guidelines.

main.go (5)

24-30: Solid test-compatibility improvement.

The switch to errUtils.OsExit enables test interception while preserving POSIX signal exit semantics. Clear rationale in the comment.


35-38: Clean separation of entry point logic.

Extracting run() while keeping signal setup and final exit in main() is the right pattern for testability.


51-69: Good UX and consistent error handling.

The conflict check between --version and --use-version provides clear guidance. The ExecuteVersion error handling now matches the pattern used for cmd.Execute() errors (capture, format, return exit code) - the past review concern about direct os.Exit calls has been addressed.


71-87: Consistent error handling throughout.

The centralized formatter and exit code extraction pattern is applied uniformly. Returning exit codes instead of calling os.Exit directly makes the logic testable.


89-105: Well-scoped flag detection helpers.

The intentional simplicity of hasVersionFlag (first arg only) for early exit is clearly documented, while hasUseVersionFlag scans all args to catch conflicts. Both strategies align with their purposes.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
main.go (1)

67-67: Add period to end comment.

Per the godot linter requirement, all comments must end with periods.

🔎 Proposed fix
-	return 0 // Exit normally after printing version
+	return 0 // Exit normally after printing version.
cmd/toolchain/exec.go (1)

43-68: Provider implementation follows the registry pattern correctly.

The ExecCommandProvider properly implements the CommandProvider interface and mirrors the structure of other toolchain command providers. Returning nil for flags/args/compat is appropriate since this command delegates directly to the tool.

Optional: Add godoc comment for better discoverability
+// ExecCommandProvider implements CommandProvider for the toolchain exec command.
 type ExecCommandProvider struct{}

This helps developers quickly understand the type's purpose when browsing godoc or IDE tooltips.

📜 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 61de449 and 56a46ca.

📒 Files selected for processing (2)
  • cmd/toolchain/exec.go
  • main.go
🧰 Additional context used
📓 Path-based instructions (4)
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

NEVER call viper.BindEnv() or viper.BindPFlag() directly. Commands MUST use flags.NewStandardParser() for command-specific flags. See cmd/version/version.go for reference implementation

Files:

  • cmd/toolchain/exec.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: Use context.Context only for cancellation signals, deadlines/timeouts, and request-scoped values (sparingly). DO NOT use context for configuration, dependencies, or avoiding proper function parameters. Context should be first parameter in functions that accept it
All comments must end with periods (enforced by godot linter)
NEVER delete existing comments without a very strong reason. Preserve helpful comments explaining why/how/what/where. Update comments to match code when refactoring
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. Use nil if no atmosConfig param. Exceptions: trivial getters/setters, command constructors, simple factories, functions that onl...

Files:

  • cmd/toolchain/exec.go
  • main.go
{cmd,internal}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

{cmd,internal}/**/*.go: Use I/O layer (pkg/io/) for stream access and UI layer (pkg/ui/) for formatting. Output data via data.Write/Writef/Writeln/WriteJSON/WriteYAML to stdout. Output UI messages via ui.Write/Writef/Writeln/Success/Error/Warning/Info/Markdown to stderr. DO NOT use fmt.Fprintf, fmt.Println, os.Stdout, or os.Stderr
Assume full TTY when writing output code. System automatically handles color degradation, width adaptation, TTY detection, CI detection, markdown rendering, icon support, secret masking, and format-aware masking
Telemetry is auto-enabled via RootCmd.ExecuteC(). Non-standard paths use telemetry.CaptureCmd(). Never capture user data

Files:

  • cmd/toolchain/exec.go
{cmd,internal,pkg/ui}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Use colors from pkg/ui/theme/colors.go for styling output

Files:

  • cmd/toolchain/exec.go
🧠 Learnings (31)
📓 Common learnings
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.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).
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: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.
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: osterman
Repo: cloudposse/atmos PR: 768
File: internal/exec/vendor_utils.go:496-513
Timestamp: 2024-11-22T12:38:33.132Z
Learning: In the Atmos project, continue to flag path traversal issues in code reviews but acknowledge when they are expected and acceptable in specific cases.
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.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain should follow XDG Base Directory Specification like the rest of atmos core, using XDG_CACHE_HOME environment variable when available and falling back to ~/.cache when not set, instead of hardcoding ~/.cache/tools-cache paths.
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.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.
Learnt from: 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.
📚 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/toolchain/exec.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/toolchain/exec.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/toolchain/exec.go
📚 Learning: 2025-12-30T20:13:29.819Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T20:13:29.819Z
Learning: Use registry pattern for extensibility. All new commands MUST use command registry pattern with CommandProvider interface. See existing implementations in cmd/internal/registry.go and pkg/store/registry.go

Applied to files:

  • cmd/toolchain/exec.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/toolchain/exec.go
  • main.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:

  • cmd/toolchain/exec.go
  • main.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:

  • main.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.mod,go.sum} : Manage dependencies with Go modules and keep dependencies up to date while minimizing external dependencies

Applied to files:

  • main.go
📚 Learning: 2025-01-17T00:21:32.987Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:3-3
Timestamp: 2025-01-17T00:21:32.987Z
Learning: The project uses Go version 1.23.0 which has been confirmed by the maintainer to be working in production for months. Do not flag this as an invalid Go version.

Applied to files:

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

Applied to files:

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

Applied to files:

  • main.go
📚 Learning: 2024-11-07T20:16:15.381Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 766
File: cmd/cmd_utils.go:177-178
Timestamp: 2024-11-07T20:16:15.381Z
Learning: In 'cmd/cmd_utils.go', using `os.Exit(1)` directly is acceptable in this context, and wrapping it with deferred cleanup is considered unnecessary.

Applied to files:

  • main.go
📚 Learning: 2025-04-04T02:03:21.906Z
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.

Applied to files:

  • main.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:

  • main.go
📚 Learning: 2025-01-18T15:18:35.475Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/root.go:172-178
Timestamp: 2025-01-18T15:18:35.475Z
Learning: The `showUsageAndExit` function in `cmd/cmd_utils.go` terminates the program with `os.Exit(1)` and never returns to the caller, making error handling unnecessary for calls to this function.

Applied to files:

  • main.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:

  • main.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:

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

Applied to files:

  • main.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:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • main.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:

  • main.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:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • main.go
📚 Learning: 2025-12-30T20:13:29.819Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T20:13:29.819Z
Learning: Applies to cmd/**/*.go : NEVER call viper.BindEnv() or viper.BindPFlag() directly. Commands MUST use flags.NewStandardParser() for command-specific flags. See cmd/version/version.go for reference implementation

Applied to files:

  • main.go
📚 Learning: 2025-12-13T04:37:45.831Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/toolchain/get.go:23-40
Timestamp: 2025-12-13T04:37:45.831Z
Learning: In cmd/toolchain/get.go, the get subcommand intentionally uses cobra.MaximumNArgs(1) so it works with zero args (list all tools) or one arg (a specific tool). Flags are defined via flags.NewStandardParser() with --all (bool) and --limit (int); no direct viper.BindEnv/BindPFlag calls are used.

Applied to files:

  • main.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:

  • main.go
🧬 Code graph analysis (2)
cmd/toolchain/exec.go (2)
pkg/flags/positional_args_builder.go (1)
  • PositionalArgsBuilder (52-54)
pkg/flags/compat/compatibility_flags.go (1)
  • CompatibilityFlag (33-37)
main.go (4)
errors/error_funcs.go (1)
  • OsExit (25-25)
cmd/root.go (2)
  • ExecuteVersion (1219-1227)
  • Execute (1274-1364)
errors/sentry.go (1)
  • CaptureError (69-109)
errors/exit_code.go (1)
  • GetExitCode (60-96)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (46)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
🔇 Additional comments (4)
main.go (2)

60-67: Past issue resolved: error handling is now consistent.

The previous review flagged that CheckErrorPrintAndExit bypassed the exit code return pattern. This has been fixed—ExecuteVersion errors now follow the same CaptureErrorFormatGetExitCode flow as cmd.Execute() errors, enabling centralized exit handling and testability.


39-86: Solid refactoring: run() enables testability and consistent exit handling.

Encapsulating the main logic in run() with exit code returns allows proper defer cleanup, eliminates os.Exit calls in testable paths, and centralizes error capture/formatting. The early --version conflict detection provides clear user feedback before initialization.

cmd/toolchain/exec.go (2)

1-13: Nice clean import organization.

The three-group structure (stdlib → third-party → atmos packages) with proper aliases follows the project conventions perfectly.


15-41: Solid command implementation.

The exec command is well-structured with clear help text, proper argument validation, and correct error handling. The pattern of detecting exec.ExitError and exiting with the tool's code (lines 34-36) ensures transparent pass-through of tool exit statuses, which is exactly what users expect from an exec wrapper.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 31, 2025
Add TTY check before starting the Bubble Tea spinner to prevent potential
hangs in CI environments where no terminal is available.

The issue was that tea.Program.Run() could block indefinitely when trying
to initialize the terminal in non-TTY environments like CI runners.

This fix adds isTTY() check at the start of the spinner, similar to how
info.go already handles TTY detection for its version fetch spinner.

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

Co-Authored-By: Claude <[email protected]>
- main.go: Add period to end of comment (godot linter requirement)
- cmd/toolchain/exec.go: Improve godoc comment for ExecCommandProvider

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

Co-Authored-By: Claude <[email protected]>
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)
cmd/toolchain/exec.go (1)

43-68: Add godoc comments for exported type and methods.

The exported ExecCommandProvider type and its methods lack documentation. Per coding guidelines, all exported entities should have godoc comments ending with periods.

🔎 Proposed documentation additions
+// ExecCommandProvider implements CommandProvider for the toolchain exec command.
+// It provides the ability to execute tools with specific versions, installing them if necessary.
 type ExecCommandProvider struct{}

+// GetCommand returns the Cobra command for toolchain exec.
 func (e *ExecCommandProvider) GetCommand() *cobra.Command {
 	return execCmd
 }

+// GetName returns the command name.
 func (e *ExecCommandProvider) GetName() string {
 	return "exec"
 }

+// GetGroup returns the command group for help display.
 func (e *ExecCommandProvider) GetGroup() string {
 	return "Toolchain Commands"
 }

+// GetFlagsBuilder returns nil as this command has no flags.
 func (e *ExecCommandProvider) GetFlagsBuilder() flags.Builder {
 	return nil
 }

+// GetPositionalArgsBuilder returns nil as positional args are handled by Cobra validation.
 func (e *ExecCommandProvider) GetPositionalArgsBuilder() *flags.PositionalArgsBuilder {
 	return nil
 }

+// GetCompatibilityFlags returns nil as this command has no compatibility flags.
 func (e *ExecCommandProvider) GetCompatibilityFlags() map[string]compat.CompatibilityFlag {
 	return 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 56a46ca and 456b0c2.

📒 Files selected for processing (2)
  • cmd/toolchain/exec.go
  • main.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: Use context.Context only for cancellation signals, deadlines/timeouts, and request-scoped values (sparingly). DO NOT use context for configuration, dependencies, or avoiding proper function parameters. Context should be first parameter in functions that accept it
All comments must end with periods (enforced by godot linter)
NEVER delete existing comments without a very strong reason. Preserve helpful comments explaining why/how/what/where. Update comments to match code when refactoring
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. Use nil if no atmosConfig param. Exceptions: trivial getters/setters, command constructors, simple factories, functions that onl...

Files:

  • main.go
  • cmd/toolchain/exec.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

NEVER call viper.BindEnv() or viper.BindPFlag() directly. Commands MUST use flags.NewStandardParser() for command-specific flags. See cmd/version/version.go for reference implementation

Files:

  • cmd/toolchain/exec.go
{cmd,internal}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

{cmd,internal}/**/*.go: Use I/O layer (pkg/io/) for stream access and UI layer (pkg/ui/) for formatting. Output data via data.Write/Writef/Writeln/WriteJSON/WriteYAML to stdout. Output UI messages via ui.Write/Writef/Writeln/Success/Error/Warning/Info/Markdown to stderr. DO NOT use fmt.Fprintf, fmt.Println, os.Stdout, or os.Stderr
Assume full TTY when writing output code. System automatically handles color degradation, width adaptation, TTY detection, CI detection, markdown rendering, icon support, secret masking, and format-aware masking
Telemetry is auto-enabled via RootCmd.ExecuteC(). Non-standard paths use telemetry.CaptureCmd(). Never capture user data

Files:

  • cmd/toolchain/exec.go
{cmd,internal,pkg/ui}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Use colors from pkg/ui/theme/colors.go for styling output

Files:

  • cmd/toolchain/exec.go
🧠 Learnings (31)
📓 Common learnings
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).
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.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.
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: 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.
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: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain should follow XDG Base Directory Specification like the rest of atmos core, using XDG_CACHE_HOME environment variable when available and falling back to ~/.cache when not set, instead of hardcoding ~/.cache/tools-cache paths.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 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.
📚 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:

  • main.go
📚 Learning: 2025-01-17T00:21:32.987Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:3-3
Timestamp: 2025-01-17T00:21:32.987Z
Learning: The project uses Go version 1.23.0 which has been confirmed by the maintainer to be working in production for months. Do not flag this as an invalid Go version.

Applied to files:

  • main.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.mod,go.sum} : Manage dependencies with Go modules and keep dependencies up to date while minimizing external dependencies

Applied to files:

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

Applied to files:

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

Applied to files:

  • main.go
📚 Learning: 2024-11-07T20:16:15.381Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 766
File: cmd/cmd_utils.go:177-178
Timestamp: 2024-11-07T20:16:15.381Z
Learning: In 'cmd/cmd_utils.go', using `os.Exit(1)` directly is acceptable in this context, and wrapping it with deferred cleanup is considered unnecessary.

Applied to files:

  • main.go
📚 Learning: 2025-04-04T02:03:21.906Z
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.

Applied to files:

  • main.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:

  • main.go
📚 Learning: 2025-01-18T15:18:35.475Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/root.go:172-178
Timestamp: 2025-01-18T15:18:35.475Z
Learning: The `showUsageAndExit` function in `cmd/cmd_utils.go` terminates the program with `os.Exit(1)` and never returns to the caller, making error handling unnecessary for calls to this function.

Applied to files:

  • main.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:

  • main.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:

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

Applied to files:

  • main.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:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • main.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:

  • main.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:

  • main.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:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • main.go
📚 Learning: 2025-12-30T20:13:29.819Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T20:13:29.819Z
Learning: Applies to cmd/**/*.go : NEVER call viper.BindEnv() or viper.BindPFlag() directly. Commands MUST use flags.NewStandardParser() for command-specific flags. See cmd/version/version.go for reference implementation

Applied to files:

  • main.go
📚 Learning: 2025-12-13T04:37:45.831Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/toolchain/get.go:23-40
Timestamp: 2025-12-13T04:37:45.831Z
Learning: In cmd/toolchain/get.go, the get subcommand intentionally uses cobra.MaximumNArgs(1) so it works with zero args (list all tools) or one arg (a specific tool). Flags are defined via flags.NewStandardParser() with --all (bool) and --limit (int); no direct viper.BindEnv/BindPFlag calls are used.

Applied to files:

  • main.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:

  • main.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:

  • main.go
  • cmd/toolchain/exec.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/toolchain/exec.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/toolchain/exec.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/toolchain/exec.go
📚 Learning: 2025-12-30T20:13:29.819Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T20:13:29.819Z
Learning: Use registry pattern for extensibility. All new commands MUST use command registry pattern with CommandProvider interface. See existing implementations in cmd/internal/registry.go and pkg/store/registry.go

Applied to files:

  • cmd/toolchain/exec.go
🧬 Code graph analysis (2)
main.go (4)
cmd/root.go (2)
  • ExecuteVersion (1219-1227)
  • Execute (1274-1364)
errors/sentry.go (1)
  • CaptureError (69-109)
errors/formatter.go (1)
  • DefaultFormatterConfig (51-56)
errors/exit_code.go (1)
  • GetExitCode (60-96)
cmd/toolchain/exec.go (2)
pkg/flags/positional_args_builder.go (1)
  • PositionalArgsBuilder (52-54)
pkg/flags/compat/compatibility_flags.go (1)
  • CompatibilityFlag (33-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). (3)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
🔇 Additional comments (6)
main.go (5)

14-37: LGTM!

The refactored main() properly delegates to run() and uses errUtils.OsExit for test interception. Signal handling is correct, and the comments explain the Go 1.25+ compatibility rationale.


50-67: Early version flag handling is well-implemented.

The conflict detection between --version and --use-version provides clear, user-friendly error messages. The early return pattern avoids unnecessary Cobra initialization for simple version queries.


60-66: Error handling now consistent with Execute() path.

The error handling for ExecuteVersion() now matches the pattern used for cmd.Execute() (lines 72-82), using centralized error capture and formatting rather than direct exit. This addresses the previous review concern about inconsistent error handling.


88-94: LGTM!

The simple check for --version as the first argument is appropriate for early exit optimization. The comment clearly explains why it's intentionally limited in scope.


96-104: LGTM!

The helper correctly detects both --use-version and --use-version=VALUE forms by checking the prefix. Simple and effective.

cmd/toolchain/exec.go (1)

28-40: The return statement is correct and required.

The code follows Go's type-checking requirements. While os.Exit() terminates the program at runtime, Go mandates a return statement for functions with a return type. The return statement remains reachable during testing when OsExit is mocked, and the pattern is consistent with the codebase.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 1, 2026
coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 1, 2026
@aknysh aknysh merged commit 3292013 into main Jan 1, 2026
59 checks passed
@aknysh aknysh deleted the tools-experiment branch January 1, 2026 18:24
@mergify mergify bot removed the needs-cloudposse Needs Cloud Posse assistance label Jan 1, 2026
@github-actions
Copy link

github-actions bot commented Jan 1, 2026

Warning

Release Documentation Required

This PR is labeled minor or major and requires documentation updates:

  • Changelog entry - Add a blog post in website/blog/YYYY-MM-DD-feature-name.mdx
  • Roadmap update - Update website/src/data/roadmap.js with the new milestone

Alternatively: If this change doesn't require release documentation, remove the minor or major label.

osterman added a commit that referenced this pull request Jan 1, 2026
Resolve conflicts:
- cmd/auth/whoami.go: Add both data and flags imports
- pkg/flags/global_registry_test.go: Merge both HEAD's NoOptDefVal tests and main's pager tests
- tests/snapshots/TestCLICommands_atmos_auth_exec_--help.stdout.golden: Use main's wording
- Delete obsolete cmd/auth_login_test.go and cmd/auth_shell_test.go
@github-actions
Copy link

github-actions bot commented Jan 2, 2026

These changes were released in v1.203.0.

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.

4 participants