Skip to content

Conversation

@osterman
Copy link
Member

@osterman osterman commented Dec 28, 2025

What

Refactored the atmos auth command family from legacy flat file structure to the Command Registry pattern with proper flag handling via pkg/flags/StandardParser.

  • Migrated 11 auth files from cmd/auth*.go flat structure to organized cmd/auth/ directory with CommandProvider interface
  • Implemented StandardParser for unified flag handling across all subcommands
  • Implemented SeparatedArgs pattern for pass-through commands (shell, exec) instead of DisableFlagParsing
  • Created proper command hierarchy with nested auth user subcommand

Why

  • Eliminates linting violations: Removes forbidden direct calls to viper.BindPFlag() and viper.BindEnv() (enforced by Forbidigo linter)
  • Improves code organization: Groups related commands in dedicated directory structure
  • Enables plugin architecture: Commands self-register via CommandProvider interface for future extensibility
  • Consistent flag handling: All commands use unified StandardParser for flags, environment variables, and defaults
  • Better architecture compliance: Follows the Command Registry pattern used throughout Atmos codebase

Testing

  • All tests pass: make testacc
  • Linting passes: make lint
  • Build succeeds: make build
  • CLI works correctly: ./build/atmos auth --help shows all subcommands
  • Identity flag handling properly resolves Cobra's NoOptDefVal quirk

Summary by CodeRabbit

  • New Features

    • Introduces a full authentication command suite (auth login, logout, list, console, env, exec, shell, validate, whoami, user) for managing identities, credentials, and provider flows.
  • Enhancements

    • Improved identity flag handling — accepts both "--identity value" and "--identity=value", supports interactive selection and better behavior when used before "--".
    • Commands now provide richer shell completion and more robust flag parsing.
  • Documentation

    • Added and updated usage examples and guidance for authentication-related commands and global identity flags.

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

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

mergify bot commented Dec 28, 2025

Warning

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

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

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

@github-actions
Copy link

github-actions bot commented Dec 28, 2025

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 28, 2025

Warning

Rate limit exceeded

@osterman has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 24 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between f25fe94 and fdba52b.

📒 Files selected for processing (74)
  • cmd/auth.go
  • cmd/auth/auth.go
  • cmd/auth/auth_test.go
  • cmd/auth/completion.go
  • cmd/auth/completion_test.go
  • cmd/auth/console.go
  • cmd/auth/console_test.go
  • cmd/auth/env.go
  • cmd/auth/env_test.go
  • cmd/auth/exec.go
  • cmd/auth/exec_test.go
  • cmd/auth/helpers.go
  • cmd/auth/helpers_test.go
  • cmd/auth/identity_resolution_test.go
  • cmd/auth/list.go
  • cmd/auth/list_test.go
  • cmd/auth/login.go
  • cmd/auth/login_test.go
  • cmd/auth/logout.go
  • cmd/auth/markdown/atmos_auth_console_usage.md
  • cmd/auth/markdown/atmos_auth_list_usage.md
  • cmd/auth/markdown/atmos_auth_logout_usage.md
  • cmd/auth/markdown/atmos_auth_shell_usage.md
  • cmd/auth/shell.go
  • cmd/auth/shell_test.go
  • cmd/auth/user/configure.go
  • cmd/auth/user/configure_test.go
  • cmd/auth/user/helpers.go
  • cmd/auth/user/helpers_test.go
  • cmd/auth/user/user.go
  • cmd/auth/user/user_test.go
  • cmd/auth/validate.go
  • cmd/auth/validate_test.go
  • cmd/auth/whoami.go
  • cmd/auth/whoami_test.go
  • cmd/auth_caching_test.go
  • cmd/auth_console_test.go
  • cmd/auth_env.go
  • cmd/auth_env_test.go
  • cmd/auth_exec.go
  • cmd/auth_exec_test.go
  • cmd/auth_integration_test.go
  • cmd/auth_list_test.go
  • cmd/auth_login.go
  • cmd/auth_login_test.go
  • cmd/auth_logout_test.go
  • cmd/auth_shell.go
  • cmd/auth_shell_test.go
  • cmd/auth_user.go
  • cmd/auth_user_helpers_test.go
  • cmd/auth_user_test.go
  • cmd/auth_validate.go
  • cmd/auth_validate_test.go
  • cmd/auth_whoami_test.go
  • cmd/auth_workflows_test.go
  • cmd/identity_flag_test.go
  • cmd/identity_helpers.go
  • cmd/root.go
  • errors/errors.go
  • pkg/flags/flag_parser.go
  • pkg/flags/global_registry.go
  • pkg/flags/global_registry_test.go
  • pkg/flags/preprocess/nooptdefval.go
  • pkg/flags/preprocess/nooptdefval_test.go
  • pkg/flags/preprocess/preprocess.go
  • pkg/flags/preprocess/preprocess_test.go
  • pkg/flags/registry.go
  • pkg/flags/registry_preprocess_test.go
  • tests/cli_describe_component_test.go
  • tests/describe_test.go
  • tests/snapshots/TestCLICommands_atmos_auth_env_--help.stdout.golden
  • website/docs/cli/commands/auth/usage.mdx
  • website/docs/cli/commands/terraform/usage.mdx
  • website/docs/cli/global-flags.mdx
📝 Walkthrough

Walkthrough

Restructures the auth CLI by moving a monolithic auth command into a modular cmd/auth/ package with subcommands (login, logout, console, env, exec, shell, validate, whoami, user), adds a NoOptDefVal preprocessing pipeline for flags, and converts auth commands to parser-driven flag/Viper binding.

Changes

