Skip to content

feat: Add default value support for custom command flags#1848

Merged
aknysh merged 5 commits intomainfrom
feature/dev-3810-custom-commands-boolean-flags-support
Dec 8, 2025
Merged

feat: Add default value support for custom command flags#1848
aknysh merged 5 commits intomainfrom
feature/dev-3810-custom-commands-boolean-flags-support

Conversation

@osterman
Copy link
Copy Markdown
Member

@osterman osterman commented Dec 8, 2025

what

  • Add default field to CommandFlag schema to support default values for both boolean and string flags
  • Boolean flags can now default to true (previously always defaulted to false)
  • Update flag registration in Cobra to use configured defaults
  • Add comprehensive documentation with usage patterns for boolean flags in bash and Go templates

why

Enable custom commands to have special behavior triggers without requiring unnecessary flag values. Users can define type: bool flags with default: true to handle cold start edge cases more cleanly.

references

Closes #1847

Summary by CodeRabbit

  • New Features
    • Custom commands now support configurable default values for boolean and string flags, allowing defaults to be preserved during flag registration
    • Boolean flags can be set to default true or false; string flags can have explicit default values
    • Added comprehensive documentation, blog posts, and usage examples for boolean flag patterns in templates and conditional execution

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

Add `default` field to custom command flags to support default values for both boolean and string flags. Boolean flags can now default to `true`, enabling special behavior triggers without requiring unnecessary flag values.

- Add `Default` field to `CommandFlag` schema
- Update flag registration to use configured default values
- Add comprehensive tests for boolean and string flag defaults
- Document boolean flag usage patterns in bash and Go templates
@osterman osterman requested a review from a team as a code owner December 8, 2025 15:37
@github-actions github-actions bot added the size/m Medium size PR label Dec 8, 2025
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 8, 2025

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 8, 2025

📝 Walkthrough

Walkthrough

Added support for configurable default values in custom command flags (boolean and string types) through schema updates, flag processing logic refinements, integration tests validating the feature, and comprehensive documentation with usage examples.

Changes

Cohort / File(s) Summary
Flag Default Value Support
cmd/cmd_utils.go, pkg/schema/command.go
Added Default field to CommandFlag struct and updated flag registration logic to respect configured defaults for both boolean and string flags instead of hardcoded values
Integration Tests
cmd/custom_command_integration_test.go
Added three test functions: TestCustomCommandIntegration_BooleanFlagDefaults, TestCustomCommandIntegration_BooleanFlagTemplatePatterns, and TestCustomCommandIntegration_StringFlagDefaults to validate flag registration and default value behavior
Documentation & Snapshots
website/docs/cli/configuration/commands.mdx, website/blog/2025-12-08-custom-command-boolean-flags.mdx, tests/snapshots/TestCLICommands_atmos_describe_config_imports.stdout.golden
Added new Boolean Flags documentation section with configuration examples and usage patterns, published blog post documenting the feature, and updated golden snapshot with default: null for stack flag definitions

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • cmd/cmd_utils.go: Review the default value retrieval logic for correctness—ensure type assertions and fallback behavior work as intended for both boolean and string flags
  • cmd/custom_command_integration_test.go: Verify test coverage aligns with expected default behaviors and template pattern execution
  • Schema field addition: Confirm Default field tagging (yaml/json/mapstructure) is correct

Possibly related PRs

Suggested reviewers

  • aknysh
  • kevcube

Pre-merge checks and finishing touches

