Skip to content

feat: register terraform compound subcommands in Cobra command tree#2044

Merged
aknysh merged 2 commits intomainfrom
aknysh/fix-issues-6
Jan 31, 2026
Merged

feat: register terraform compound subcommands in Cobra command tree#2044
aknysh merged 2 commits intomainfrom
aknysh/fix-issues-6

Conversation

@aknysh
Copy link
Member

@aknysh aknysh commented Jan 30, 2026

what

  • Register terraform compound subcommands (state, providers, workspace) as proper Cobra child commands
  • Register per-subcommand compat flags for all 15 compound terraform subcommands
  • Add dedicated documentation pages for all compound subcommands with detailed "Native Terraform Flags" sections
  • Update screengrabs for all CLI commands
  • Fix quoted compound terraform subcommands like "providers lock"
  • Add compound subcommand argument parsing (parseCompoundSubcommand, processTerraformCompoundSubcommand)
  • Add website documentation updates (templates defaults, stores, hooks)

why

Terraform compound subcommands registered in Cobra command tree (#2018)

Previously, compound terraform subcommands (state list, providers lock, workspace select, etc.) were handled entirely by argument parsing in processArgsAndFlags. This had several limitations:

  • Tab completion didn't work for subcommands
  • Help text didn't show subcommands with [command] suffix
  • Quoted forms like "providers lock" weren't supported

Fix (Part 1 — argument parsing): Added modular helper functions (parseCompoundSubcommand, parseQuotedCompoundSubcommand, parseSeparateCompoundSubcommand, processTerraformCompoundSubcommand) with configurable subcommand lists for workspace, state, providers, and write commands. Supports both quoted ("providers lock") and separate (providers lock) forms.

Fix (Part 2 — Cobra command tree registration): Registered compound subcommands as proper Cobra child commands:

  • cmd/terraform/state.golist, mv, pull, push, replace-provider, rm, show as children of stateCmd
  • cmd/terraform/providers.golock, mirror, schema as children of providersCmd
  • cmd/terraform/workspace.golist, select, new, delete, show as children of workspaceCmd
  • cmd/terraform/utils.gonewTerraformPassthroughSubcommand() helper creates Cobra child commands that delegate to the parent command's execution flow

The legacy compound subcommand parsing in processArgsAndFlags is retained as a fallback for the interactive UI path (which bypasses Cobra) and backward compatibility.

Files: internal/exec/cli_utils.go, internal/exec/cli_utils_test.go, cmd/terraform/utils.go, cmd/terraform/state.go, cmd/terraform/providers.go, cmd/terraform/workspace.go, cmd/terraform/subcommands_test.go

Per-subcommand compat flags for compound terraform subcommands

Added per-subcommand compat flag definitions for all 15 compound terraform subcommands, registered them with the command registry, and documented them in the website docs.

Compat flags registered per subcommand:

Subcommand Native Terraform Flags
state list -state, -id
state mv -lock, -lock-timeout, -ignore-remote-version
state pull (none)
state push -force, -lock, -lock-timeout, -ignore-remote-version
state replace-provider -auto-approve, -lock, -lock-timeout, -ignore-remote-version
state rm -lock, -lock-timeout, -ignore-remote-version
state show -state
providers lock -platform, -fs-mirror, -net-mirror, -enable-plugin-cache
providers mirror -platform
providers schema -json
workspace list (none)
workspace select -or-create
workspace new -lock, -lock-timeout, -state
workspace delete -force, -lock, -lock-timeout
workspace show (none)

Note: Terraform's -dry-run on state mv/state rm is intentionally excluded to avoid conflict with Atmos's --dry-run flag.

Files: cmd/terraform/compat_flags.go, cmd/terraform/state.go, cmd/terraform/providers.go, cmd/terraform/workspace.go, cmd/terraform/subcommands_test.go

Website documentation for compound subcommands

Added dedicated documentation pages for 15 terraform compound subcommands across 3 command families, each with detailed "Native Terraform Flags" sections documenting all supported terraform flags per subcommand:

  • providers/lock, mirror, schema
  • state/list, mv, pull, push, replace-provider, rm, show
  • workspace/list, select, new, delete, show

Each page follows the existing documentation pattern with frontmatter, Intro component, Screengrab, Usage, Examples, Arguments, Flags, Native Terraform Flags, and See Also sections.

Updated screengrabs

Regenerated all CLI command screengrabs to reflect current help text including the new compound subcommand [command] suffixes.

references

Register compound terraform subcommands (state, providers, workspace) as proper
Cobra child commands with dedicated documentation pages and updated screengrabs.

- Add cmd/terraform/{state,providers,workspace}.go with child subcommands
- Add cmd/terraform/utils.go with newTerraformPassthroughSubcommand helper
- Add compound subcommand parsing (parseCompoundSubcommand, processTerraformCompoundSubcommand)
- Add website documentation for all providers/state/workspace subcommands
- Update screengrabs for all CLI commands
- Add blog posts for chdir config isolation and artifactory store fix

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@aknysh aknysh requested a review from a team as a code owner January 30, 2026 20:52
@github-actions github-actions bot added the size/xl Extra large size PR label Jan 30, 2026
@mergify
Copy link

mergify bot commented Jan 30, 2026

Warning

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

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

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

@mergify
Copy link

mergify bot commented Jan 30, 2026

Important

Cloud Posse Engineering Team Review Required

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

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

@mergify mergify bot added the needs-cloudposse Needs Cloud Posse assistance label Jan 30, 2026
@github-actions
Copy link

github-actions bot commented Jan 30, 2026

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@codecov
Copy link

codecov bot commented Jan 30, 2026

Codecov Report

❌ Patch coverage is 93.02326% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.63%. Comparing base (d72e3e8) to head (4a89271).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
cmd/terraform/workspace.go 55.00% 8 Missing and 1 partial ⚠️
cmd/terraform/utils.go 63.63% 3 Missing and 1 partial ⚠️
internal/exec/cli_utils.go 97.72% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2044      +/-   ##
==========================================
+ Coverage   75.54%   75.63%   +0.09%     
==========================================
  Files         793      793              
  Lines       73718    73888     +170     
==========================================
+ Hits        55692    55887     +195     
+ Misses      14530    14514      -16     
+ Partials     3496     3487       -9     
Flag Coverage Δ
unittests 75.63% <93.02%> (+0.09%) ⬆️

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

Files with missing lines Coverage Δ
cmd/terraform/compat_flags.go 100.00% <100.00%> (ø)
cmd/terraform/providers.go 70.00% <100.00%> (+12.85%) ⬆️
cmd/terraform/state.go 70.00% <100.00%> (+12.85%) ⬆️
internal/exec/cli_utils.go 80.99% <97.72%> (+8.49%) ⬆️
cmd/terraform/utils.go 50.42% <63.63%> (+0.65%) ⬆️
cmd/terraform/workspace.go 48.64% <55.00%> (+4.20%) ⬆️

... 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.

@aknysh aknysh self-assigned this Jan 30, 2026
@aknysh aknysh added the patch A minor, backward compatible change label Jan 30, 2026
…commands

Add per-subcommand compat flag definitions for all 15 compound terraform
subcommands (state/providers/workspace families), register them with the
command registry, add comprehensive tests, and update website docs with
detailed "Native Terraform Flags" sections.

Compat flags added:
- state list: -state, -id
- state mv: -lock, -lock-timeout, -ignore-remote-version
- state pull: (none)
- state push: -force, -lock, -lock-timeout, -ignore-remote-version
- state replace-provider: -auto-approve, -lock, -lock-timeout, -ignore-remote-version
- state rm: -lock, -lock-timeout, -ignore-remote-version
- state show: -state
- providers lock: -platform, -fs-mirror, -net-mirror, -enable-plugin-cache
- providers mirror: -platform
- providers schema: -json
- workspace list: (none)
- workspace select: -or-create
- workspace new: -lock, -lock-timeout, -state
- workspace delete: -force, -lock, -lock-timeout
- workspace show: (none)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@aknysh
Copy link
Member Author

aknysh commented Jan 31, 2026

@coderabbitai full review please

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 31, 2026

@aknysh: I'll conduct a full review of the PR.


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

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

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

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

Learnt from: 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`.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.

Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 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: osterman
Repo: cloudposse/atmos PR: 1813
File: cmd/terraform/shell.go:28-73
Timestamp: 2025-12-13T03:21:35.786Z
Learning: In Atmos, when calling cfg.InitCliConfig, you must first populate the schema.ConfigAndStacksInfo struct with global flag values using flags.ParseGlobalFlags(cmd, v) rather than passing an empty struct. The LoadConfig function (pkg/config/load.go) reads config selection fields (AtmosConfigFilesFromArg, AtmosConfigDirsFromArg, BasePath, ProfilesFromArg) directly from the ConfigAndStacksInfo struct, NOT from Viper. Passing an empty struct causes config selection flags (--base-path, --config, --config-path, --profile) to be silently ignored. Correct pattern: parse flags → populate struct → call InitCliConfig. See cmd/terraform/plan_diff.go for reference implementation.

Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under `cmd/` directory

Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-23T21:56:19.037Z
Learning: Applies to website/docs/cli/commands/**/*.mdx : All new CLI commands MUST have Docusaurus documentation in `website/docs/cli/commands/<command>/<subcommand>.mdx` with frontmatter, Intro component, Screengrab, Usage section, Arguments/Flags (using <dl>), and Examples
✅ Actions performed

Full review triggered.

@aknysh aknysh requested a review from osterman January 31, 2026 19:19
@aknysh aknysh merged commit 4d6767d into main Jan 31, 2026
58 checks passed
@aknysh aknysh deleted the aknysh/fix-issues-6 branch January 31, 2026 22:17
@mergify mergify bot removed the needs-cloudposse Needs Cloud Posse assistance label Jan 31, 2026
@github-actions
Copy link

github-actions bot commented Feb 1, 2026

These changes were released in v1.205.1-rc.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch A minor, backward compatible change size/xl Extra large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can't run terrafrom providers lock CMD in atmos

2 participants