Cohort / File(s) Summary
Auth package core
cmd/auth.go (removed), cmd/auth/auth.go, cmd/auth/helpers.go
Replace top-level auth initialization with a modular auth package and AuthCommandProvider; add identity constants and CreateAuthManager / BuildConfigAndStacksInfo helpers.
Auth subcommands
cmd/auth/console.go, cmd/auth/env.go, cmd/auth/exec.go, cmd/auth/login.go, cmd/auth/logout.go, cmd/auth/shell.go, cmd/auth/validate.go, cmd/auth/whoami.go
New/rewritten command modules under cmd/auth/ using flags.StandardParser, persistent identity flag wiring, Viper binding, identity resolution helpers, and reworked command execution flows.
Completion helpers
cmd/auth/completion.go
Add identity/provider/components completion and registration helpers for auth commands.
User management
cmd/auth/user/user.go, cmd/auth/user/configure.go, cmd/auth/user/helpers.go
New user subcommand group and interactive AWS user credential configuration with keyring storage and prompt UI.
Documentation / examples
cmd/auth/markdown/*.md
New usage docs for auth console, list, logout, shell and related examples.
Flag preprocessing infra
pkg/flags/preprocess/preprocess.go, pkg/flags/preprocess/nooptdefval.go, pkg/flags/preprocess/*_test.go
New Preprocessor/Pipeline and NoOptDefValPreprocessor to rewrite space-separated NoOptDefVal flags into equals-form before Cobra parsing.
Flag parser & registry changes
pkg/flags/flag_parser.go, pkg/flags/global_registry.go, pkg/flags/global_registry_test.go, pkg/flags/registry.go
Integrate preprocessing into AtmosFlagParser, add BuildConfigAndStacksInfo wrapper, remove old registry PreprocessNoOptDefValArgs implementation.
Root preprocessing
cmd/root.go
Add preprocessArgs orchestration (NoOptDefVal + compatibility flag handling) and side-effect import to auto-register auth command.
Identity helpers & instrumentation
cmd/identity_helpers.go
Add perf.Track instrumentation and switch internal references to config-based identity constants.
Errors and internal update
errors/errors.go, internal/exec/helmfile.go
Add ErrComponentPathNotFound sentinel and update helmfile to use it for not-found cases.
Tests removed / migrated
Many cmd/*_test.go and auth-related tests (see diff)
Removal of ~15 authentication-related test files (unit/integration/e2e) — test coverage appears relocated or restructured elsewhere.
Tests added / updated
pkg/flags/preprocess/*_test.go, pkg/flags/global_registry_test.go, tests/*
Add tests for preprocess pipeline and registry preprocessing; add TTY guards and update CLI help snapshots and docs.

Sequence Diagram(s)

(Skipped — changes are broad and spread across many command modules; no single concise multi-component sequential flow was requested for diagramming.)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

minor

Suggested reviewers

  • aknysh
  • milldr

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 65.69% 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 accurately summarizes the main refactoring: migrating auth commands to use Command Registry and StandardParser patterns.

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (7)
cmd/auth/markdown/atmos_auth_console_usage.md (1)

1-59: Good coverage of console options, but missing command prompts.

Per project convention, CLI docs use $ atmos command format with the dollar sign prompt. Other auth docs like atmos_auth_logout_usage.md follow this pattern. Consider adding $ prefix to commands for consistency.

🔎 Example fix for first code block
 ```shell
-atmos auth console
+$ atmos auth console
</details>

</blockquote></details>
<details>
<summary>cmd/auth/helpers.go (1)</summary><blockquote>

`111-112`: **Consider using UI layer for stderr output.**

Per coding guidelines, `fmt.Fprintf(os.Stderr, ...)` should be replaced with the UI layer utilities. Line 64 correctly uses `u.PrintfMessageToTUI`, but line 111 uses direct stderr write.

<details>
<summary>🔎 Suggested fix</summary>

```diff
-	fmt.Fprintf(os.Stderr, "%s\n\n", t)
+	u.PrintfMessageToTUI("%s\n\n", t)
cmd/auth/completion.go (1)

47-72: Works correctly, minor duplication with identityFlagCompletion.

The identity gathering logic (lines 57-69) duplicates lines 19-31. Consider extracting a helper if more completion functions need this pattern.

🔎 Optional: Extract helper function
// getIdentityNames returns sorted identity names from config.
func getIdentityNames() ([]string, error) {
	defer perf.Track(nil, "auth.getIdentityNames")()

	atmosConfig, err := cfg.InitCliConfig(schema.ConfigAndStacksInfo{}, false)
	if err != nil {
		return nil, err
	}

	var identities []string
	if atmosConfig.Auth.Identities != nil {
		for name := range atmosConfig.Auth.Identities {
			identities = append(identities, name)
		}
	}
	sort.Strings(identities)
	return identities, nil
}
cmd/auth/console.go (1)

278-293: Consider propagating global flags to InitCliConfig.

Per learnings, when calling cfg.InitCliConfig, you should populate schema.ConfigAndStacksInfo with global flag values using flags.ParseGlobalFlags(cmd, v) rather than passing an empty struct. This ensures config selection flags (--base-path, --config, --config-path, --profile) are respected.

🔎 Suggested approach
 func initializeAuthManager() (types.AuthManager, error) {
 	defer perf.Track(nil, "auth.initializeAuthManager")()

-	atmosConfig, err := cfg.InitCliConfig(schema.ConfigAndStacksInfo{}, false)
+	// TODO: Consider accepting cmd and viper to populate ConfigAndStacksInfo
+	// with global flags for config path resolution.
+	atmosConfig, err := cfg.InitCliConfig(schema.ConfigAndStacksInfo{}, false)
 	if err != nil {
 		return nil, fmt.Errorf("%w: failed to load atmos config: %w", errUtils.ErrAuthConsole, err)
 	}
cmd/identity_helpers.go (1)

74-88: perf.Track on trivial normalizeIdentityValue may add overhead.

Per learnings, perf.Track() should exclude "trivial accessors/mutators where the tracking overhead would exceed the actual method cost." This function is a simple string comparison and switch. Consider removing the tracking here.

🔎 Remove perf tracking from trivial function
 func normalizeIdentityValue(value string) string {
-	defer perf.Track(nil, "cmd.normalizeIdentityValue")()
-
 	if value == "" {
 		return ""
 	}
cmd/auth/whoami.go (1)

171-183: Same config flag propagation note applies here.

Like initializeAuthManager in console.go, loadAuthManager passes an empty ConfigAndStacksInfo{}. Consider whether global flags should be propagated for config path resolution.

cmd/auth/user/configure.go (1)

69-73: Consider using UI layer for stderr output.

Per coding guidelines, UI messages should use pkg/ui/ or pkg/utils helpers (u.PrintfMessageToTUI, u.PrintfMarkdownToTUI) rather than direct fmt.Fprintln/fmt.Fprintf to stderr. This maintains consistency with other auth commands in the PR.

📜 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 b373a2d and 7d312eb.

📒 Files selected for processing (42)
  • cmd/auth.go
  • cmd/auth/auth.go
  • cmd/auth/completion.go
  • cmd/auth/console.go
  • cmd/auth/env.go
  • cmd/auth/exec.go
  • cmd/auth/helpers.go
  • cmd/auth/list.go
  • cmd/auth/login.go
  • cmd/auth/logout.go
  • cmd/auth/markdown/atmos_auth_console_usage.md
  • cmd/auth/markdown/atmos_auth_list_usage.md
  • cmd/auth/markdown/atmos_auth_logout_usage.md
  • cmd/auth/markdown/atmos_auth_shell_usage.md
  • cmd/auth/shell.go
  • cmd/auth/user/configure.go
  • cmd/auth/user/helpers.go
  • cmd/auth/user/user.go
  • cmd/auth/validate.go
  • cmd/auth/whoami.go
  • cmd/auth_caching_test.go
  • cmd/auth_console_test.go
  • cmd/auth_env.go
  • cmd/auth_env_test.go
  • cmd/auth_exec_test.go
  • cmd/auth_integration_test.go
  • cmd/auth_list_test.go
  • cmd/auth_login.go
  • cmd/auth_login_test.go
  • cmd/auth_logout_test.go
  • cmd/auth_shell.go
  • cmd/auth_shell_test.go
  • cmd/auth_user.go
  • cmd/auth_user_helpers_test.go
  • cmd/auth_user_test.go
  • cmd/auth_validate_test.go
  • cmd/auth_whoami_test.go
  • cmd/auth_workflows_test.go
  • cmd/identity_flag_test.go
  • cmd/identity_helpers.go
  • cmd/root.go
  • website/docs/quick-start/install-atmos.mdx
💤 Files with no reviewable changes (21)
  • cmd/auth_console_test.go
  • cmd/auth_integration_test.go
  • cmd/auth_env_test.go
  • cmd/auth_logout_test.go
  • cmd/auth_user_helpers_test.go
  • cmd/auth_validate_test.go
  • cmd/auth_user.go
  • cmd/identity_flag_test.go
  • cmd/auth_shell_test.go
  • cmd/auth_whoami_test.go
  • cmd/auth_env.go
  • cmd/auth_workflows_test.go
  • cmd/auth_login_test.go
  • cmd/auth_list_test.go
  • cmd/auth_login.go
  • cmd/auth.go
  • cmd/auth_exec_test.go
  • cmd/auth_caching_test.go
  • website/docs/quick-start/install-atmos.mdx
  • cmd/auth_user_test.go
  • cmd/auth_shell.go
🧰 Additional context used
📓 Path-based instructions (2)
cmd/**/*.go

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

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

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

Files:

  • cmd/auth/user/user.go
  • cmd/identity_helpers.go
  • cmd/auth/shell.go
  • cmd/auth/validate.go
  • cmd/auth/exec.go
  • cmd/root.go
  • cmd/auth/helpers.go
  • cmd/auth/user/helpers.go
  • cmd/auth/login.go
  • cmd/auth/env.go
  • cmd/auth/user/configure.go
  • cmd/auth/completion.go
  • cmd/auth/auth.go
  • cmd/auth/whoami.go
  • cmd/auth/list.go
  • cmd/auth/console.go
  • cmd/auth/logout.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: Context should be first parameter in functions that accept it
Use I/O layer (pkg/io/) for stream access and UI layer (pkg/ui/) for formatting - use data.Write/Writef/Writeln for stdout, ui.Write/Writef/Writeln for stderr - DO NOT use fmt.Fprintf(os.Stdout/Stderr) or fmt.Println
All comments must end with periods (enforced by godot linter)
Use three-group import organization separated by blank lines, sorted alphabetically: Go stdlib, 3rd-party (NOT cloudposse/atmos), 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
All errors MUST be wrapped using static errors defined in errors/errors.go - Use errors.Join for combining multiple errors, fmt.Errorf with %w for adding string context, error builder for complex errors, errors.Is() for error checking
Use go.uber.org/...

Files:

  • cmd/auth/user/user.go
  • cmd/identity_helpers.go
  • cmd/auth/shell.go
  • cmd/auth/validate.go
  • cmd/auth/exec.go
  • cmd/root.go
  • cmd/auth/helpers.go
  • cmd/auth/user/helpers.go
  • cmd/auth/login.go
  • cmd/auth/env.go
  • cmd/auth/user/configure.go
  • cmd/auth/completion.go
  • cmd/auth/auth.go
  • cmd/auth/whoami.go
  • cmd/auth/list.go
  • cmd/auth/console.go
  • cmd/auth/logout.go
🧠 Learnings (65)
📓 Common learnings
Learnt from: osterman
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-11-10T03:03:31.505Z
Learning: In the Atmos codebase, commands using the `StandardParser` flag pattern (from pkg/flags) do NOT need explicit `viper.BindPFlag()` calls in their code. The StandardParser encapsulates flag binding internally: flags are registered via `parser.RegisterFlags(cmd)` in init(), and bound via `parser.BindFlagsToViper(cmd, v)` in RunE, which internally calls viper.BindPFlag for each flag. This pattern is used throughout Atmos (e.g., cmd/toolchain/get.go, cmd/toolchain/info.go, cmd/toolchain/install.go, cmd/toolchain/path.go). Do not flag missing viper.BindPFlag calls when StandardParser is used.
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.
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1452
File: cmd/auth_login.go:43-44
Timestamp: 2025-09-07T18:07:00.549Z
Learning: In the atmos project, the identity flag is defined as a persistent flag on the auth root command (cmd/auth.go), making it available to all auth subcommands without needing to be redefined in each individual subcommand.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.
Learnt from: osterman
Repo: cloudposse/atmos PR: 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: 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: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 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: 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: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under `cmd/` directory
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-26T06:31:02.244Z
Learning: Use registry pattern for extensibility - all new commands MUST use command registry pattern via CommandProvider interface in cmd/internal/registry.go
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Use Viper for managing configuration, environment variables, and flags in CLI commands
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-26T06:31:02.244Z
Learning: Applies to cmd/**/*.go : Commands MUST use flags.NewStandardParser() for command-specific flags - NEVER call viper.BindEnv() or viper.BindPFlag() directly
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/manager.go:304-312
Timestamp: 2025-09-25T01:02:48.697Z
Learning: The auth manager in pkg/auth/manager.go should remain cloud-agnostic and not contain AWS-specific logic or references to specific cloud providers. Keep the manager generic and extensible.
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

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