✅ Passed checks (5 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 change: adding default value support for custom command flags, which aligns with the core objective of the PR.
Linked Issues check ✅ Passed All coding objectives from issue #1847 are met: boolean flag type support added [cmd/cmd_utils.go], default field implementation for both flag types [pkg/schema/command.go], Cobra flag registration respecting defaults, and comprehensive tests validating the functionality.
Out of Scope Changes check ✅ Passed All changes are in scope. Code changes implement default field support; test files validate the feature; documentation explains usage; snapshot file reflects schema updates; blog post documents the feature for users.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/dev-3810-custom-commands-boolean-flags-support

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.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 8, 2025

📝 Walkthrough

Walkthrough

This PR adds support for boolean flags with configurable default values in custom commands. Changes include a new Default field in the CommandFlag schema, updated flag processing logic in cmd_utils.go to respect defaults for both boolean and string flags, integration tests validating the behavior, and documentation explaining the feature with usage examples.

Changes

Cohort / File(s) Summary
Core Logic
pkg/schema/command.go
Added Default field of type any to CommandFlag struct to support default values for flags.
Flag Processing
cmd/cmd_utils.go
Updated processCustomCommands to respect flag.Default values for boolean and string flags instead of always defaulting to false and "" respectively.
Integration Tests
cmd/custom_command_integration_test.go
Added TestCustomCommandIntegration_BooleanFlagDefaults and TestCustomCommandIntegration_StringFlagDefaults to verify flag defaults are correctly registered and applied (note: tests appear duplicated in the diff).
Documentation
website/docs/cli/configuration/commands.mdx, website/blog/2025-12-08-custom-command-boolean-flags.mdx
Added "Boolean Flags" and "Flag Defaults" sections documenting syntax, usage examples, Go template patterns, and behavior for boolean and string flags with defaults.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • Test duplication: Both test functions appear twice in the diff—verify whether this is intentional or a merge artifact.
  • Default field type: The Default field uses type any—confirm type safety is handled correctly in both schema validation and flag processing logic.
  • Boolean flag parsing: Ensure the boolean parsing in cmd_utils.go correctly handles various inputs (true/false strings, empty defaults, etc.).

Possibly related PRs

Suggested reviewers

  • aknysh
  • kevcube
  • joe-niland

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding default value support for custom command flags, which is the primary objective of this PR.
Linked Issues check ✅ Passed The PR implementation meets all coding requirements from #1847: adds Default field to CommandFlag schema, respects defaults in processCustomCommands, supports boolean and string flag defaults, and updates flag registration.
Out of Scope Changes check ✅ Passed All changes are in scope: schema changes (Default field), command processing logic updates, integration tests for defaults, and documentation for the new feature. No unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/dev-3810-custom-commands-boolean-flags-support

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
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
cmd/cmd_utils.go (2)

111-123: Consider adding a warning for type assertion failures.

The boolean flag default handling is safe with proper nil checks and type assertions. However, if a user configures a non-boolean default (e.g., default: "true"), it silently falls back to false without warning the user of the misconfiguration.

Consider adding a log warning when type assertion fails:

 if flag.Type == "bool" {
   defaultVal := false
   if flag.Default != nil {
     if boolVal, ok := flag.Default.(bool); ok {
       defaultVal = boolVal
+    } else {
+      log.Warn("Invalid default value for boolean flag, using false", "flag", flag.Name, "default", flag.Default)
     }
   }

This helps users catch configuration mistakes early.


123-135: Consider adding a warning for type assertion failures.

The string flag default handling follows the same safe pattern as boolean flags. Similar to the boolean case, if a user configures a non-string default (e.g., default: 123), it silently falls back to "" without warning.

Consider adding a log warning for consistency:

 } else {
   defaultVal := ""
   if flag.Default != nil {
     if strVal, ok := flag.Default.(string); ok {
       defaultVal = strVal
+    } else {
+      log.Warn("Invalid default value for string flag, using empty string", "flag", flag.Name, "default", flag.Default)
     }
   }

This maintains consistency with the boolean flag suggestion and aids debugging.

📜 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 a10d9ad and dffe967.

📒 Files selected for processing (5)
  • cmd/cmd_utils.go (1 hunks)
  • cmd/custom_command_integration_test.go (1 hunks)
  • pkg/schema/command.go (1 hunks)
  • website/blog/2025-12-08-custom-command-boolean-flags.mdx (1 hunks)
  • website/docs/cli/configuration/commands.mdx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
website/**

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

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

Files:

  • website/blog/2025-12-08-custom-command-boolean-flags.mdx
  • website/docs/cli/configuration/commands.mdx
website/blog/*.mdx

📄 CodeRabbit inference engine (CLAUDE.md)

Blog posts require YAML front matter with slug, title, authors, and tags. Use <!--truncate--> after intro. ONLY use existing tags from website/blog/*.mdx - check before writing. Author field must be GitHub username, added to website/blog/authors.yml. Filename format: YYYY-MM-DD-feature-name.mdx. PRs labeled minor/major MUST include blog post

Files:

  • website/blog/2025-12-08-custom-command-boolean-flags.mdx
cmd/**/*.go

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

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

cmd/**/*.go: CLI command files must be thin wrappers that only handle CLI concerns (flags, arguments, command registration). All business logic must be delegated to pkg/ packages
Use flags.NewStandardParser() for command-specific flag parsing. NEVER call viper.BindEnv() or viper.BindPFlag() directly - use the unified pkg/flags/ infrastructure instead. Register flags with Cobra command and bind to Viper for precedence handling
All CLI commands MUST implement the CommandProvider interface and register via command registry pattern in cmd/internal/registry.go
Embed examples from cmd/markdown/*_usage.md using //go:embed. Render with utils.PrintfMarkdown()

Files:

  • cmd/cmd_utils.go
  • cmd/custom_command_integration_test.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: All comments must end with periods (enforced by godot linter)
Import organization: three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages. Maintain aliases: cfg, log, u, errUtils
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig param
Keep files small and focused (<600 lines). One cmd/impl per file. Co-locate tests. Never use //revive:disable:file-length-limit
Use sentinel errors from errors/errors.go with ErrorBuilder for all user-facing errors. Use errors.Is() for checking errors, never string comparison. WithCause() preserves underlying error messages, WithExplanation() adds context, WithHint() provides guidance, WithContext() adds key-value pairs
Use context.Context as first parameter for: cancellation signals (prop...

Files:

  • cmd/cmd_utils.go
  • pkg/schema/command.go
  • cmd/custom_command_integration_test.go
pkg/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

pkg/**/*.go: Business logic packages must follow the Service-Oriented Architecture pattern with: one Service struct per domain, Provider interfaces for classes of problems, default implementations, mock implementations, and dependency injection for testability
Use interface-driven design: define interfaces for all major functionality, use dependency injection for testability, generate mocks with go.uber.org/mock/mockgen with //go:generate directives, avoid integration tests by mocking external dependencies
Create focused purpose-built packages in pkg/ for new functionality, each with clear responsibility. DO NOT add new functions to pkg/utils/ or internal/exec/. Each package should have focused business logic with tests
Implement registry pattern for extensibility and plugin-like architecture. Define interfaces for provider implementations, register implementations in registry, generate mocks with mockgen. Examples: Command Registry in cmd/internal/registry.go, Store Registry in pkg/store/registry.go

Files:

  • pkg/schema/command.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 assert.ErrorIs(t, err, ErrSentinel) for checking our own errors and stdlib errors. Only use string matching for third-party errors
NEVER use assert.Contains(err.Error(), ...) for error checking. ALWAYS use assert.ErrorIs() instead. NEVER use string comparison: err.Error() == "..." or strings.Contains(err.Error(), ...)
Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoid os.Exit, CheckErrorPrintAndExit, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation. Never create manual mocks. Pattern: //go:generate go run go.uber.org/mock/mockgen@latest -source=filename.go -destination=mock_filename_test.go
Use table-driven tests for comprehensive coverage. Tests must call actual production code, never duplicate logic. Target >80% test coverage (enforced by CodeCov)

Files:

  • cmd/custom_command_integration_test.go
cmd/**/*_test.go

📄 CodeRabbit inference engine (CLAUDE.md)

ALWAYS use cmd.NewTestKit(t) for cmd tests. This auto-cleans RootCmd state (flags, args) and is required for any test touching RootCmd

Files:

  • cmd/custom_command_integration_test.go
🧠 Learnings (28)
📓 Common learnings
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.
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
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
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to website/docs/cli/commands/**/*.mdx : All CLI commands need Docusaurus documentation using `<dl>` for arguments/flags. Follow Docusaurus conventions: frontmatter (slug, title, etc.), purpose note, screengrab, usage/examples/arguments/flags sections. File location: `website/docs/cli/commands/<command>/<subcommand>.mdx`. Always build after changes: `cd website && npm run build`

Applied to files:

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

Applied to files:

  • website/blog/2025-12-08-custom-command-boolean-flags.mdx
  • cmd/cmd_utils.go
  • website/docs/cli/configuration/commands.mdx
  • cmd/custom_command_integration_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions

Applied to files:

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

Applied to files:

  • cmd/cmd_utils.go
  • website/docs/cli/configuration/commands.mdx
  • cmd/custom_command_integration_test.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/cmd_utils.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to cmd/**/*.go : CLI command files must be thin wrappers that only handle CLI concerns (flags, arguments, command registration). All business logic must be delegated to `pkg/` packages

Applied to files:

  • cmd/cmd_utils.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to cmd/**/*.go : Use `flags.NewStandardParser()` for command-specific flag parsing. NEVER call `viper.BindEnv()` or `viper.BindPFlag()` directly - use the unified `pkg/flags/` infrastructure instead. Register flags with Cobra command and bind to Viper for precedence handling

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 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:

  • website/docs/cli/configuration/commands.mdx
  • cmd/custom_command_integration_test.go
📚 Learning: 2024-12-01T00:33:20.298Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml:28-32
Timestamp: 2024-12-01T00:33:20.298Z
Learning: In `examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml`, `!exec atmos terraform output` is used in examples to demonstrate its usage, even though `!terraform.output` is the recommended approach according to the documentation.

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*.go : Use `viper.BindEnv("ATMOS_VAR", "ATMOS_VAR", "FALLBACK")` for environment variables - ATMOS_ prefix required. Configuration loading precedence: CLI flags → ENV vars → config files → defaults

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

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

Applied to files:

  • cmd/custom_command_integration_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*_test.go : Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoid `os.Exit`, `CheckErrorPrintAndExit`, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios

Applied to files:

  • cmd/custom_command_integration_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to tests/**/*.go : Use `cmd.NewTestKit(t)` for any test touching RootCmd. This auto-cleans RootCmd state. Tests skip gracefully with helpers from `tests/test_preconditions.go`

Applied to files:

  • cmd/custom_command_integration_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages

Applied to files:

  • cmd/custom_command_integration_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*_test.go : Use table-driven tests for comprehensive coverage. Tests must call actual production code, never duplicate logic. Target >80% test coverage (enforced by CodeCov)

Applied to files:

  • cmd/custom_command_integration_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to cmd/**/*_test.go : ALWAYS use `cmd.NewTestKit(t)` for cmd tests. This auto-cleans RootCmd state (flags, args) and is required for any test touching RootCmd

Applied to files:

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

Applied to files:

  • cmd/custom_command_integration_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:

  • cmd/custom_command_integration_test.go
🧬 Code graph analysis (1)
cmd/custom_command_integration_test.go (4)
cmd/testkit_test.go (1)
  • NewTestKit (55-65)
pkg/config/config.go (1)
  • InitCliConfig (28-67)
pkg/schema/command.go (2)
  • Command (5-16)
  • CommandFlag (25-33)
cmd/root.go (1)
  • RootCmd (290-433)
⏰ 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). (1)
  • GitHub Check: Summary
🔇 Additional comments (6)
website/blog/2025-12-08-custom-command-boolean-flags.mdx (1)

12-69: LGTM! Well-structured blog post with clear examples.

The blog post follows the required structure with the <!--truncate--> marker after the introduction, clear YAML examples demonstrating the new feature, and a helpful link to detailed documentation.

website/docs/cli/configuration/commands.mdx (2)

134-243: LGTM! Comprehensive documentation for boolean flags.

The Boolean Flags section provides clear examples and covers all usage patterns developers need. The seven patterns demonstrate conditional execution, inline conditionals, flag passing, negation, and shell variable conversion. The tip about boolean values rendering as lowercase strings is particularly helpful.


244-264: LGTM! Clear explanation of flag defaults.

The Flag Defaults section concisely explains the feature with examples covering both string and boolean flags. The note about omitting flags is helpful for users.

pkg/schema/command.go (1)

32-32: LGTM! Using any type for flexible defaults.

The any type allows the Default field to hold both boolean and string values, which aligns with the feature requirements. The code in cmd_utils.go properly handles type assertions to extract values safely.

cmd/custom_command_integration_test.go (2)

260-343: LGTM! Comprehensive test for boolean flag defaults.

The test properly uses NewTestKit(t) for clean state management and thoroughly verifies all scenarios: explicit false default, explicit true default, and no default (should fall back to false). The test validates actual flag registration behavior rather than mocking.

Based on coding guidelines for test coverage.


345-420: LGTM! Comprehensive test for string flag defaults.

The test properly uses NewTestKit(t) and validates all string flag default scenarios: explicit defaults ("development", "json") and no default (empty string). The test structure mirrors the boolean flag test, providing good consistency.

Based on coding guidelines for test coverage.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 8, 2025
Update snapshot to include new 'default' field in CommandFlag schema output.

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

Co-Authored-By: Claude <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov bot commented Dec 8, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.84%. Comparing base (40a0d1c) to head (3ad2136).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1848      +/-   ##
==========================================
+ Coverage   72.81%   72.84%   +0.03%     
==========================================
  Files         528      528              
  Lines       50533    50539       +6     
==========================================
+ Hits        36796    36816      +20     
+ Misses      10966    10954      -12     
+ Partials     2771     2769       -2     
Flag Coverage Δ
unittests 72.84% <100.00%> (+0.03%) ⬆️

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

Files with missing lines Coverage Δ
cmd/cmd_utils.go 56.36% <100.00%> (+2.35%) ⬆️

... and 2 files with indirect coverage changes

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

Add TestCustomCommandIntegration_BooleanFlagTemplatePatterns to verify
that boolean flags work correctly with various Go template patterns:
- {{ if .Flags.verbose }} (conditional block)
- {{ if .Flags.verbose }}...{{ end }} (inline conditional)
- {{ if .Flags.clean }}...{{ else }}...{{ end }} (if/else)
- {{ if not .Flags.verbose }} (negation)
- {{ .Flags.verbose }} (direct value rendering as "true"/"false")
- {{ printf "%t" .Flags.clean }} (explicit boolean formatting)

Tests verify both default values (verbose=false, clean=true) and
explicit flag overrides (--verbose --clean=false).

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

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
pkg/schema/command.go (1)

32-32: Add documentation for the Default field.

The Default field lacks a godoc comment explaining what types are valid. Based on the usage in cmd/cmd_utils.go, this field accepts bool or string values (or nil for no default). Document these expectations to guide users.

Apply this diff:

+	// Default specifies the default value for the flag.
+	// For boolean flags (type: bool), this should be a bool value (true/false).
+	// For string flags, this should be a string value.
+	// If omitted or nil, defaults to false for boolean flags and empty string for string flags.
 	Default     any    `yaml:"default" json:"default" mapstructure:"default"`
cmd/cmd_utils.go (1)

109-143: Consider validating Default value type against flag type.

The code silently falls back to hardcoded defaults when flag.Default is provided but doesn't match the expected type. For example, if a user mistakenly configures default: "true" (string) for a boolean flag, it will silently use false instead. This could confuse users debugging their configuration.

Consider logging a warning when type mismatch occurs:

 			// Process and add flags to the command.
 			for _, flag := range commandConfig.Flags {
 				if flag.Type == "bool" {
 					defaultVal := false
 					if flag.Default != nil {
 						if boolVal, ok := flag.Default.(bool); ok {
 							defaultVal = boolVal
+						} else {
+							log.Warn("Boolean flag has non-boolean default, using false",
+								"flag", flag.Name,
+								"default", flag.Default,
+								"command", commandConfig.Name)
 						}
 					}
 					if flag.Shorthand != "" {
 						customCommand.PersistentFlags().BoolP(flag.Name, flag.Shorthand, defaultVal, flag.Usage)
 					} else {
 						customCommand.PersistentFlags().Bool(flag.Name, defaultVal, flag.Usage)
 					}
 				} else {
 					defaultVal := ""
 					if flag.Default != nil {
 						if strVal, ok := flag.Default.(string); ok {
 							defaultVal = strVal
+						} else {
+							log.Warn("String flag has non-string default, using empty string",
+								"flag", flag.Name,
+								"default", flag.Default,
+								"command", commandConfig.Name)
 						}
 					}
 					if flag.Shorthand != "" {
 						customCommand.PersistentFlags().StringP(flag.Name, flag.Shorthand, defaultVal, flag.Usage)
 					} else {
 						customCommand.PersistentFlags().String(flag.Name, defaultVal, flag.Usage)
 					}
 				}
cmd/custom_command_integration_test.go (2)

260-343: Test verifies flag registration but not execution.

The test correctly validates that boolean flags with various defaults are registered with the expected DefValue. However, it doesn't execute the command to verify the defaults work correctly at runtime. This is acceptable given TestCustomCommandIntegration_BooleanFlagTemplatePatterns provides comprehensive execution testing, but consider adding a simpler execution test here for completeness.

Based on learnings, this is solid test coverage for the feature.


480-555: Test verifies flag registration but not execution.

Similar to the boolean flag defaults test, this validates string flags are registered with correct defaults but doesn't execute the command. This is acceptable coverage, though adding a simple execution test would provide additional confidence.

📜 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 a10d9ad and 2688fb1.

📒 Files selected for processing (6)
  • cmd/cmd_utils.go (1 hunks)
  • cmd/custom_command_integration_test.go (1 hunks)
  • pkg/schema/command.go (1 hunks)
  • tests/snapshots/TestCLICommands_atmos_describe_config_imports.stdout.golden (3 hunks)
  • website/blog/2025-12-08-custom-command-boolean-flags.mdx (1 hunks)
  • website/docs/cli/configuration/commands.mdx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.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)
Import organization: three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages. Maintain aliases: cfg, log, u, errUtils
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig param
Keep files small and focused (<600 lines). One cmd/impl per file. Co-locate tests. Never use //revive:disable:file-length-limit
Use sentinel errors from errors/errors.go with ErrorBuilder for all user-facing errors. Use errors.Is() for checking errors, never string comparison. WithCause() preserves underlying error messages, WithExplanation() adds context, WithHint() provides guidance, WithContext() adds key-value pairs
Use context.Context as first parameter for: cancellation signals (prop...

Files:

  • pkg/schema/command.go
  • cmd/cmd_utils.go
  • cmd/custom_command_integration_test.go
pkg/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

pkg/**/*.go: Business logic packages must follow the Service-Oriented Architecture pattern with: one Service struct per domain, Provider interfaces for classes of problems, default implementations, mock implementations, and dependency injection for testability
Use interface-driven design: define interfaces for all major functionality, use dependency injection for testability, generate mocks with go.uber.org/mock/mockgen with //go:generate directives, avoid integration tests by mocking external dependencies
Create focused purpose-built packages in pkg/ for new functionality, each with clear responsibility. DO NOT add new functions to pkg/utils/ or internal/exec/. Each package should have focused business logic with tests
Implement registry pattern for extensibility and plugin-like architecture. Define interfaces for provider implementations, register implementations in registry, generate mocks with mockgen. Examples: Command Registry in cmd/internal/registry.go, Store Registry in pkg/store/registry.go

Files:

  • pkg/schema/command.go
website/**

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

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

Files:

  • website/blog/2025-12-08-custom-command-boolean-flags.mdx
  • website/docs/cli/configuration/commands.mdx
website/blog/*.mdx

📄 CodeRabbit inference engine (CLAUDE.md)

Blog posts require YAML front matter with slug, title, authors, and tags. Use <!--truncate--> after intro. ONLY use existing tags from website/blog/*.mdx - check before writing. Author field must be GitHub username, added to website/blog/authors.yml. Filename format: YYYY-MM-DD-feature-name.mdx. PRs labeled minor/major MUST include blog post

Files:

  • website/blog/2025-12-08-custom-command-boolean-flags.mdx
cmd/**/*.go

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

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

cmd/**/*.go: CLI command files must be thin wrappers that only handle CLI concerns (flags, arguments, command registration). All business logic must be delegated to pkg/ packages
Use flags.NewStandardParser() for command-specific flag parsing. NEVER call viper.BindEnv() or viper.BindPFlag() directly - use the unified pkg/flags/ infrastructure instead. Register flags with Cobra command and bind to Viper for precedence handling
All CLI commands MUST implement the CommandProvider interface and register via command registry pattern in cmd/internal/registry.go
Embed examples from cmd/markdown/*_usage.md using //go:embed. Render with utils.PrintfMarkdown()

Files:

  • cmd/cmd_utils.go
  • cmd/custom_command_integration_test.go
**/*_test.go

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

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

**/*_test.go: Use assert.ErrorIs(t, err, ErrSentinel) for checking our own errors and stdlib errors. Only use string matching for third-party errors
NEVER use assert.Contains(err.Error(), ...) for error checking. ALWAYS use assert.ErrorIs() instead. NEVER use string comparison: err.Error() == "..." or strings.Contains(err.Error(), ...)
Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoid os.Exit, CheckErrorPrintAndExit, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation. Never create manual mocks. Pattern: //go:generate go run go.uber.org/mock/mockgen@latest -source=filename.go -destination=mock_filename_test.go
Use table-driven tests for comprehensive coverage. Tests must call actual production code, never duplicate logic. Target >80% test coverage (enforced by CodeCov)

Files:

  • cmd/custom_command_integration_test.go
cmd/**/*_test.go

📄 CodeRabbit inference engine (CLAUDE.md)

ALWAYS use cmd.NewTestKit(t) for cmd tests. This auto-cleans RootCmd state (flags, args) and is required for any test touching RootCmd

Files:

  • cmd/custom_command_integration_test.go
🧠 Learnings (34)
📓 Common learnings
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.
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to website/docs/cli/commands/**/*.mdx : All CLI commands need Docusaurus documentation using `<dl>` for arguments/flags. Follow Docusaurus conventions: frontmatter (slug, title, etc.), purpose note, screengrab, usage/examples/arguments/flags sections. File location: `website/docs/cli/commands/<command>/<subcommand>.mdx`. Always build after changes: `cd website && npm run build`

Applied to files:

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

Applied to files:

  • website/blog/2025-12-08-custom-command-boolean-flags.mdx
  • cmd/cmd_utils.go
  • website/docs/cli/configuration/commands.mdx
  • tests/snapshots/TestCLICommands_atmos_describe_config_imports.stdout.golden
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to cmd/**/*.go : Use `flags.NewStandardParser()` for command-specific flag parsing. NEVER call `viper.BindEnv()` or `viper.BindPFlag()` directly - use the unified `pkg/flags/` infrastructure instead. Register flags with Cobra command and bind to Viper for precedence handling

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • cmd/cmd_utils.go
  • cmd/custom_command_integration_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • website/docs/cli/configuration/commands.mdx
  • tests/snapshots/TestCLICommands_atmos_describe_config_imports.stdout.golden
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to README.md : Update README.md with new commands and features

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 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:

  • website/docs/cli/configuration/commands.mdx
  • cmd/custom_command_integration_test.go
📚 Learning: 2024-12-01T00:33:20.298Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml:28-32
Timestamp: 2024-12-01T00:33:20.298Z
Learning: In `examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml`, `!exec atmos terraform output` is used in examples to demonstrate its usage, even though `!terraform.output` is the recommended approach according to the documentation.

Applied to files:

  • website/docs/cli/configuration/commands.mdx
  • tests/snapshots/TestCLICommands_atmos_describe_config_imports.stdout.golden
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*.go : Use `viper.BindEnv("ATMOS_VAR", "ATMOS_VAR", "FALLBACK")` for environment variables - ATMOS_ prefix required. Configuration loading precedence: CLI flags → ENV vars → config files → defaults

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_describe_config_imports.stdout.golden
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to tests/**/*.yaml : NEVER modify `tests/test-cases/` or `tests/testdata/` unless explicitly instructed. Golden snapshots are sensitive to minor changes. Use fixtures in `tests/test-cases/`: `atmos.yaml`, `stacks/`, `components/`

Applied to files:

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

Applied to files:

  • tests/snapshots/TestCLICommands_atmos_describe_config_imports.stdout.golden
📚 Learning: 2024-12-07T16:19:01.683Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.

Applied to files:

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

Applied to files:

  • cmd/custom_command_integration_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to tests/**/*.go : Use `cmd.NewTestKit(t)` for any test touching RootCmd. This auto-cleans RootCmd state. Tests skip gracefully with helpers from `tests/test_preconditions.go`

Applied to files:

  • cmd/custom_command_integration_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*.go : New configs support Go templating with `FuncMap()` from `internal/exec/template_funcs.go`. Implement template functions in `internal/exec/template_funcs.go`, register them, add tests, and update documentation

Applied to files:

  • cmd/custom_command_integration_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*_test.go : Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoid `os.Exit`, `CheckErrorPrintAndExit`, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios

Applied to files:

  • cmd/custom_command_integration_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to cmd/**/*_test.go : ALWAYS use `cmd.NewTestKit(t)` for cmd tests. This auto-cleans RootCmd state (flags, args) and is required for any test touching RootCmd

Applied to files:

  • cmd/custom_command_integration_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages

Applied to files:

  • cmd/custom_command_integration_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to cmd/**/*.go : All CLI commands MUST implement the CommandProvider interface and register via command registry pattern in `cmd/internal/registry.go`

Applied to files:

  • cmd/custom_command_integration_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*_test.go : Use table-driven tests for comprehensive coverage. Tests must call actual production code, never duplicate logic. Target >80% test coverage (enforced by CodeCov)

Applied to files:

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

Applied to files:

  • cmd/custom_command_integration_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:

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

Applied to files:

  • cmd/custom_command_integration_test.go
🧬 Code graph analysis (1)
cmd/custom_command_integration_test.go (4)
cmd/testkit_test.go (1)
  • NewTestKit (55-65)
pkg/config/config.go (1)
  • InitCliConfig (28-67)
pkg/schema/command.go (2)
  • Command (5-16)
  • CommandFlag (25-33)
cmd/root.go (1)
  • RootCmd (290-433)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
🔇 Additional comments (4)
tests/snapshots/TestCLICommands_atmos_describe_config_imports.stdout.golden (1)

75-75: LGTM!

The snapshot correctly reflects the new Default field in flag definitions. The default: null values are appropriate for required flags that don't have configured defaults.

Also applies to: 115-115, 168-168

website/blog/2025-12-08-custom-command-boolean-flags.mdx (1)

1-69: LGTM!

The blog post effectively documents the new boolean flag defaults feature. The examples are clear and practical, demonstrating both boolean and string flag usage patterns. Proper frontmatter and truncate marker are in place.

website/docs/cli/configuration/commands.mdx (1)

134-264: Excellent documentation!

The new sections comprehensively cover boolean flags and defaults with practical examples. The seven template patterns (lines 184-243) provide clear guidance for different use cases. The tip about boolean values rendering as lowercase strings is particularly helpful.

cmd/custom_command_integration_test.go (1)

345-478: LGTM! Comprehensive template pattern coverage.

This test thoroughly validates boolean flags in Go templates with six different patterns and two execution scenarios. The comment explaining why RootCmd.Execute() is necessary (lines 416-418) is particularly helpful for future maintainers.

Based on learnings, tests use proper patterns with NewTestKit and t.Setenv.

@aknysh aknysh merged commit e402d17 into main Dec 8, 2025
57 checks passed
@aknysh aknysh deleted the feature/dev-3810-custom-commands-boolean-flags-support branch December 8, 2025 21:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor New features that do not break anything size/l Large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom commands: boolean flags support

2 participants