feat: Improve source provisioner UX with spinners and interactive delete#1965
feat: Improve source provisioner UX with spinners and interactive delete#1965
Conversation
- Add spinner to auto-provisioning in provision_hook.go - Add PromptForConfirmation() to pkg/flags/interactive.go for reusable destructive action confirmation prompts - Update delete command to prompt interactively instead of requiring --force - Delete operation now shows spinner during deletion - Add blog post and roadmap milestone for the enhancement Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds interactive prompting for missing component/stack across source provisioner commands, a TTY-guarded destructive confirmation helper, spinner-wrapped vendoring/deletion UX, shell completion helpers, and extensive tests and docs updates. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI as Source CLI (delete/pull/describe/list)
participant Prompt as Prompt subsystem
participant Config as Atmos Config / DescribeStacks
participant Spinner as Spinner/UI
participant FS as Filesystem
User->>CLI: invoke command (no component/stack)
CLI->>Prompt: PromptForComponent()
Prompt->>Config: listComponentsWithSource()
Config-->>Prompt: components
Prompt->>User: show component selector
User-->>Prompt: select component
Prompt-->>CLI: component
CLI->>Prompt: PromptForStack(component)
Prompt->>Config: listStacksWithSourceForComponent(component)
Config-->>Prompt: stacks
Prompt->>User: show stack selector
User-->>Prompt: select stack
Prompt-->>CLI: stack
CLI->>Prompt: PromptForConfirmation(title, force)
alt force == true
Prompt-->>CLI: confirmed
else
Prompt->>User: show yes/no prompt (TTY required)
User-->>Prompt: confirm/decline
Prompt-->>CLI: result
end
alt confirmed
CLI->>Spinner: start operation spinner
Spinner->>FS: perform os.RemoveAll / vendor
FS-->>Spinner: success/failure
Spinner->>User: show completion
else declined
CLI->>User: operation cancelled
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
🧹 Recent nitpick comments
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (4)
🧰 Additional context used📓 Path-based instructions (3)**/*.go📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
Files:
**/*_test.go📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
Files:
**/{pkg,internal,cmd}/**/*.go📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (33)📓 Common learnings📚 Learning: 2025-11-24T17:35:37.209ZApplied to files:
📚 Learning: 2025-11-24T17:35:37.209ZApplied to files:
📚 Learning: 2025-11-24T17:35:37.209ZApplied to files:
📚 Learning: 2025-12-10T18:32:51.237ZApplied to files:
📚 Learning: 2024-11-16T17:30:52.893ZApplied to files:
📚 Learning: 2026-01-04T00:55:21.720ZApplied to files:
📚 Learning: 2025-11-24T17:35:37.209ZApplied to files:
📚 Learning: 2026-01-04T00:55:21.720ZApplied to files:
📚 Learning: 2025-11-24T17:35:37.209ZApplied to files:
📚 Learning: 2025-01-09T22:27:25.538ZApplied to files:
📚 Learning: 2024-11-12T03:16:02.910ZApplied to files:
📚 Learning: 2025-12-13T04:37:40.435ZApplied to files:
📚 Learning: 2025-12-21T04:10:29.030ZApplied to files:
📚 Learning: 2024-11-02T15:35:09.958ZApplied to files:
📚 Learning: 2025-05-23T19:51:47.091ZApplied to files:
📚 Learning: 2025-11-11T03:47:59.576ZApplied to files:
📚 Learning: 2024-10-28T01:51:30.811ZApplied to files:
📚 Learning: 2025-12-13T06:10:25.156ZApplied to files:
📚 Learning: 2025-11-11T03:47:45.878ZApplied to files:
📚 Learning: 2025-05-23T19:51:47.091ZApplied to files:
📚 Learning: 2026-01-04T00:55:21.720ZApplied to files:
📚 Learning: 2026-01-04T00:55:21.720ZApplied to files:
📚 Learning: 2025-11-24T17:35:37.209ZApplied to files:
📚 Learning: 2025-05-23T19:51:47.091ZApplied to files:
📚 Learning: 2025-05-23T19:51:47.091ZApplied to files:
📚 Learning: 2025-08-15T14:43:41.030ZApplied to files:
📚 Learning: 2024-12-07T16:19:01.683ZApplied to files:
📚 Learning: 2025-10-11T19:11:58.965ZApplied to files:
📚 Learning: 2025-01-09T22:37:01.004ZApplied to files:
📚 Learning: 2024-12-07T16:16:13.038ZApplied to files:
📚 Learning: 2025-10-07T00:25:16.333ZApplied to files:
📚 Learning: 2024-12-25T20:28:47.526ZApplied to files:
🧬 Code graph analysis (1)pkg/provisioner/source/cmd/prompt_test.go (2)
⏰ 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)
🔇 Additional comments (23)
✏️ Tip: You can disable this entire section by setting Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Dependency Review✅ No vulnerabilities or license issues found.Scanned FilesNone |
When --stack flag is omitted, source commands (pull, delete, describe, list) now prompt interactively for stack selection instead of immediately erroring. The prompt shows only stacks that contain the specified component with source configured, providing a filtered and relevant selection. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When component argument is omitted, source commands (pull, delete, describe) now prompt interactively for component selection in addition to stack selection. The prompt shows only terraform components that have source configured, providing a filtered and relevant selection. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…force The delete command returns nil when the directory doesn't exist (nothing to delete), so the tests expecting an error about --force were failing. Updated tests to create the target directory first so the --force requirement can be properly tested. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1965 +/- ##
==========================================
- Coverage 74.37% 74.37% -0.01%
==========================================
Files 774 775 +1
Lines 70119 70359 +240
==========================================
+ Hits 52151 52328 +177
- Misses 14548 14597 +49
- Partials 3420 3434 +14
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
The TestSourceProvisionerDelete_MissingForce tests were failing because the `force` flag value from previous tests leaked via the global Viper instance. Added viper.Reset() calls at the start of both delete tests to ensure clean state. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Fix all issues with AI agents
In `@pkg/provisioner/source/cmd/delete.go`:
- Around line 114-118: The code shadows the outer err when checking
PromptForStack's result: after calling PromptForStack (assigned to stack, err)
change the inner short-declaration so it reuses the existing err variable
instead of creating a new one; specifically replace the "if err :=
HandlePromptError(err, \"stack\"); err != nil" pattern with an assignment that
sets the outer err (e.g., "if err = HandlePromptError(err, \"stack\"); err !=
nil") so PromptForStack, HandlePromptError, stack and err are all correctly
handled without shadowing.
- Around line 72-76: The prompt error check currently uses a short-declared
variable that shadows the previously set err from PromptForComponent, causing
the original error to be ignored; change the shadowing short declaration to an
assignment so HandlePromptError reuses the existing err variable (i.e., assign
the result of HandlePromptError(err, "component") to the already-declared err
and return it if non-nil) for the PromptForComponent/HandlePromptError sequence.
In `@pkg/provisioner/source/cmd/describe.go`:
- Around line 86-90: The code shadows the earlier err from PromptForStack
because HandlePromptError is called with :=; change the shadowing assignment to
reuse the existing err variable—call PromptForStack as now, then replace `if err
:= HandlePromptError(err, "stack"); err != nil { return err }` with `if err =
HandlePromptError(err, "stack"); err != nil { return err }` so PromptForStack's
error is preserved and properly checked; references: PromptForStack,
HandlePromptError, stack, err.
- Around line 68-72: The code shadows the earlier err from PromptForComponent by
using := in the if statement, so the error returned by PromptForComponent is
ignored; change the if to assign to the existing err (e.g., use err =
HandlePromptError(err, "component") and then check if err != nil) or separate
into two statements: err = HandlePromptError(err, "component"); if err != nil {
return err } so PromptForComponent and HandlePromptError errors are correctly
handled (refer to PromptForComponent, HandlePromptError, and the err/component
variables).
In `@pkg/provisioner/source/cmd/pull.go`:
- Around line 91-95: The code shadows the previously declared err when calling
HandlePromptError after PromptForStack; replace the short-declaration that
creates a new err with an assignment to the existing err (i.e., use if err =
HandlePromptError(err, "stack"); err != nil { return err }) or use a distinct
name like perr to avoid shadowing; update the call site around
PromptForStack/HandlePromptError so PromptForStack's err is checked correctly
without shadowing (references: stack, err, PromptForStack, HandlePromptError,
cmd, component).
- Around line 73-77: The prompt error is being shadowed: in pull.go you call
component, err = PromptForComponent(cmd) but then redeclare a new err in the if
statement (if err := HandlePromptError(err, "component"); ...), which hides the
original err and can cause the prompt error to be ignored; change the if to
reuse the existing err variable (e.g., if err = HandlePromptError(err,
"component"); err != nil { return err }) so HandlePromptError actually receives
and returns the original error from PromptForComponent and is properly checked;
update the same pattern wherever PromptForComponent, HandlePromptError or
similar prompt/error handling occurs in this file.
♻️ Duplicate comments (1)
tests/cli_source_provisioner_test.go (1)
15-21: Same consolidation opportunity noted.Duplicate of
resetWorkdirViperState()in the other test file. Same package, could share.
🧹 Nitpick comments (2)
pkg/provisioner/source/cmd/prompt.go (1)
103-125: Consider caching ExecuteDescribeStacks results.Each list function (
listStacksWithSourceForComponent,listStacksWithSource,listComponentsWithSource) initializes config and callsExecuteDescribeStacksindependently. For shell completion, this is called on each tab press. Not a blocker, but could be optimized later with a shared cache.Also applies to: 152-174, 202-227
tests/cli_source_provisioner_workdir_test.go (1)
15-21: Consider consolidating duplicate helper.Both
resetWorkdirViperState()here andresetViperState()incli_source_provisioner_test.godo the same thing. Since they're in the same package, you could define it once in a shared test helper file (e.g.,helpers_test.go) and use it across both test files.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (14)
pkg/flags/interactive.gopkg/provisioner/source/cmd/delete.gopkg/provisioner/source/cmd/delete_test.gopkg/provisioner/source/cmd/describe.gopkg/provisioner/source/cmd/describe_test.gopkg/provisioner/source/cmd/list.gopkg/provisioner/source/cmd/prompt.gopkg/provisioner/source/cmd/pull.gopkg/provisioner/source/cmd/pull_test.gopkg/provisioner/source/provision_hook.gotests/cli_source_provisioner_test.gotests/cli_source_provisioner_workdir_test.gowebsite/blog/2026-01-14-source-provisioner-ux.mdxwebsite/src/data/roadmap.js
🧰 Additional context used
📓 Path-based instructions (5)
**/*.go
📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context usingfmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: usegofmtandgoimportsto format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging
**/*.go: All comments must end with periods (enforced bygodotlinter) in Go code
Organize imports into three groups separated by blank lines, sorted alphabetically: Go stdlib, 3rd-party (NOT cloudposse/atmos), then Atmos packages with maintained aliases (cfg,log,u,errUtils)
All errors MUST be wrapped using static errors defined inerrors/errors.go- useerrors.Joinfor combining errors,fmt.Errorfwith%wfor context, anderrors.Is()for error checking
Never manually create mocks - usego.uber.org/mock/mockgenwith//go:generatedirectives in Go code
Keep files small and focused - under 600 lines with one cmd/impl per file, co-locate tests, never use//revive:disable:file-length-limit
Use colors frompkg/ui/theme/colors.gofor all UI theming in Go code
Code must be compatible with Linux, macOS, and Windows - use SDKs over binaries, usefilepath.Join()instead of h...
Files:
pkg/provisioner/source/cmd/pull_test.gopkg/provisioner/source/provision_hook.gopkg/flags/interactive.gopkg/provisioner/source/cmd/describe.gopkg/provisioner/source/cmd/pull.gopkg/provisioner/source/cmd/describe_test.gopkg/provisioner/source/cmd/list.gopkg/provisioner/source/cmd/delete.gotests/cli_source_provisioner_test.gopkg/provisioner/source/cmd/delete_test.gopkg/provisioner/source/cmd/prompt.gotests/cli_source_provisioner_workdir_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 fixturesPrefer unit tests with mocks over integration tests - use interfaces and dependency injection for testability, generate mocks with
go.uber.org/mock/mockgen, use table-driven tests, target >80% coverage
Files:
pkg/provisioner/source/cmd/pull_test.gopkg/provisioner/source/cmd/describe_test.gotests/cli_source_provisioner_test.gopkg/provisioner/source/cmd/delete_test.gotests/cli_source_provisioner_workdir_test.go
**/{pkg,internal,cmd}/**/*.go
📄 CodeRabbit inference engine (CLAUDE.md)
Add
defer perf.Track(atmosConfig, "pkg.FuncName")()plus blank line to all public functions, usingnilif no atmosConfig param - exceptions: trivial getters/setters, command constructors, simple factories, functions delegating to tracked functions
Files:
pkg/provisioner/source/cmd/pull_test.gopkg/provisioner/source/provision_hook.gopkg/flags/interactive.gopkg/provisioner/source/cmd/describe.gopkg/provisioner/source/cmd/pull.gopkg/provisioner/source/cmd/describe_test.gopkg/provisioner/source/cmd/list.gopkg/provisioner/source/cmd/delete.gopkg/provisioner/source/cmd/delete_test.gopkg/provisioner/source/cmd/prompt.go
website/**
📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
website/**: Update website documentation in thewebsite/directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in thewebsite/directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases
Files:
website/src/data/roadmap.jswebsite/blog/2026-01-14-source-provisioner-ux.mdx
website/blog/*.mdx
📄 CodeRabbit inference engine (CLAUDE.md)
PRs labeled
minorormajorMUST include a blog post atwebsite/blog/YYYY-MM-DD-feature-name.mdxwith YAML frontmatter, using only tags defined inwebsite/blog/tags.yml
Files:
website/blog/2026-01-14-source-provisioner-ux.mdx
🧠 Learnings (56)
📓 Common learnings
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:233-235
Timestamp: 2024-10-31T19:25:41.298Z
Learning: When specifying color values in functions like `confirmDeleteTerraformLocal` in `internal/exec/terraform_clean.go`, avoid hardcoding color values. Instead, use predefined color constants or allow customization through configuration settings to improve accessibility and user experience across different terminals and themes.
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
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform.go:114-118
Timestamp: 2024-10-21T17:51:07.087Z
Learning: Use `bubbletea` for confirmation prompts instead of `fmt.Scanln` in the `atmos terraform clean` command.
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform.go:114-118
Timestamp: 2024-10-21T17:51:53.976Z
Learning: When `atmos terraform clean --everything` is used without specifying a component and without the `--force` flag, prompt the user for confirmation before deleting all components. Use the `--force` flag to skip the confirmation prompt.
📚 Learning: 2024-12-07T16:16:13.038Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.
Applied to files:
pkg/provisioner/source/cmd/pull_test.gopkg/provisioner/source/cmd/describe.gopkg/provisioner/source/cmd/pull.gopkg/provisioner/source/cmd/describe_test.gopkg/provisioner/source/cmd/list.gopkg/provisioner/source/cmd/prompt.go
📚 Learning: 2025-09-29T02:20:11.636Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1540
File: internal/exec/validate_component.go:117-118
Timestamp: 2025-09-29T02:20:11.636Z
Learning: The ValidateComponent function in internal/exec/validate_component.go had its componentSection parameter type refined from `any` to `map[string]any` without adding new parameters. This is a type safety improvement, not a signature change requiring call site updates.
Applied to files:
pkg/provisioner/source/cmd/pull_test.gopkg/provisioner/source/cmd/describe.gopkg/provisioner/source/cmd/pull.gopkg/provisioner/source/cmd/describe_test.go
📚 Learning: 2025-01-09T22:37:01.004Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.
Applied to files:
pkg/provisioner/source/cmd/pull_test.gopkg/provisioner/source/cmd/describe.gopkg/provisioner/source/cmd/pull.gopkg/provisioner/source/cmd/describe_test.gopkg/provisioner/source/cmd/delete.gopkg/provisioner/source/cmd/delete_test.gopkg/provisioner/source/cmd/prompt.go
📚 Learning: 2025-12-10T18:32:51.237Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1808
File: cmd/terraform/backend/backend_delete_test.go:9-23
Timestamp: 2025-12-10T18:32:51.237Z
Learning: In cmd subpackages (e.g., cmd/terraform/backend/), tests cannot use cmd.NewTestKit(t) due to Go's test visibility rules (NewTestKit is in a parent package test file). These tests only need TestKit if they execute commands through RootCmd or modify RootCmd state. Structural tests that only verify command structure/flags without touching RootCmd don't require TestKit cleanup.
Applied to files:
pkg/provisioner/source/cmd/pull_test.gopkg/provisioner/source/cmd/describe_test.gotests/cli_source_provisioner_test.gopkg/provisioner/source/cmd/delete_test.gotests/cli_source_provisioner_workdir_test.go
📚 Learning: 2025-12-13T04:37:40.435Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/toolchain/get.go:23-40
Timestamp: 2025-12-13T04:37:40.435Z
Learning: In Go CLI command files using Cobra, constrain the subcommand to accept at most one positional argument (MaximumNArgs(1)) so it supports both listing all items (zero args) and fetching a specific item (one arg). Define and parse flags with a standard parser (e.g., flags.NewStandardParser()) and avoid binding flags to Viper (no viper.BindEnv/BindPFlag). This promotes explicit argument handling and predictable flag behavior across command files.
Applied to files:
pkg/provisioner/source/cmd/pull_test.gopkg/provisioner/source/cmd/describe.gopkg/provisioner/source/cmd/pull.gopkg/provisioner/source/cmd/describe_test.gopkg/provisioner/source/cmd/list.gopkg/provisioner/source/cmd/delete.gopkg/provisioner/source/cmd/delete_test.gopkg/provisioner/source/cmd/prompt.go
📚 Learning: 2025-12-21T04:10:29.030Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: internal/exec/describe_affected.go:468-468
Timestamp: 2025-12-21T04:10:29.030Z
Learning: In Go, package-level declarations (constants, variables, types, and functions) are visible to all files in the same package without imports. During reviews in cloudposse/atmos (and similar Go codebases), before suggesting to declare a new identifier, first check if it already exists in another file of the same package. If it exists, you can avoid adding a new declaration; if not, proceed with a proper package-level declaration.
Applied to files:
pkg/provisioner/source/cmd/pull_test.gopkg/provisioner/source/provision_hook.gopkg/flags/interactive.gopkg/provisioner/source/cmd/describe.gopkg/provisioner/source/cmd/pull.gopkg/provisioner/source/cmd/describe_test.gopkg/provisioner/source/cmd/list.gopkg/provisioner/source/cmd/delete.gotests/cli_source_provisioner_test.gopkg/provisioner/source/cmd/delete_test.gopkg/provisioner/source/cmd/prompt.gotests/cli_source_provisioner_workdir_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 meaningful feedback to users and include progress indicators for long-running operations in CLI commands
Applied to files:
pkg/provisioner/source/provision_hook.gopkg/provisioner/source/cmd/delete.gopkg/provisioner/source/cmd/prompt.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:
pkg/provisioner/source/provision_hook.go
📚 Learning: 2024-10-21T17:51:07.087Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform.go:114-118
Timestamp: 2024-10-21T17:51:07.087Z
Learning: Use `bubbletea` for confirmation prompts instead of `fmt.Scanln` in the `atmos terraform clean` command.
Applied to files:
pkg/flags/interactive.gopkg/provisioner/source/cmd/delete_test.gopkg/provisioner/source/cmd/prompt.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:
pkg/provisioner/source/cmd/describe.gopkg/provisioner/source/cmd/pull.gopkg/provisioner/source/cmd/list.gopkg/provisioner/source/cmd/prompt.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:
pkg/provisioner/source/cmd/describe.gopkg/provisioner/source/cmd/pull.gopkg/provisioner/source/cmd/describe_test.gopkg/provisioner/source/cmd/delete.gopkg/provisioner/source/cmd/prompt.go
📚 Learning: 2025-06-23T02:14:30.937Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1327
File: cmd/terraform.go:111-117
Timestamp: 2025-06-23T02:14:30.937Z
Learning: In cmd/terraform.go, flags for the DescribeAffected function are added dynamically at runtime when info.Affected is true. This is intentional to avoid exposing internal flags like "file", "format", "verbose", "include-spacelift-admin-stacks", "include-settings", and "upload" in the terraform command interface, while still providing them for the shared DescribeAffected function used by both `atmos describe affected` and `atmos terraform apply --affected`.
Applied to files:
pkg/provisioner/source/cmd/describe.gopkg/provisioner/source/cmd/prompt.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:
pkg/provisioner/source/cmd/describe.gopkg/provisioner/source/cmd/pull.gopkg/provisioner/source/cmd/delete.go
📚 Learning: 2025-02-03T06:00:11.419Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/describe_config.go:20-20
Timestamp: 2025-02-03T06:00:11.419Z
Learning: The `describe config` command should use `PrintErrorMarkdownAndExit` with empty title and suggestion for consistency with other commands.
Applied to files:
pkg/provisioner/source/cmd/describe.gopkg/provisioner/source/cmd/describe_test.go
📚 Learning: 2025-08-16T23:33:07.477Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:651-652
Timestamp: 2025-08-16T23:33:07.477Z
Learning: In the cloudposse/atmos Go codebase, ExecuteDescribeDependents expects a pointer to AtmosConfiguration (*schema.AtmosConfiguration), so when calling it with a value returned by cfg.InitCliConfig (which returns schema.AtmosConfiguration), the address-of operator (&) is necessary: ExecuteDescribeDependents(&atmosConfig, ...).
Applied to files:
pkg/provisioner/source/cmd/describe.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:
pkg/provisioner/source/cmd/pull.gopkg/provisioner/source/cmd/list.gopkg/provisioner/source/cmd/delete_test.go
📚 Learning: 2025-10-10T23:51:36.597Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.
Applied to files:
pkg/provisioner/source/cmd/pull.gopkg/provisioner/source/cmd/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:
pkg/provisioner/source/cmd/describe_test.gotests/cli_source_provisioner_test.gopkg/provisioner/source/cmd/delete_test.gotests/cli_source_provisioner_workdir_test.go
📚 Learning: 2024-11-16T17:30:52.893Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 786
File: internal/exec/shell_utils.go:159-162
Timestamp: 2024-11-16T17:30:52.893Z
Learning: For the `atmos terraform shell` command in `internal/exec/shell_utils.go`, input validation for the custom shell prompt is not required, as users will use this as a CLI tool and any issues will impact themselves.
Applied to files:
pkg/provisioner/source/cmd/list.gopkg/provisioner/source/cmd/prompt.go
📚 Learning: 2024-12-07T16:19:01.683Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 825
File: internal/exec/terraform.go:30-30
Timestamp: 2024-12-07T16:19:01.683Z
Learning: In `internal/exec/terraform.go`, skipping stack validation when help flags are present is not necessary.
Applied to files:
pkg/provisioner/source/cmd/list.gotests/cli_source_provisioner_test.gotests/cli_source_provisioner_workdir_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:
pkg/provisioner/source/cmd/list.gopkg/provisioner/source/cmd/prompt.go
📚 Learning: 2024-10-31T19:25:41.298Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:233-235
Timestamp: 2024-10-31T19:25:41.298Z
Learning: When specifying color values in functions like `confirmDeleteTerraformLocal` in `internal/exec/terraform_clean.go`, avoid hardcoding color values. Instead, use predefined color constants or allow customization through configuration settings to improve accessibility and user experience across different terminals and themes.
Applied to files:
pkg/provisioner/source/cmd/delete.gopkg/provisioner/source/cmd/delete_test.go
📚 Learning: 2024-11-07T20:16:15.381Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 766
File: cmd/cmd_utils.go:177-178
Timestamp: 2024-11-07T20:16:15.381Z
Learning: In 'cmd/cmd_utils.go', using `os.Exit(1)` directly is acceptable in this context, and wrapping it with deferred cleanup is considered unnecessary.
Applied to files:
pkg/provisioner/source/cmd/delete.go
📚 Learning: 2026-01-04T00:55:21.720Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.720Z
Learning: Applies to **/*.go : All errors MUST be wrapped using static errors defined in `errors/errors.go` - use `errors.Join` for combining errors, `fmt.Errorf` with `%w` for context, and `errors.Is()` for error checking
Applied to files:
pkg/provisioner/source/cmd/delete.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:
pkg/provisioner/source/cmd/delete.gopkg/provisioner/source/cmd/delete_test.go
📚 Learning: 2025-01-07T20:38:09.618Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 896
File: cmd/editor_config.go:37-40
Timestamp: 2025-01-07T20:38:09.618Z
Learning: Error handling suggestion for `cmd.Help()` in `cmd/editor_config.go` was deferred as the code is planned for future modifications.
Applied to files:
pkg/provisioner/source/cmd/delete.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging
Applied to files:
pkg/provisioner/source/cmd/delete.go
📚 Learning: 2025-02-03T06:00:11.419Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/describe_config.go:20-20
Timestamp: 2025-02-03T06:00:11.419Z
Learning: Commands should use `PrintErrorMarkdownAndExit` with empty title and suggestion (`"", err, ""`) for general error handling. Specific titles like "Invalid Usage" or "File Not Found" should only be used for validation or specific error scenarios.
Applied to files:
pkg/provisioner/source/cmd/delete.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using `fmt.Errorf("context: %w", err)`, and consider using custom error types for domain-specific errors
Applied to files:
pkg/provisioner/source/cmd/delete.go
📚 Learning: 2024-10-21T17:51:53.976Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform.go:114-118
Timestamp: 2024-10-21T17:51:53.976Z
Learning: When `atmos terraform clean --everything` is used without specifying a component and without the `--force` flag, prompt the user for confirmation before deleting all components. Use the `--force` flag to skip the confirmation prompt.
Applied to files:
pkg/provisioner/source/cmd/delete.gowebsite/blog/2026-01-14-source-provisioner-ux.mdxpkg/provisioner/source/cmd/delete_test.gopkg/provisioner/source/cmd/prompt.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:
pkg/provisioner/source/cmd/delete.go
📚 Learning: 2024-10-27T04:54:32.397Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:314-319
Timestamp: 2024-10-27T04:54:32.397Z
Learning: When deleting empty folders in the `deleteFolders` function, handling errors from `os.Remove` are not required, as failures do not affect the process.
Applied to files:
pkg/provisioner/source/cmd/delete.gopkg/provisioner/source/cmd/delete_test.go
📚 Learning: 2026-01-04T00:55:21.720Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.720Z
Learning: PRs labeled `minor` or `major` MUST update `website/src/data/roadmap.js` with shipped milestones, status, changelog link, PR number, and initiative progress percentage
Applied to files:
website/src/data/roadmap.js
📚 Learning: 2026-01-04T00:55:21.720Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.720Z
Learning: Applies to cmd/**/*_test.go : Always use `cmd.NewTestKit(t)` for cmd tests to auto-clean RootCmd state
Applied to files:
tests/cli_source_provisioner_test.gopkg/provisioner/source/cmd/delete_test.gotests/cli_source_provisioner_workdir_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/cli_source_provisioner_test.gopkg/provisioner/source/cmd/delete_test.gotests/cli_source_provisioner_workdir_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:
tests/cli_source_provisioner_test.gopkg/provisioner/source/cmd/delete_test.gotests/cli_source_provisioner_workdir_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Use Viper for managing configuration, environment variables, and flags in CLI commands
Applied to files:
tests/cli_source_provisioner_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:
tests/cli_source_provisioner_test.gopkg/provisioner/source/cmd/delete_test.go
📚 Learning: 2025-12-24T04:29:23.938Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: pkg/ci/terraform/templates/apply.md:17-17
Timestamp: 2025-12-24T04:29:23.938Z
Learning: In the cloudposse/atmos repository, Terraform CI templates (pkg/ci/terraform/templates/*.md) are rendered using TerraformTemplateContext (defined in pkg/ci/terraform/context.go), not the base ci.TemplateContext. TerraformTemplateContext provides top-level fields: .Resources (ci.ResourceCounts), .HasChanges() method, and .HasDestroy field, which are correctly accessed directly in templates without a .Result prefix.
Applied to files:
tests/cli_source_provisioner_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/cli_source_provisioner_test.gopkg/provisioner/source/cmd/delete_test.gotests/cli_source_provisioner_workdir_test.go
📚 Learning: 2026-01-04T00:55:21.720Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T00:55:21.720Z
Learning: Commands MUST use `flags.NewStandardParser()` for command-specific flags and NEVER call `viper.BindEnv()` or `viper.BindPFlag()` directly
Applied to files:
pkg/provisioner/source/cmd/delete_test.go
📚 Learning: 2025-02-18T13:18:53.146Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-18T13:18:53.146Z
Learning: Error checking is not required for cobra.Command.RegisterFlagCompletionFunc calls as these are static configurations done at init time.
Applied to files:
pkg/provisioner/source/cmd/delete_test.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:
pkg/provisioner/source/cmd/delete_test.go
📚 Learning: 2024-11-12T03:16:02.910Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 775
File: internal/exec/template_funcs_component.go:157-159
Timestamp: 2024-11-12T03:16:02.910Z
Learning: In the Go code for `componentFunc` in `internal/exec/template_funcs_component.go`, the function `cleanTerraformWorkspace` does not return errors, and it's acceptable if the file does not exist. Therefore, error handling for `cleanTerraformWorkspace` is not needed.
Applied to files:
pkg/provisioner/source/cmd/delete_test.go
📚 Learning: 2024-10-28T01:51:30.811Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:329-332
Timestamp: 2024-10-28T01:51:30.811Z
Learning: In the Atmos Go code, when deleting directories or handling file paths (e.g., in `terraform_clean.go`), always resolve the absolute path using `filepath.Abs` and use the logger `u.LogWarning` for logging messages instead of using `fmt.Printf`.
Applied to files:
pkg/provisioner/source/cmd/delete_test.go
📚 Learning: 2024-10-27T04:41:49.199Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:215-223
Timestamp: 2024-10-27T04:41:49.199Z
Learning: In `internal/exec/terraform_clean.go`, the function `determineCleanPath` is necessary and should not be removed.
Applied to files:
pkg/provisioner/source/cmd/delete_test.go
📚 Learning: 2024-11-24T19:13:10.287Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:407-416
Timestamp: 2024-11-24T19:13:10.287Z
Learning: In `internal/exec/terraform_clean.go`, when `getStackTerraformStateFolder` returns an error in the `handleCleanSubCommand` function, the error is logged, and the process continues without returning the error.
Applied to files:
pkg/provisioner/source/cmd/delete_test.go
📚 Learning: 2024-11-02T15:35:09.958Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 759
File: internal/exec/terraform.go:366-368
Timestamp: 2024-11-02T15:35:09.958Z
Learning: In `internal/exec/terraform.go`, the workspace cleaning code under both the general execution path and within the `case "init":` block is intentionally duplicated because the code execution paths are different. The `.terraform/environment` file should be deleted before executing `terraform init` in both scenarios to ensure a clean state.
Applied to files:
pkg/provisioner/source/cmd/delete_test.gotests/cli_source_provisioner_workdir_test.go
📚 Learning: 2024-10-27T04:28:40.966Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:155-175
Timestamp: 2024-10-27T04:28:40.966Z
Learning: In the `CollectDirectoryObjects` function in `internal/exec/terraform_clean.go`, recursive search through all subdirectories is not needed.
Applied to files:
pkg/provisioner/source/cmd/delete_test.go
📚 Learning: 2025-12-13T04:37:25.223Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/root.go:0-0
Timestamp: 2025-12-13T04:37:25.223Z
Learning: In Atmos cmd/root.go Execute(), after cfg.InitCliConfig, we must call both toolchainCmd.SetAtmosConfig(&atmosConfig) and toolchain.SetAtmosConfig(&atmosConfig) so the CLI wrapper and the toolchain package receive configuration; missing either can cause nil-pointer panics in toolchain path resolution.
Applied to files:
pkg/provisioner/source/cmd/delete_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests. This is implemented through custom testing framework extensions and is used consistently throughout the test suite.
Applied to files:
pkg/provisioner/source/cmd/delete_test.gotests/cli_source_provisioner_workdir_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests.
Applied to files:
pkg/provisioner/source/cmd/delete_test.gotests/cli_source_provisioner_workdir_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method that can be called on *testing.T objects. This functionality is implemented through custom testing framework extensions and is used consistently throughout the test suite for changing working directories during tests.
Applied to files:
pkg/provisioner/source/cmd/delete_test.gotests/cli_source_provisioner_workdir_test.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:
pkg/provisioner/source/cmd/prompt.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:
tests/cli_source_provisioner_workdir_test.go
🧬 Code graph analysis (8)
pkg/provisioner/source/provision_hook.go (4)
pkg/ui/spinner/spinner.go (1)
ExecWithSpinner(22-64)errors/builder.go (1)
Build(24-37)errors/errors.go (1)
ErrSourceProvision(743-743)pkg/provisioner/source/vendor.go (1)
VendorSource(33-97)
pkg/flags/interactive.go (4)
pkg/perf/perf.go (1)
Track(121-138)internal/tui/templates/term/term_writer.go (1)
IsTTYSupportForStdin(133-135)errors/errors.go (2)
ErrInteractiveNotAvailable(297-297)ErrUserAborted(614-614)internal/tui/utils/utils.go (1)
NewAtmosHuhTheme(166-188)
pkg/provisioner/source/cmd/describe.go (3)
pkg/provisioner/source/cmd/prompt.go (3)
PromptForComponent(21-31)HandlePromptError(53-67)PromptForStack(35-49)errors/errors.go (1)
ErrInvalidPositionalArgs(92-92)pkg/flags/parser.go (1)
GetString(117-126)
pkg/provisioner/source/cmd/pull.go (4)
pkg/provisioner/source/cmd/prompt.go (3)
PromptForComponent(21-31)HandlePromptError(53-67)PromptForStack(35-49)errors/errors.go (2)
ErrInvalidPositionalArgs(92-92)ErrRequiredFlagNotProvided(270-270)pkg/flags/parser.go (2)
GetString(117-126)GetBool(141-150)pkg/flags/global_registry.go (1)
ParseGlobalFlags(33-77)
pkg/provisioner/source/cmd/list.go (1)
pkg/provisioner/source/cmd/prompt.go (2)
PromptForStack(35-49)HandlePromptError(53-67)
pkg/provisioner/source/cmd/delete_test.go (1)
errors/errors.go (2)
ErrRequiredFlagNotProvided(270-270)ErrInteractiveNotAvailable(297-297)
pkg/provisioner/source/cmd/prompt.go (2)
errors/exit_code.go (1)
ExitCodeSIGINT(12-12)pkg/provisioner/source/extract.go (1)
HasSource(147-170)
tests/cli_source_provisioner_workdir_test.go (1)
cmd/root.go (1)
RootCmd(333-515)
⏰ 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 (macos)
- GitHub Check: Acceptance Tests (windows)
- GitHub Check: Acceptance Tests (linux)
- GitHub Check: Summary
🔇 Additional comments (20)
website/src/data/roadmap.js (1)
290-298: Roadmap updates look good.Progress bump from 60 to 83 aligns with the new shipped milestone. The "Source provisioner UX improvements" entry follows the established structure and documents the spinner feedback and interactive confirmation features appropriately.
pkg/provisioner/source/provision_hook.go (1)
125-151: Spinner integration is solid.The refactor wraps vendoring in
spinner.ExecWithSpinnerwith meaningful progress/completion messages. Error handling stays within the callback, and the package handles non-TTY fallback gracefully. Based on learnings, this aligns with providing progress indicators for long-running operations.website/blog/2026-01-14-source-provisioner-ux.mdx (2)
12-69: Documentation is clear and actionable.The before/after examples effectively demonstrate the UX improvements. The "How to Use It" section covers TTY vs non-TTY behavior and the
--forceescape hatch for scripts.
1-6: Blog post tags are valid. Bothenhancementanddxare properly defined inwebsite/blog/tags.yml. Frontmatter is correct.pkg/provisioner/source/cmd/prompt.go (3)
1-17: Imports are well-organized.Follows the three-group pattern: stdlib, third-party, then atmos packages with proper aliases (
errUtils,cfg,log).
51-67: HandlePromptError exit behavior is correct.Calling
errUtils.Exit(errUtils.ExitCodeSIGINT)on user abort matches expected CLI behavior for Ctrl+C-style interrupts.
128-150: Helper functions are clean and focused.Good use of
source.HasSourcefrom the extract package to centralize the source-detection logic. Type assertions are handled defensively.Also applies to: 176-200, 229-252
pkg/provisioner/source/cmd/pull_test.go (1)
29-29: Usage string update is correct.The change from
<component>(required) to[component](optional) accurately reflects the new interactive prompt behavior when component is omitted.pkg/provisioner/source/cmd/list.go (1)
54-69: LGTM — Interactive stack prompting looks solid.The pattern correctly handles the prompt flow: attempt interactive selection, process any prompt errors, then fall back to validation if still empty. The error shadowing in line 59 is intentional Go idiom — HandlePromptError receives the outer
errfrom line 58.pkg/provisioner/source/cmd/describe_test.go (1)
25-25: LGTM.Usage string correctly updated to reflect optional component argument.
pkg/flags/interactive.go (1)
196-241: Solid implementation for destructive action confirmation.Good use of huh for the prompt per project conventions. The behavioral difference from other prompts (returning
ErrInteractiveNotAvailablevs empty string) is appropriate here — destructive actions should fail-safe rather than silently skip confirmation.One consideration: this checks only
IsTTYSupportForStdin(), whileisInteractive()also checksviper.GetBool("interactive")and!telemetry.IsCI(). If the--interactive=falseflag should also disable this confirmation, you'd want to incorporate that check. However, for destructive actions, requiring explicit--forcein CI/non-interactive environments is likely the safer design.tests/cli_source_provisioner_workdir_test.go (1)
87-105: Test setup and assertions look good.Creating the target directory before delete and cleaning up after is the right approach. The expanded assertion correctly handles both
--forcerequirement and interactive mode unavailability.tests/cli_source_provisioner_test.go (1)
86-103: Test improvements are well-structured.The Viper reset prevents flaky tests from flag leakage. Creating the target directory ensures the delete command has a real path to evaluate. Cleanup via
t.Cleanupis the right pattern.pkg/provisioner/source/cmd/describe.go (1)
22-50: LGTM on command structure updates.The shift to
RangeArgs(0, 1)with updated help text and examples clearly documents the interactive behavior. Well done.pkg/provisioner/source/cmd/pull.go (1)
105-110: LGTM on CommonOptions construction.Global flags parsed properly, and the Force/Identity flags are correctly extracted from Viper.
pkg/provisioner/source/cmd/delete_test.go (3)
48-67: Good addition: Force default test.Validates the expected behavior when
--forceis omitted.
243-300: Solid non-TTY test coverage.Tests the interactive path gracefully degrades with
ErrInteractiveNotAvailablein non-TTY environments. This aligns with the PR objectives.
108-113: LGTM on force parameter additions.Using
force=truein tests to skip interactive prompts is the right approach for unit test isolation.Also applies to: 140-141, 353-354
pkg/provisioner/source/cmd/delete.go (2)
191-202: Nice: Interactive confirmation with graceful degradation.Good UX—warns the user about
--forcewhen non-interactive mode isn't available. This aligns with learned preferences for confirmation prompts. Based on learnings, using a confirmation prompt before destructive operations is the expected pattern.
204-217: Good: Spinner feedback during deletion.Provides visual feedback for long-running operations as per coding guidelines and PR objectives.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
Add comprehensive tests to improve coverage from 33% to 80%+ target: - prompt.go: Add DI function variables for testability, test pure functions (stackHasAnySource, stackContainsComponentWithSource, collectComponentsWithSource) and config-loading functions with mocks - provision_hook_test.go: Add tests for needsProvisioning and AutoProvisionSource - interactive_test.go: Add tests for PromptForConfirmation force and non-TTY paths Coverage improvements: - pkg/provisioner/source: 84.1% - pkg/provisioner/source/cmd: 84.1% - pkg/flags: 79.2% Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
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. |
Fix 6 critical variable shadowing bugs identified by CodeRabbit where
`err` was being shadowed in prompt error handling blocks. The pattern:
```go
var err error
value, err = PromptFunc(cmd)
if err := HandlePromptError(err, "name"); err != nil {
```
Was causing the original `err` to be shadowed by the `if` statement's
short variable declaration. This could lead to prompt errors being
silently ignored.
Fixed by renaming the prompt result variable to `promptErr` to avoid
shadowing in all affected locations:
- delete.go: component prompt and stack prompt in parseDeleteFlags
- describe.go: component prompt and stack prompt
- pull.go: component prompt and stack prompt
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
These changes were released in v1.204.0-rc.5. |
what
vendorToTarget()PromptForConfirmation()topkg/flags/interactive.gofor reusable destructive action confirmation prompts--forceflagwhy
These changes improve UX consistency across the CLI by providing:
references
Related to source provisioner improvements for better developer experience with JIT vendoring.
Summary by CodeRabbit
New Features
Tests
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.