Applied to files:

  • cmd/auth/markdown/atmos_auth_console_usage.md
  • cmd/auth/markdown/atmos_auth_shell_usage.md
📚 Learning: 2025-09-10T21:17:55.273Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/http_client_test.go:3-10
Timestamp: 2025-09-10T21:17:55.273Z
Learning: In the cloudposse/atmos repository, imports should never be changed as per samtholiya's coding guidelines.

Applied to files:

  • cmd/auth/markdown/atmos_auth_console_usage.md
  • cmd/root.go
📚 Learning: 2025-12-04T02:40:45.489Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1588
File: website/blog/2025-10-18-auth-tutorials-geodesic-leapp.md:21-21
Timestamp: 2025-12-04T02:40:45.489Z
Learning: In Docusaurus documentation for the cloudposse/atmos repository, page routing uses the `id` field from frontmatter, not the filename. For example, `auth-login.mdx` with `id: login` is accessible at `/cli/commands/auth/login`, not `/cli/commands/auth/auth-login`.

Applied to files:

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

Applied to files:

  • cmd/auth/markdown/atmos_auth_console_usage.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 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/auth/user/user.go
  • cmd/identity_helpers.go
  • cmd/auth/shell.go
  • cmd/auth/validate.go
  • cmd/auth/exec.go
  • cmd/auth/helpers.go
  • cmd/auth/login.go
  • cmd/auth/env.go
  • cmd/auth/completion.go
  • cmd/auth/auth.go
  • cmd/auth/list.go
  • cmd/auth/console.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/auth/user/user.go
  • cmd/auth/shell.go
  • cmd/auth/exec.go
  • cmd/auth/user/helpers.go
  • cmd/auth/login.go
  • cmd/auth/auth.go
  • cmd/auth/console.go
📚 Learning: 2025-09-07T18:07:00.549Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1452
File: cmd/auth_login.go:43-44
Timestamp: 2025-09-07T18:07:00.549Z
Learning: In the atmos project, the identity flag is defined as a persistent flag on the auth root command (cmd/auth.go), making it available to all auth subcommands without needing to be redefined in each individual subcommand.

Applied to files:

  • cmd/auth/user/user.go
  • cmd/identity_helpers.go
  • cmd/auth/shell.go
  • cmd/auth/validate.go
  • cmd/auth/exec.go
  • cmd/root.go
  • cmd/auth/login.go
  • cmd/auth/env.go
  • cmd/auth/completion.go
  • cmd/auth/auth.go
  • cmd/auth/whoami.go
  • cmd/auth/list.go
  • cmd/auth/console.go
  • cmd/auth/logout.go
📚 Learning: 2025-09-25T01:02:48.697Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/manager.go:304-312
Timestamp: 2025-09-25T01:02:48.697Z
Learning: The auth manager in pkg/auth/manager.go should remain cloud-agnostic and not contain AWS-specific logic or references to specific cloud providers. Keep the manager generic and extensible.

Applied to files:

  • cmd/auth/user/user.go
  • cmd/auth/validate.go
  • cmd/auth/exec.go
  • cmd/auth/helpers.go
  • cmd/auth/whoami.go
  • cmd/auth/list.go
  • cmd/auth/console.go
  • cmd/auth/logout.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/auth/user/user.go
  • cmd/identity_helpers.go
  • cmd/auth/shell.go
  • cmd/auth/validate.go
  • cmd/auth/exec.go
  • cmd/root.go
  • cmd/auth/helpers.go
  • cmd/auth/user/helpers.go
  • cmd/auth/login.go
  • cmd/auth/env.go
  • cmd/auth/user/configure.go
  • cmd/auth/completion.go
  • cmd/auth/auth.go
  • cmd/auth/whoami.go
  • cmd/auth/list.go
  • cmd/auth/console.go
  • cmd/auth/logout.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/auth/user/user.go
  • cmd/identity_helpers.go
  • cmd/auth/shell.go
  • cmd/auth/validate.go
  • cmd/auth/exec.go
  • cmd/root.go
  • cmd/auth/helpers.go
  • cmd/auth/user/helpers.go
  • cmd/auth/login.go
  • cmd/auth/env.go
  • cmd/auth/user/configure.go
  • cmd/auth/completion.go
  • cmd/auth/auth.go
  • cmd/auth/whoami.go
  • cmd/auth/list.go
  • cmd/auth/console.go
  • cmd/auth/logout.go
📚 Learning: 2025-12-13T06:07:37.766Z
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.

Applied to files:

  • cmd/auth/markdown/atmos_auth_list_usage.md
  • cmd/auth/markdown/atmos_auth_shell_usage.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 README.md : Update README.md with new commands and features

Applied to files:

  • cmd/auth/markdown/atmos_auth_list_usage.md
  • cmd/auth/markdown/atmos_auth_shell_usage.md
📚 Learning: 2025-12-26T06:31:02.244Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-26T06:31:02.244Z
Learning: Applies to website/docs/cli/commands/**/*.mdx : All new CLI commands MUST have Docusaurus documentation with frontmatter (title, sidebar_label, sidebar_class_name, id, description), Intro component, Screengrab, Usage section, Arguments/Flags in definition lists, and Examples section

Applied to files:

  • cmd/auth/markdown/atmos_auth_list_usage.md
  • cmd/auth/markdown/atmos_auth_shell_usage.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:

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

Applied to files:

  • cmd/identity_helpers.go
📚 Learning: 2025-12-26T06:31:02.244Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-26T06:31:02.244Z
Learning: Applies to **/*.go : Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions, use nil if no atmosConfig param

Applied to files:

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

Applied to files:

  • cmd/identity_helpers.go
📚 Learning: 2025-11-30T04:16:24.155Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1821
File: pkg/merge/deferred.go:34-48
Timestamp: 2025-11-30T04:16:24.155Z
Learning: In the cloudposse/atmos repository, the `defer perf.Track()` guideline applies to functions that perform meaningful work (I/O, computation, external calls), but explicitly excludes trivial accessors/mutators (e.g., simple getters, setters with single integer increments, string joins, or map appends) where the tracking overhead would exceed the actual method cost and provide no actionable performance data. Hot-path methods called in tight loops should especially avoid perf.Track() if they perform only trivial operations.

Applied to files:

  • cmd/identity_helpers.go
  • cmd/auth/user/helpers.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:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/auth/shell.go
  • cmd/auth/markdown/atmos_auth_shell_usage.md
📚 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/auth/shell.go
  • cmd/auth/exec.go
  • cmd/auth/whoami.go
📚 Learning: 2025-01-30T19:30:59.120Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/workflow.go:74-74
Timestamp: 2025-01-30T19:30:59.120Z
Learning: Error handling for `cmd.Usage()` is not required in the Atmos CLI codebase, as confirmed by the maintainer.

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/auth/shell.go
  • cmd/auth/validate.go
  • cmd/auth/exec.go
  • cmd/auth/env.go
📚 Learning: 2025-12-26T06:31:02.244Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-26T06:31:02.244Z
Learning: Applies to cmd/**/*.go : Commands MUST use flags.NewStandardParser() for command-specific flags - NEVER call viper.BindEnv() or viper.BindPFlag() directly

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/auth/validate.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/auth/validate.go
  • cmd/auth/exec.go
  • cmd/root.go
  • cmd/auth/whoami.go
📚 Learning: 2025-12-26T06:31:02.244Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-26T06:31:02.244Z
Learning: Applies to **/*.go : Use viper.BindEnv("ATMOS_VAR", "ATMOS_VAR", "FALLBACK") for environment variables - ATMOS_ prefix required

Applied to files:

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

Applied to files:

  • cmd/auth/validate.go
  • cmd/auth/env.go
📚 Learning: 2025-12-26T06:31:02.244Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-26T06:31:02.244Z
Learning: Applies to internal/exec/**/*.go : New configs support Go templating with FuncMap() from internal/exec/template_funcs.go

Applied to files:

  • cmd/auth/exec.go
📚 Learning: 2025-12-26T06:31:02.244Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-26T06:31:02.244Z
Learning: Applies to **/*.go : Context should be first parameter in functions that accept it

Applied to files:

  • cmd/auth/exec.go
  • cmd/auth/whoami.go
  • cmd/auth/console.go
  • cmd/auth/logout.go
📚 Learning: 2025-12-13T06:10:25.156Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: internal/exec/workflow_utils.go:0-0
Timestamp: 2025-12-13T06:10:25.156Z
Learning: Atmos workflows: In internal/exec/workflow_utils.go ExecuteWorkflow, non-identity steps intentionally use baseWorkflowEnv, which is constructed from the parent environment with PATH modifications for the toolchain. Avoid appending os.Environ() again; prefer documenting this behavior and testing that standard environment variables are preserved.

Applied to files:

  • cmd/auth/exec.go
  • cmd/auth/env.go
📚 Learning: 2025-07-05T20:59:02.914Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1363
File: internal/exec/template_utils.go:18-18
Timestamp: 2025-07-05T20:59:02.914Z
Learning: In the Atmos project, gomplate v4 is imported with a blank import (`_ "github.com/hairyhenderson/gomplate/v4"`) alongside v3 imports to resolve AWS SDK version conflicts. V3 uses older AWS SDK versions that conflict with newer AWS modules used by Atmos. A full migration to v4 requires extensive refactoring due to API changes and should be handled in a separate PR.

Applied to files:

  • cmd/root.go
  • cmd/auth/user/helpers.go
  • cmd/auth/list.go
  • cmd/auth/console.go
  • cmd/auth/logout.go
📚 Learning: 2025-12-26T06:31:02.244Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-26T06:31:02.244Z
Learning: Applies to **/*.go : Use three-group import organization separated by blank lines, sorted alphabetically: Go stdlib, 3rd-party (NOT cloudposse/atmos), Atmos packages - maintain aliases: cfg, log, u, errUtils

Applied to files:

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

Applied to files:

  • cmd/root.go
  • cmd/auth/user/helpers.go
  • cmd/auth/login.go
  • cmd/auth/console.go
📚 Learning: 2025-12-26T06:31:02.244Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-26T06:31:02.244Z
Learning: Use registry pattern for extensibility - all new commands MUST use command registry pattern via CommandProvider interface in cmd/internal/registry.go

Applied to files:

  • cmd/root.go
  • cmd/auth/auth.go
📚 Learning: 2025-09-10T22:38:42.212Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/identities/aws/user.go:141-145
Timestamp: 2025-09-10T22:38:42.212Z
Learning: The user confirmed that the errors package has an error string wrapping format, contradicting the previous learning about ErrWrappingFormat being invalid. The current usage of fmt.Errorf(errUtils.ErrWrappingFormat, errUtils.ErrAuthAwsFileManagerFailed, err) appears to be the correct pattern.

Applied to files:

  • cmd/auth/user/helpers.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 meaningful feedback to users and include progress indicators for long-running operations in CLI commands

Applied to files:

  • cmd/auth/user/helpers.go
📚 Learning: 2025-12-26T06:31:02.244Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-26T06:31:02.244Z
Learning: Applies to cmd/**/*.go : Embed examples from cmd/markdown/*_usage.md using //go:embed and render with utils.PrintfMarkdown()

Applied to files:

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

Applied to files:

  • cmd/auth/user/helpers.go
  • cmd/auth/logout.go
📚 Learning: 2025-11-30T04:16:01.899Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1821
File: pkg/merge/deferred.go:50-59
Timestamp: 2025-11-30T04:16:01.899Z
Learning: In the cloudposse/atmos repository, performance tracking with `defer perf.Track()` should NOT be added to trivial O(1) getter methods that only return field references or check map lengths (e.g., `GetDeferredValues()`, `HasDeferredValues()`). The guideline to add perf tracking to "all public functions" applies to functions that do meaningful work (I/O, computation, external calls), not to trivial accessors where the tracking overhead would exceed the operation time and pollute performance reports.

Applied to files:

  • cmd/auth/user/helpers.go
📚 Learning: 2025-10-22T14:55:44.014Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1695
File: pkg/auth/manager.go:169-171
Timestamp: 2025-10-22T14:55:44.014Z
Learning: Go 1.20+ supports multiple %w verbs in fmt.Errorf, which returns an error implementing Unwrap() []error. This is valid and does not panic. Atmos uses Go 1.24.8 and configures errorlint with errorf-multi: true to validate this pattern.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/auth/env.go
  • cmd/auth/logout.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:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/auth/whoami.go
  • cmd/auth/console.go
📚 Learning: 2025-10-11T19:04:55.909Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/workflow.go:4-4
Timestamp: 2025-10-11T19:04:55.909Z
Learning: In Go, blank importing the embed package (`import _ "embed"`) is the correct and idiomatic way to enable `go:embed` directives. The blank import is required for the compiler to recognize and process `//go:embed` directives. The embed package should not be imported with a named import unless its exported functions are explicitly used, which is rare.

Applied to files:

  • cmd/auth/list.go
📚 Learning: 2025-12-13T06:19:17.739Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: pkg/http/client.go:0-0
Timestamp: 2025-12-13T06:19:17.739Z
Learning: In pkg/http/client.go, GetGitHubTokenFromEnv intentionally reads viper.GetString("github-token") to honor precedence of the persistent --github-token flag over ATMOS_GITHUB_TOKEN and GITHUB_TOKEN. Do not replace this with os.Getenv in future reviews; using Viper here is by design.

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/auth/console.go
🧬 Code graph analysis (9)
cmd/auth/user/user.go (1)
pkg/perf/perf.go (1)
  • Track (121-138)
cmd/identity_helpers.go (2)
cmd/auth/auth.go (1)
  • IdentityFlagSelectValue (19-19)
pkg/perf/perf.go (1)
  • Track (121-138)
cmd/auth/shell.go (5)
pkg/config/config.go (1)
  • InitCliConfig (28-67)
pkg/schema/schema.go (1)
  • ConfigAndStacksInfo (679-775)
internal/exec/shell_utils.go (1)
  • ExecAuthShellCommand (316-374)
cmd/auth/auth.go (3)
  • GetIdentityFromFlags (109-129)
  • IdentityFlagName (17-17)
  • IdentityFlagSelectValue (19-19)
cmd/identity_helpers.go (3)
  • GetIdentityFromFlags (43-69)
  • IdentityFlagName (17-17)
  • IdentityFlagSelectValue (19-19)
cmd/auth/validate.go (5)
pkg/flags/standard_parser.go (2)
  • StandardParser (18-22)
  • NewStandardParser (34-40)
pkg/perf/perf.go (1)
  • Track (121-138)
pkg/flags/options.go (2)
  • WithBoolFlag (63-74)
  • WithEnvVars (221-244)
pkg/flags/parser.go (1)
  • GetBool (141-150)
pkg/utils/markdown_utils.go (1)
  • PrintfMarkdown (80-84)
cmd/auth/exec.go (1)
cmd/auth/auth.go (3)
  • GetIdentityFromFlags (109-129)
  • IdentityFlagName (17-17)
  • IdentityFlagSelectValue (19-19)
cmd/auth/user/configure.go (6)
cmd/auth/user/user.go (1)
  • AuthUserCmd (10-17)
pkg/config/config.go (1)
  • InitCliConfig (28-67)
pkg/schema/schema.go (1)
  • ConfigAndStacksInfo (679-775)
errors/errors.go (3)
  • ErrWrapFormat (12-12)
  • ErrInvalidAuthConfig (534-534)
  • ErrAwsAuth (543-543)
pkg/auth/credentials/store.go (1)
  • NewCredentialStore (42-46)
pkg/auth/types/aws_credentials.go (1)
  • AWSCredentials (16-24)
cmd/auth/completion.go (3)
pkg/config/config.go (1)
  • InitCliConfig (28-67)
pkg/schema/schema.go (1)
  • ConfigAndStacksInfo (679-775)
pkg/logger/log.go (1)
  • Trace (14-16)
cmd/auth/list.go (6)
pkg/flags/standard_parser.go (2)
  • StandardParser (18-22)
  • NewStandardParser (34-40)
pkg/logger/log.go (1)
  • Trace (14-16)
pkg/config/config.go (1)
  • InitCliConfig (28-67)
pkg/schema/schema.go (1)
  • ConfigAndStacksInfo (679-775)
errors/errors.go (1)
  • ErrInvalidAuthConfig (534-534)
cmd/auth/helpers.go (1)
  • CreateAuthManager (29-36)
cmd/auth/console.go (4)
pkg/flags/standard_parser.go (2)
  • StandardParser (18-22)
  • NewStandardParser (34-40)
pkg/auth/types/interfaces.go (2)
  • ConsoleURLOptions (363-380)
  • ConsoleAccessProvider (353-360)
cmd/auth/helpers.go (1)
  • CreateAuthManager (29-36)
cmd/auth/auth.go (2)
  • GetIdentityFromFlags (109-129)
  • IdentityFlagName (17-17)
🪛 GitHub Check: CodeQL
cmd/auth/env.go

[failure] 185-185: Clear-text logging of sensitive information
Sensitive data returned by an access to passwdParts flows to a logging call.


[failure] 204-204: Clear-text logging of sensitive information
Sensitive data returned by an access to passwdParts flows to a logging call.

🪛 LanguageTool
cmd/auth/markdown/atmos_auth_console_usage.md

[typographical] ~1-~1: Consider using an em dash in dialogues and enumerations.
Context: - Open console with default identity ```...

(DASH_RULE)

cmd/auth/markdown/atmos_auth_list_usage.md

[typographical] ~1-~1: Consider using an em dash in dialogues and enumerations.
Context: - List all providers and identities ``` ...

(DASH_RULE)

cmd/auth/markdown/atmos_auth_shell_usage.md

[typographical] ~1-~1: Consider using an em dash in dialogues and enumerations.
Context: - Launch an interactive shell with authen...

(DASH_RULE)

🪛 markdownlint-cli2 (0.18.1)
cmd/auth/markdown/atmos_auth_shell_usage.md

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

(MD040, fenced-code-language)


4-4: Dollar signs used before commands without showing output

(MD014, commands-show-output)


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

(MD040, fenced-code-language)


10-10: Dollar signs used before commands without showing output

(MD014, commands-show-output)


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

(MD040, fenced-code-language)


16-16: Dollar signs used before commands without showing output

(MD014, commands-show-output)


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

(MD040, fenced-code-language)


22-22: Dollar signs used before commands without showing output

(MD014, commands-show-output)


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

(MD040, fenced-code-language)


28-28: Dollar signs used before commands without showing output

(MD014, commands-show-output)


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

(MD040, fenced-code-language)


34-34: Dollar signs used before commands without showing output

(MD014, commands-show-output)

⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 29, 2025
@mergify
Copy link

mergify bot commented Dec 30, 2025

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

@codecov
Copy link

codecov bot commented Dec 31, 2025

Codecov Report

❌ Patch coverage is 25.57298% with 617 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.14%. Comparing base (8dafe30) to head (5d12ef0).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
cmd/auth/user/configure.go 3.40% 85 Missing ⚠️
cmd/auth/env.go 12.35% 75 Missing and 3 partials ⚠️
cmd/auth/shell.go 10.52% 67 Missing and 1 partial ⚠️
cmd/auth/helpers.go 0.00% 56 Missing ⚠️
cmd/auth/console.go 18.18% 52 Missing and 2 partials ⚠️
cmd/auth/login.go 14.00% 42 Missing and 1 partial ⚠️
cmd/auth/completion.go 6.66% 41 Missing and 1 partial ⚠️
cmd/auth/exec.go 12.50% 34 Missing and 1 partial ⚠️
cmd/auth/list.go 24.32% 25 Missing and 3 partials ⚠️
cmd/auth/whoami.go 26.31% 25 Missing and 3 partials ⚠️
... and 9 more

❌ Your patch check has failed because the patch coverage (25.57%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1919      +/-   ##
==========================================
- Coverage   73.78%   72.14%   -1.65%     
==========================================
  Files         659      664       +5     
  Lines       61106    61290     +184     
==========================================
- Hits        45088    44215     -873     
- Misses      12974    14090    +1116     
+ Partials     3044     2985      -59     
Flag Coverage Δ
unittests 72.14% <25.57%> (-1.65%) ⬇️

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

Files with missing lines Coverage Δ
cmd/auth/user/user.go 100.00% <100.00%> (ø)
errors/errors.go 100.00% <ø> (ø)
pkg/flags/preprocess/nooptdefval.go 100.00% <100.00%> (ø)
pkg/flags/preprocess/preprocess.go 100.00% <100.00%> (ø)
pkg/flags/registry.go 54.88% <ø> (-11.26%) ⬇️
internal/exec/helmfile.go 10.99% <0.00%> (ø)
pkg/flags/flag_parser.go 81.74% <81.81%> (-0.16%) ⬇️
cmd/identity_helpers.go 31.11% <70.00%> (ø)
cmd/auth/user/helpers.go 0.00% <0.00%> (ø)
pkg/flags/global_registry.go 95.19% <0.00%> (-4.81%) ⬇️
... and 14 more

... and 14 files with indirect coverage changes

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

♻️ Duplicate comments (2)
cmd/auth/env.go (1)

174-218: LGTM! Intentional credential output is properly annotated.

The CodeQL warnings for lines 192 and 215 are false positives. This command intentionally outputs credentials for shell sourcing (similar to aws configure export-credentials). The code includes proper annotations acknowledging this behavior.

Single-quote escaping is correct, and sorted output ensures consistency.

cmd/auth/shell.go (1)

122-146: Duplicate identity resolution logic.

This mirrors resolveIdentityNameForExec in exec.go. As noted there, consider consolidating into a shared helper.

🧹 Nitpick comments (5)
cmd/auth/exec.go (1)

154-178: Consider extracting shared identity resolution logic.

resolveIdentityNameForExec is nearly identical to resolveIdentityNameForShell in shell.go. Both follow the same flow: check flags → check Viper → handle forceSelect → call GetDefaultIdentity. Consider a shared helper like ResolveIdentityName(cmd, v, authManager) in helpers.go to reduce duplication.

cmd/auth/validate.go (1)

79-84: Potential double error display.

When validation fails, you print the error message via PrintfMarkdown (line 82) and then return the same error (line 83). Depending on how the caller handles this, the user might see the error twice. If the parent command already prints returned errors, consider returning a sentinel or nil after printing.

🔎 One approach
 	if err := validator.ValidateAuthConfig(&atmosConfig.Auth); err != nil {
 		u.PrintfMarkdown("**❌ Authentication configuration validation failed:**\n")
 		u.PrintfMarkdown("%s\n", err.Error())
-		return err
+		return nil // Error already displayed to user
 	}
cmd/auth/helpers.go (1)

122-123: Direct stderr write instead of UI layer.

Per coding guidelines, output should use ui.Write/Writef for stderr messages rather than fmt.Fprintf(os.Stderr, ...). The table rendering could use the UI layer for consistency.

🔎 Suggested approach
-	fmt.Fprintf(os.Stderr, "%s\n\n", t)
+	_ = ui.Writef("%s\n\n", t)
cmd/auth/list.go (1)

361-367: Double error wrapping pattern.

The error format %w: failed to marshal JSON: %w wraps the sentinel error and then adds a string with another %w. This creates a somewhat unusual error chain. Consider using the standard pattern from errors.go.

🔎 Cleaner approach
-		return "", fmt.Errorf("%w: failed to marshal JSON: %w", errUtils.ErrParseFile, err)
+		return "", fmt.Errorf(errUtils.ErrWrapFormat, errUtils.ErrParseFile, fmt.Errorf("failed to marshal JSON: %w", err))

Or simply:

-		return "", fmt.Errorf("%w: failed to marshal JSON: %w", errUtils.ErrParseFile, err)
+		return "", fmt.Errorf("failed to marshal JSON: %w", err)
cmd/auth/whoami.go (1)

193-198: Inconsistent Viper instance usage.

Line 197 uses global viper.GetString(IdentityFlagName) while the rest of the function uses the local v variable. For consistency, use v.GetString(IdentityFlagName).

🔎 Suggested fix
 	// If flag wasn't provided, check Viper for env var fallback.
 	if identityName == "" {
-		identityName = viper.GetString(IdentityFlagName)
+		identityName = v.GetString(IdentityFlagName)
 	}

Note: The function signature needs v *viper.Viper parameter added.

@mergify
Copy link

mergify bot commented Jan 1, 2026

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

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

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
cmd/auth/whoami.go (1)

207-210: Use %w for error wrapping to preserve error chain.

Line 209 uses %v which loses the error type information. Use %w for proper error chain preservation, consistent with the pattern used in loadAuthManager.

🔎 Suggested fix
 	defaultIdentity, err := authManager.GetDefaultIdentity(forceSelect)
 	if err != nil {
-		return "", fmt.Errorf("%w: no default identity configured and no identity specified: %v", errUtils.ErrInvalidAuthConfig, err)
+		return "", fmt.Errorf("%w: no default identity configured and no identity specified: %w", errUtils.ErrInvalidAuthConfig, err)
 	}
🧹 Nitpick comments (3)
tests/describe_test.go (1)

32-47: Consider using TestKit to avoid RootCmd state pollution.

Both tests modify RootCmd state via SetArgs and execute through RootCmd.Execute(). According to project learnings, tests that modify RootCmd state should use cmd.NewTestKit(t) to ensure proper cleanup between tests.

🔎 Suggested pattern with TestKit
 func TestDescribeComponentJSON(t *testing.T) {
+	tk := cmd.NewTestKit(t)
 	skipIfNoTTY(t)
 
 	// Set up the environment variables.
 	t.Chdir("./fixtures/scenarios/atmos-providers-section")
 
 	t.Setenv("ATMOS_PAGER", "more")
 
 	// Use SetArgs for Cobra command testing.
-	cmd.RootCmd.SetArgs([]string{"describe", "component", "component-1", "--stack", "nonprod", "--format", "json"})
+	tk.RootCmd.SetArgs([]string{"describe", "component", "component-1", "--stack", "nonprod", "--format", "json"})
 
-	err := cmd.Execute()
+	err := tk.RootCmd.Execute()
 	if err != nil {
 		t.Fatalf("Failed to execute command: %v", err)
 	}
 }

Apply the same pattern to TestDescribeComponentYAML.

Based on learnings, as cmd.NewTestKit(t) handles RootCmd state cleanup automatically.

Also applies to: 49-64

cmd/auth/shell.go (2)

77-80: Consider passing ConfigInfo to ValidateAtmosConfig.

ValidateAtmosConfig() is called before BuildConfigAndStacksInfo(), so global flags (--base-path, --config, etc.) won't be respected during validation. The actual config loading at line 96 is correct, but validation may check the wrong path.

Consider reordering or passing config info:

Suggested fix
+	// Parse global flags and build ConfigAndStacksInfo to honor --base-path, --config, --config-path, --profile.
+	v := viper.GetViper()
+	if err := shellParser.BindFlagsToViper(cmd, v); err != nil {
+		return err
+	}
+	configAndStacksInfo := BuildConfigAndStacksInfo(cmd, v)
+
 	handleHelpRequest(cmd, args)
-	if err := internal.ValidateAtmosConfig(); err != nil {
+	if err := internal.ValidateAtmosConfig(internal.WithConfigInfo(configAndStacksInfo)); err != nil {
 		return err
 	}
-
-	// Bind parsed flags to Viper for precedence.
-	v := viper.GetViper()
-	if err := shellParser.BindFlagsToViper(cmd, v); err != nil {
-		return err
-	}

174-177: Use sentinel error for shell environment preparation failure.

Per coding guidelines, errors should wrap static sentinels from errors/errors.go. This raw string should use a defined sentinel.

Suggested fix

Add sentinel to errors/errors.go if not present, then:

 	envList, err := authManager.PrepareShellEnvironment(ctx, identityName, baseEnv)
 	if err != nil {
-		return nil, "", fmt.Errorf("failed to prepare shell environment: %w", err)
+		return nil, "", fmt.Errorf(errUtils.ErrWrapFormat, errUtils.ErrShellEnvironmentPreparationFailed, err)
 	}
📜 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 5d12ef0 and f25fe94.

📒 Files selected for processing (11)
  • cmd/auth/shell.go
  • cmd/auth/whoami.go
  • cmd/root.go
  • errors/errors.go
  • internal/exec/helmfile.go
  • pkg/flags/global_registry.go
  • pkg/flags/global_registry_test.go
  • tests/cli_describe_component_test.go
  • tests/describe_test.go
  • tests/snapshots/TestCLICommands_atmos_auth_env_--help.stdout.golden
  • tests/snapshots/TestCLICommands_atmos_auth_exec_--help.stdout.golden
✅ Files skipped from review due to trivial changes (1)
  • tests/snapshots/TestCLICommands_atmos_auth_exec_--help.stdout.golden
🚧 Files skipped from review as they are similar to previous changes (6)
  • pkg/flags/global_registry.go
  • errors/errors.go
  • internal/exec/helmfile.go
  • tests/cli_describe_component_test.go
  • tests/snapshots/TestCLICommands_atmos_auth_env_--help.stdout.golden
  • pkg/flags/global_registry_test.go
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

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

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

**/*.go: 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, and 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
Use flags.NewStandardParser() for command-specific flags; NEVER call viper.BindEnv() or viper.BindPFlag() directly (enforced by Forbidigo)
All errors MUST be wrapped using static errors defined in errors/errors.go; use errors.Join for combining multiple errors, fmt.Errorf with %w for adding string context, error builder for complex errors, and errors.Is() for error checking. Never use dynamic errors directly
Define interfaces for all major funct...

Files:

  • tests/describe_test.go
  • cmd/root.go
  • cmd/auth/whoami.go
  • cmd/auth/shell.go
**/*_test.go

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

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

**/*_test.go: Use cmd.NewTestKit(t) for cmd tests to auto-clean RootCmd state (flags, args)
Test behavior, not implementation; never test stub functions; avoid tautological tests; use errors.Is() for error checking; remove always-skipped tests
Prefer unit tests with mocks over integration tests; use interfaces and dependency injection for testability; use table-driven tests for comprehensive coverage; target >80% coverage; skip tests gracefully with helpers from tests/test_preconditions.go
Never manually edit golden snapshot files under tests/test-cases/ or tests/testdata/; always use -regenerate-snapshots flag. Never use pipe redirection when running tests as it breaks TTY detection

Files:

  • tests/describe_test.go
cmd/**/*.go

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

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

cmd/**/*.go: Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions, except trivial getters/setters, command constructors, simple factory functions, and functions that only delegate to another tracked function
Commands MUST use the command registry pattern via CommandProvider interface; see docs/prd/command-registry-pattern.md and cmd/internal/registry.go
Embed examples from cmd/markdown/*_usage.md using //go:embed and render with utils.PrintfMarkdown()

Files:

  • cmd/root.go
  • cmd/auth/whoami.go
  • cmd/auth/shell.go
🧠 Learnings (67)
📓 Common learnings
Learnt from: osterman
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-11-10T03:03:31.505Z
Learning: In the Atmos codebase, commands using the `StandardParser` flag pattern (from pkg/flags) do NOT need explicit `viper.BindPFlag()` calls in their code. The StandardParser encapsulates flag binding internally: flags are registered via `parser.RegisterFlags(cmd)` in init(), and bound via `parser.BindFlagsToViper(cmd, v)` in RunE, which internally calls viper.BindPFlag for each flag. This pattern is used throughout Atmos (e.g., cmd/toolchain/get.go, cmd/toolchain/info.go, cmd/toolchain/install.go, cmd/toolchain/path.go). Do not flag missing viper.BindPFlag calls when StandardParser is used.
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1452
File: cmd/auth_login.go:43-44
Timestamp: 2025-09-07T18:07:00.549Z
Learning: In the atmos project, the identity flag is defined as a persistent flag on the auth root command (cmd/auth.go), making it available to all auth subcommands without needing to be redefined in each individual subcommand.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.
Learnt from: osterman
Repo: cloudposse/atmos PR: 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.
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.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: When adding new CLI command: (1) Create `cmd/[command]/` with CommandProvider interface, (2) Add blank import to `cmd/root.go`, (3) Implement in `internal/exec/mycommand.go`, (4) Add tests and Docusaurus docs in `website/docs/cli/commands/`, (5) Build website: `cd website && npm run build`. See `docs/developing-atmos-commands.md` and `docs/prd/command-registry-pattern.md`
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: Applies to cmd/**/*.go : Commands MUST use the command registry pattern via `CommandProvider` interface; see `docs/prd/command-registry-pattern.md` and `cmd/internal/registry.go`
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: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under `cmd/` directory
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Use Viper for managing configuration, environment variables, and flags in CLI commands
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Learnt from: 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: 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.
📚 Learning: 2026-01-01T18:25:25.942Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: Applies to **/*_test.go : Test behavior, not implementation; never test stub functions; avoid tautological tests; use `errors.Is()` for error checking; remove always-skipped tests

Applied to files:

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

Applied to files:

  • tests/describe_test.go
📚 Learning: 2026-01-01T18:25:25.942Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: Applies to **/*_test.go : Never manually edit golden snapshot files under `tests/test-cases/` or `tests/testdata/`; always use `-regenerate-snapshots` flag. Never use pipe redirection when running tests as it breaks TTY detection

Applied to files:

  • tests/describe_test.go
📚 Learning: 2024-11-10T18:37:10.032Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 768
File: internal/exec/vendor_component_utils.go:354-360
Timestamp: 2024-11-10T18:37:10.032Z
Learning: In the vendoring process, a TTY can exist without being interactive. If the process does not prompt the user, we should not require interactive mode to display the TUI. The `CheckTTYSupport` function should check TTY support on stdout rather than stdin.

Applied to files:

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

Applied to files:

  • tests/describe_test.go
📚 Learning: 2026-01-01T18:25:25.942Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: Applies to **/*_test.go : Prefer unit tests with mocks over integration tests; use interfaces and dependency injection for testability; use table-driven tests for comprehensive coverage; target >80% coverage; skip tests gracefully with helpers from `tests/test_preconditions.go`

Applied to files:

  • tests/describe_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Use table-driven tests for testing multiple scenarios in Go

Applied to files:

  • tests/describe_test.go
📚 Learning: 2026-01-01T18:25:25.942Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: Applies to **/*_test.go : Use `cmd.NewTestKit(t)` for cmd tests to auto-clean RootCmd state (flags, args)

Applied to files:

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

Applied to files:

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

Applied to files:

  • tests/describe_test.go
📚 Learning: 2024-11-10T19:28:17.365Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 768
File: internal/exec/vendor_utils.go:0-0
Timestamp: 2024-11-10T19:28:17.365Z
Learning: When TTY is not supported, log the downgrade message at the Warn level using `u.LogWarning(cliConfig, ...)` instead of `fmt.Println`.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • tests/describe_test.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:

  • tests/describe_test.go
📚 Learning: 2025-08-16T23:32:40.412Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:455-456
Timestamp: 2025-08-16T23:32:40.412Z
Learning: In the cloudposse/atmos Go codebase, `InitCliConfig` returns a `schema.AtmosConfiguration` value (not a pointer), while `ExecuteDescribeDependents` expects a `*schema.AtmosConfiguration` pointer parameter. Therefore, when passing the result of `InitCliConfig` to `ExecuteDescribeDependents`, use `&atmosConfig` to pass the address of the value.

Applied to files:

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

Applied to files:

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

Applied to files:

  • tests/describe_test.go
  • cmd/auth/whoami.go
  • cmd/auth/shell.go
📚 Learning: 2026-01-01T18:25:25.942Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: Stack pipeline: Load atmos.yaml → process imports/inheritance → apply overrides → render templates → generate config. Templates use Go templates + Gomplate with `atmos.Component()`, `!terraform.state`, `!terraform.output`, store integration

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/root.go
  • cmd/auth/whoami.go
  • cmd/auth/shell.go
📚 Learning: 2026-01-01T18:25:25.942Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: Applies to **/*.go : Organize imports in three groups separated by blank lines, sorted alphabetically: (1) Go stdlib, (2) 3rd-party (NOT cloudposse/atmos), (3) Atmos packages. Maintain aliases: `cfg`, `log`, `u`, `errUtils`

Applied to files:

  • cmd/root.go
📚 Learning: 2026-01-01T18:25:25.942Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: When adding new CLI command: (1) Create `cmd/[command]/` with CommandProvider interface, (2) Add blank import to `cmd/root.go`, (3) Implement in `internal/exec/mycommand.go`, (4) Add tests and Docusaurus docs in `website/docs/cli/commands/`, (5) Build website: `cd website && npm run build`. See `docs/developing-atmos-commands.md` and `docs/prd/command-registry-pattern.md`

Applied to files:

  • cmd/root.go
  • cmd/auth/shell.go
📚 Learning: 2026-01-01T18:25:25.942Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: Applies to cmd/**/*.go : Add `defer perf.Track(atmosConfig, "pkg.FuncName")()` + blank line to all public functions, except trivial getters/setters, command constructors, simple factory functions, and functions that only delegate to another tracked function

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/root.go
  • cmd/auth/shell.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:

  • cmd/root.go
  • cmd/auth/whoami.go
  • cmd/auth/shell.go
📚 Learning: 2026-01-01T18:25:25.942Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: Configuration loading precedence: CLI flags → ENV vars → config files → defaults (use Viper). Environment variables require ATMOS_ prefix via `viper.BindEnv("ATMOS_VAR", ...)`

Applied to files:

  • cmd/root.go
  • cmd/auth/whoami.go
📚 Learning: 2025-07-05T20:59:02.914Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1363
File: internal/exec/template_utils.go:18-18
Timestamp: 2025-07-05T20:59:02.914Z
Learning: In the Atmos project, gomplate v4 is imported with a blank import (`_ "github.com/hairyhenderson/gomplate/v4"`) alongside v3 imports to resolve AWS SDK version conflicts. V3 uses older AWS SDK versions that conflict with newer AWS modules used by Atmos. A full migration to v4 requires extensive refactoring due to API changes and should be handled in a separate PR.

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/root.go
📚 Learning: 2026-01-01T18:25:25.942Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: Applies to pkg/**/*.go : Add `defer perf.Track(atmosConfig, "pkg.FuncName")()` + blank line to all public functions, except trivial getters/setters, command constructors, simple factory functions, and functions that only delegate to another tracked function. Use `nil` if no atmosConfig param

Applied to files:

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

Applied to files:

  • cmd/root.go
  • cmd/auth/whoami.go
  • cmd/auth/shell.go
📚 Learning: 2026-01-01T18:25:25.942Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: Applies to pkg/**/*.go : Avoid adding new functions to `pkg/utils/`; create purpose-built packages for new functionality (e.g., `pkg/store/`, `pkg/git/`, `pkg/pro/`, `pkg/filesystem/`)

Applied to files:

  • cmd/root.go
📚 Learning: 2026-01-01T18:25:25.942Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T18:25:25.942Z
Learning: Applies to cmd/**/*.go : Commands MUST use the command registry pattern via `CommandProvider` interface; see `docs/prd/command-registry-pattern.md` and `cmd/internal/registry.go`

Applied to files:

  • cmd/root.go
  • cmd/auth/whoami.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/root.go
  • cmd/auth/whoami.go
  • cmd/auth/shell.go
📚 Learning: 2025-01-30T19:30:59.120Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/workflow.go:74-74
Timestamp: 2025-01-30T19:30:59.120Z
Learning: Error handling for `cmd.Usage()` is not required in the Atmos CLI codebase, as confirmed by the maintainer.

Applied to files:

  • cmd/root.go
  • cmd/auth/shell.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/root.go
  • cmd/auth/shell.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/root.go
  • cmd/auth/whoami.go
  • cmd/auth/shell.go
📚 Learning: 2025-02-18T13:18:53.146Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-18T13:18:53.146Z
Learning: Error checking is not required for cobra.Command.RegisterFlagCompletionFunc calls as these are static configurations done at init time.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/auth/whoami.go
📚 Learning: 2025-10-22T14:55:44.014Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1695
File: pkg/auth/manager.go:169-171
Timestamp: 2025-10-22T14:55:44.014Z
Learning: Go 1.20+ supports multiple %w verbs in fmt.Errorf, which returns an error implementing Unwrap() []error. This is valid and does not panic. Atmos uses Go 1.24.8 and configures errorlint with errorf-multi: true to validate this pattern.

Applied to files:

  • cmd/auth/whoami.go
📚 Learning: 2025-09-10T22:38:42.212Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/identities/aws/user.go:141-145
Timestamp: 2025-09-10T22:38:42.212Z
Learning: ErrWrappingFormat is correctly defined as "%w: %w" in the errors package and is used throughout the codebase to wrap two error types together. The usage fmt.Errorf(errUtils.ErrWrappingFormat, errUtils.ErrAuthAwsFileManagerFailed, err) is the correct pattern when both arguments are error types.

Applied to files:

  • cmd/auth/whoami.go
📚 Learning: 2025-09-10T22:38:42.212Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/identities/aws/user.go:141-145
Timestamp: 2025-09-10T22:38:42.212Z
Learning: The user confirmed that the errors package has an error string wrapping format, contradicting the previous learning about ErrWrappingFormat being invalid. The current usage of fmt.Errorf(errUtils.ErrWrappingFormat, errUtils.ErrAuthAwsFileManagerFailed, err) appears to be the correct pattern.

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/auth/whoami.go
📚 Learning: 2025-12-13T06:10:13.688Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: errors/errors.go:184-203
Timestamp: 2025-12-13T06:10:13.688Z
Learning: cloudposse/atmos: For toolchain work, duplicate/unused error sentinels in errors/errors.go should be cleaned up in a separate refactor PR and not block feature PRs; canonical toolchain sentinels live under toolchain/registry with re-exports in toolchain/errors.go.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/auth/whoami.go
📚 Learning: 2024-12-11T18:46:02.483Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/terraform.go:39-39
Timestamp: 2024-12-11T18:46:02.483Z
Learning: `cliConfig` is initialized in `cmd/root.go` and can be used across the `cmd` package.

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/auth/shell.go
📚 Learning: 2025-12-13T06:10:25.156Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: internal/exec/workflow_utils.go:0-0
Timestamp: 2025-12-13T06:10:25.156Z
Learning: Atmos workflows: In internal/exec/workflow_utils.go ExecuteWorkflow, non-identity steps intentionally use baseWorkflowEnv, which is constructed from the parent environment with PATH modifications for the toolchain. Avoid appending os.Environ() again; prefer documenting this behavior and testing that standard environment variables are preserved.

Applied to files:

  • cmd/auth/shell.go
📚 Learning: 2025-04-23T15:02:50.246Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1202
File: pkg/utils/yaml_func_exec.go:104-104
Timestamp: 2025-04-23T15:02:50.246Z
Learning: In the Atmos codebase, direct calls to `os.Getenv` should be avoided. Instead, use `viper.BindEnv` for environment variable access. This provides a consistent approach to configuration management across the codebase.

Applied to files:

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

Applied to files:

  • cmd/auth/shell.go
📚 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/auth/shell.go
📚 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:

  • cmd/auth/shell.go
🧬 Code graph analysis (2)
tests/describe_test.go (1)
internal/tui/templates/term/term_writer.go (1)
  • IsTTYSupportForStdout (121-123)
cmd/auth/shell.go (11)
pkg/flags/options.go (2)
  • WithStringFlag (49-60)
  • WithEnvVars (221-244)
cmd/internal/validation.go (1)
  • ValidateAtmosConfig (44-73)
pkg/flags/global_registry.go (1)
  • BuildConfigAndStacksInfo (85-95)
cmd/auth/helpers.go (2)
  • BuildConfigAndStacksInfo (32-36)
  • CreateAuthManager (40-47)
pkg/config/config.go (1)
  • InitCliConfig (28-67)
pkg/flags/parser.go (1)
  • GetString (117-126)
internal/exec/shell_utils.go (1)
  • ExecAuthShellCommand (316-374)
cmd/identity_helpers.go (1)
  • GetIdentityFromFlags (36-62)
cmd/auth/auth.go (3)
  • GetIdentityFromFlags (109-129)
  • IdentityFlagName (17-17)
  • IdentityFlagSelectValue (19-19)
pkg/schema/schema.go (1)
  • AtmosConfiguration (54-100)
pkg/env/global.go (1)
  • MergeGlobalEnv (16-35)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
🔇 Additional comments (15)
tests/describe_test.go (1)

12-30: Nice cross-platform TTY detection!

The helper properly addresses the past review comments about resource leaks. The file descriptor is now correctly closed immediately after opening (line 27), and the cross-platform logic using runtime.GOOS is clean.

cmd/root.go (5)

35-35: LGTM on import additions.

The preprocess package import and blank import for auth command registration follow the command registry pattern correctly. Based on learnings, this is the expected wiring for auto-registering commands via side-effect imports.

Also applies to: 54-54


1368-1392: Well-structured preprocessing orchestration.

The two-step approach is sound: rewriting NoOptDefVal flags before separating compatibility flags ensures proper handling across command types. The early return and conditional SetArgs logic avoids redundant work.


1394-1405: Simple and correct slice comparison.

Works as expected. Go 1.21+ has slices.Equal but this inline helper is fine for the single call site.


1407-1449: Good refactor to return status.

Returning the bool allows preprocessArgs to know whether SetArgs was already called, avoiding redundant calls. The separation logic for Atmos vs pass-through flags remains intact.


1451-1477: Solid NoOptDefVal handling.

The pipeline approach is clean and extensible. Converting registry flags to FlagInfo interface for the preprocessor is done correctly. This properly addresses Cobra's NoOptDefVal behavior for flags like --identity.

cmd/auth/whoami.go (6)

46-73: Clean init following StandardParser pattern.

The flag registration, Viper binding, and completion setup are well-organized. Using panic for Viper binding errors in init() is acceptable since these are static configuration issues. The log.Trace on completion registration failure is appropriate for non-critical errors.


75-114: LGTM on command execution flow.

The flag binding, auth manager loading, identity resolution, and output handling are properly structured. Using v.GetString(OutputFlagName) respects the flag/env/config precedence.


171-186: Proper config loading and error wrapping.

Using BuildConfigAndStacksInfo(cmd, v) correctly honors global flags like --base-path, --config, --config-path, and --profile before calling InitCliConfig. The %w verb is now used correctly for error chain preservation. Based on learnings, this is the correct pattern.


116-151: Validation logic is sound.

The credential validation correctly checks for the validator interface, falls back to expiration checking, and populates whoami info on success. Good defensive nil check on credentials.


214-229: Output functions are well-structured.

JSON output properly redacts credentials and home directory. Human output uses consistent theming and provides helpful tips when credentials are invalid.

Also applies to: 231-254


344-360: Sanitization covers expected sensitive patterns.

The sensitive keyword list covers common secret patterns. The home directory redaction protects user paths from leaking in output.

cmd/auth/shell.go (3)

124-148: LGTM!

Identity resolution logic properly handles the NoOptDefVal quirk, Viper fallback, and interactive selection. Error wrapping uses appropriate sentinel.


182-191: LGTM!

Environment variable parsing correctly handles values containing = by splitting only on the first occurrence.


195-208: LGTM!

Correctly uses Cobra's ArgsLenAtDash() to extract arguments after the -- separator with proper bounds checking.

@mergify
Copy link

mergify bot commented Jan 2, 2026

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

@mergify mergify bot added conflict This PR has conflicts and removed conflict This PR has conflicts labels Jan 2, 2026
osterman and others added 9 commits January 4, 2026 00:10
* Simplify Nerd Fonts installation instructions

Removed Homebrew tap and search commands from installation instructions. Cask-fonts has been deprecated.

* Fix markdown code fence formatting

The previous commit accidentally removed the opening code fence when deleting
the deprecated Homebrew tap commands.

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

Co-Authored-By: Claude Opus 4.5 <[email protected]>

---------

Co-authored-by: Matt Topper <[email protected]>
Co-authored-by: Claude Opus 4.5 <[email protected]>
Co-authored-by: Andriy Knysh <[email protected]>
- Fix Comment #3: Parse global flags before InitCliConfig in all auth
  commands by adding BuildConfigAndStacksInfo helper to pkg/flags and
  cmd/auth/helpers.go

- Fix Comment #4: Add guard for empty selectable array in configure.go
  to prevent index out of bounds when no AWS user identities found

- Fix Comment #5: Remove duplicate IdentityFlagName constants by using
  cfg.IdentityFlagName from pkg/config/const.go as canonical source

- Remove unused schema imports from login.go, exec.go, shell.go
- Remove unnecessary nolint:gosec directives from env.go

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

Co-Authored-By: Claude Opus 4.5 <[email protected]>
The identity flag uses Cobra's NoOptDefVal feature which only works with
equals syntax (--identity=value), not space-separated syntax (--identity value).
This caused explicit identity values to be ignored, falling back to interactive
selection which fails without a TTY.

Fix by adding NoOptDefVal preprocessing in preprocessCompatibilityFlags() to
rewrite --identity value → --identity=value before Cobra parses. This ensures
explicit identity values work correctly in all environments (CI, piped output,
redirected stdin).

Fixes:
- TestInteractiveIdentitySelection/explicit_identity_value_should_work_even_with_piped_output
- TestExplicitIdentityAlwaysWorks/with_CI=true

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

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Document recommended usage patterns for the --identity flag:
- Use equals syntax (--identity=admin) for clarity
- Place flag before -- separator and positional arguments
- Both auth and terraform command docs updated

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

Co-Authored-By: Claude Opus 4.5 <[email protected]>
1. Remove redundant constant aliases in cmd/identity_helpers.go
   - Use cfg.IdentityFlagName and cfg.IdentityFlagSelectValue directly
   - Eliminates duplicate definitions (CodeRabbit feedback)

2. Add CodeQL suppression comments in cmd/auth/env.go
   - Document intentional credential output for shell sourcing
   - Add codeql[go/clear-text-logging] annotations
   - Similar to aws configure export-credentials behavior

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

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Document the --identity flag in the Command-Specific Flags section:
- Available in auth, terraform, and describe commands
- Supports multiple modes: explicit value, interactive selector, disabled
- Add ATMOS_IDENTITY environment variable reference
- Include flag placement best practice tip (equals syntax recommended)

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

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Separate NoOptDefVal preprocessing and compatibility flag translation into
sibling operations orchestrated by a new preprocessArgs() function.

Architecture:
- preprocessArgs() orchestrates all argument preprocessing
- preprocessNoOptDefValFlags() rewrites --flag value → --flag=value for NoOptDefVal flags
- preprocessCompatibilityFlags() separates Atmos flags from pass-through flags

Key fixes:
- Call SetArgs when NoOptDefVal changes args but no compat flags exist
- This ensures --identity value works correctly for auth commands

New pkg/flags/preprocess/ package:
- Pipeline interface for extensible preprocessing
- NoOptDefValPreprocessor with fixed hasSeparatedValue() using strings.Contains
- FlagInfo interface to avoid circular imports

Tests:
- All auth tests pass (29 tests)
- All preprocess package tests pass
- Pager tests skip gracefully when TTY unavailable

Also fixes pre-existing lint errors in:
- errors/errors.go: Add ErrComponentPathNotFound sentinel
- internal/exec/helmfile.go: Use sentinel errors instead of dynamic errors
- internal/exec/stack_processor_merge.go: Use %w instead of %v for errors
- pkg/downloader/file_downloader.go: Use %w instead of %v for errors
- internal/exec/path_utils_test.go: Use constants for paths with separators

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

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- cmd/auth/shell.go: Use envpkg.MergeGlobalEnv() for consistency with exec.go
  (addresses CodeRabbit comment #3 about env merging inconsistency)

- cmd/auth/whoami.go: Use %w for error wrapping to preserve error chain
  (addresses CodeRabbit comment #4 about error wrapping)

- tests/cli_describe_component_test.go: Use cross-platform TTY detection
  with term.IsTTYSupportForStdout() and close file handle properly
  (addresses CodeRabbit comments #5, #6)

- tests/describe_test.go: Add skipIfNoTTY helper with cross-platform
  TTY detection and proper file handle cleanup
  (addresses CodeRabbit comments #7, #8)

Note: Comments #1 and #2 (codeql clear-text logging) are false positives -
the atmos auth env command intentionally outputs credentials for shell
sourcing, similar to `aws configure export-credentials`. Suppression
comments are already in place.

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

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Add 15 new test files covering pure functions and mock-based tests:
- helpers_test.go: formatDuration, displayAuthSuccess, BuildConfigAndStacksInfo
- whoami_test.go: redactHomeDir, sanitizeEnvMap, buildWhoamiTableRows, validateCredentials
- list_test.go: parseCommaSeparatedNames, filter functions, render functions
- env_test.go: outputEnvAsExport, outputEnvAsDotenv
- login_test.go: authenticateIdentity with MockAuthManager
- shell_test.go: getSeparatedArgs, viper fallback tests
- exec_test.go: getSeparatedArgsForExec, executeCommandWithEnv
- console_test.go: resolveIdentityName, retrieveCredentials, resolveConsoleDuration
- auth_test.go: AuthCommandProvider, GetIdentityFromFlags
- completion_test.go: completion functions
- validate_test.go: command structure
- identity_resolution_test.go: shared identity resolution test helper
- user/user_test.go: AuthUserCmd structure
- user/configure_test.go: command structure
- user/helpers_test.go: selectAWSUserIdentities, extractAWSUserInfo

Coverage improved from ~25.57% to ~36.2% for cmd/auth package.

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

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-release Do not create a new release (wait for additional code changes) size/xl Extra large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants