Skip to content

Conversation

aknysh
Copy link
Member

@aknysh aknysh commented Aug 23, 2025

what

  • Update atmos describe affected and atmos describe dependents commands
  • Update docs
  • Add tests

why

  • atmos describe affected --include dependents should respect the flags --process-templates and --process-functions in the dependent components

    • atmos describe affected --include dependents will process templates and YAML functions in the affected components and in the dependents

    • atmos describe affected --include dependents --process-templates=false --process-functions=false will not process templates and YAML functions in the affected components and in the dependents for each affected component

  • Add --exclude-locked flag to atmos describe affected

  • Add --process-templates and --process-functions flags to atmos describe dependents to explicitly disable templates and YAML functions processing (similar to atmos describe affected)

    • atmos describe dependents will process templates and YAML functions in all components
    • atmos describe dependents --process-templates=false --process-functions=false will not process templates and YAML functions in all components

Summary by CodeRabbit

  • New Features

    • describe affected: added --exclude-locked; describe dependents: added --process-templates, --process-functions, --skip and --include-settings; deterministic sorting of dependents.
  • Workflows

    • Improved describe workflows command help, parsing and format/output validation; execution modularized.
  • Schema

    • depends_on may include an optional stack field.
  • Documentation

    • Updated CLI docs and examples to show new flags and optional-flag semantics.
  • Chores

    • Bumped example Atmos version to 1.188.0 and upgraded dependencies.
  • Tests

    • Added fixtures and tests covering affected/dependents scenarios and new flags.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
website/docs/troubleshoot/errors.mdx (4)

101-103: Fix wording and double period

Tighten the lead sentence and remove the trailing double period.

-The Terraform/OpenTofu error means Terraform noticed that your backend configuration (the section in your code that
-defines where and how Terraform stores state) has changed compared to what’s currently in use..
+This Terraform/OpenTofu error indicates that Terraform detected a change in your backend configuration (where and how Terraform stores state) compared to the currently configured backend.

109-114: Make list items parallel; move consequence out of the list; capitalize S3

The last bullet is not a cause; it’s the outcome. Also fix capitalization and phrasing.

-- Switching from local to s3
+- Switching from local to S3
 - Changing the bucket, key, or region for an S3 backend
-- Modifying a prefix or workspace config in Terraform Cloud
+- Modifying a prefix or workspace configuration in Terraform Cloud
 - Adjusting encryption or locking settings
-- Terraform detects that the state might need to be migrated from the old backend to the new one.
+
+When any of the above change, Terraform may need to migrate state from the old backend to the new one.

139-142: Clarify behavior; add a caution about skipping migration; tweak tone

“tell Atmos” → “configures Atmos”. Add an admonition warning that -reconfigure skips migration, which can orphan state if used unintentionally. Include a short runnable example.

-This will tell Atmos to run `terraform init -reconfigure` when executing Terraform commands.
-The `-reconfigure` option disregards any existing backend configuration and configures a new backend,
-preventing migration of any existing state.
+This configures Atmos to run `terraform init -reconfigure` when executing Terraform commands.
+The `-reconfigure` option disregards any existing backend configuration and configures a new backend,
+preventing migration of any existing state.
+
+:::caution
+Only use `-reconfigure` when you intentionally changed backends and do not want to migrate existing state.
+If you need to preserve state, follow Terraform's interactive migration prompt and answer "yes" to copy state.
+:::
+
+#### Example
+
+```console
+$ atmos terraform init -s <stack> -w <component>
+# or explicitly:
+$ atmos terraform init -s <stack> -w <component> --init-run-reconfigure
+```

130-137: All clear—flag and ENV var names are correct

I’ve verified that the ENV var and CLI flag are consistently defined and used across the codebase:

  • The environment variable ATMOS_COMPONENTS_TERRAFORM_INIT_RUN_RECONFIGURE is read in pkg/config/utils.go (around lines 256–260).
  • The CLI flag --init-run-reconfigure is implemented in the Terraform init logic (e.g. internal/exec/terraform_output_utils.go) and appears in all relevant docs (e.g. website/docs/troubleshoot/errors.mdx).

As an optional enhancement to improve usability, I recommend surfacing these alternative settings in the prose rather than only as YAML comments. For example, in website/docs/troubleshoot/errors.mdx (after the code block at lines 130–137), add a sentence like:

“You can also enable this behavior by setting the ATMOS_COMPONENTS_TERRAFORM_INIT_RUN_RECONFIGURE environment variable or by passing the --init-run-reconfigure flag to the Atmos CLI.”

You might:

  • Add the above sentence immediately below the existing snippet in website/docs/troubleshoot/errors.mdx.
  • Consider using a markdown callout/admonition to highlight the flag and ENV var for easier copy/paste.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • 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 8d124d6 and 270df4e.

📒 Files selected for processing (1)
  • website/docs/troubleshoot/errors.mdx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
website/**

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

website/**: Update website documentation in the website/ directory when adding new features
Follow the website's documentation structure and style
Keep website code in the website/ directory
Follow the existing website architecture and style
Document new features on the website
Include examples and use cases in website documentation

Files:

  • website/docs/troubleshoot/errors.mdx
🧠 Learnings (1)
📓 Common learnings
Learnt from: Listener430
PR: cloudposse/atmos#934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: CR
PR: cloudposse/atmos#0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-07-01T02:22:25.901Z
Learning: Clearly describe the changes in the PR description
Learnt from: aknysh
PR: cloudposse/atmos#944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
🪛 LanguageTool
website/docs/troubleshoot/errors.mdx

[grammar] ~101-~101: There might be a mistake here.
Context: ...iguration (the section in your code that defines where and how Terraform stores s...

(QB_NEW_EN)


[grammar] ~110-~110: There might be a mistake here.
Context: ...bucket, key, or region for an S3 backend - Modifying a prefix or workspace config i...

(QB_NEW_EN)


[grammar] ~111-~111: There might be a mistake here.
Context: ...x or workspace config in Terraform Cloud - Adjusting encryption or locking settings...

(QB_NEW_EN)


[grammar] ~112-~112: There might be a mistake here.
Context: ...Adjusting encryption or locking settings - Terraform detects that the state might n...

(QB_NEW_EN)


[grammar] ~117-~117: There might be a mistake here.
Context: ...e — it prompts you to confirm migration. Typically, you’ll see a message like: `...

(QB_NEW_EN)


[style] ~139-~139: Consider using the more polite verb “ask” (“tell” implies ordering/instructing someone).
Context: ...it_run_reconfigure: true ``` This will tell Atmos to run `terraform init -reconfigu...

(TELL_ASK)


[grammar] ~140-~140: There might be a mistake here.
Context: ...figuration and configures a new backend, preventing migration of any existing sta...

(QB_NEW_EN)


[grammar] ~147-~147: There might be a mistake here.
Context: ..., refer to: - terraform init command - [Terraform Backend Initialization](https:...

(QB_NEW_EN)


[grammar] ~148-~148: There might be a mistake here.
Context: ...nit) - Terraform Backend Initialization - [Atmos CLI configuration](/cli/configurat...

(QB_NEW_EN)


[grammar] ~149-~149: There might be a mistake here.
Context: ...itialization) - Atmos CLI configuration - [Atmos Terraform/OpenTofu commands](/cli/...

(QB_NEW_EN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Build (ubuntu-latest, linux)
  • GitHub Check: Analyze (go)
  • GitHub Check: Lint (golangci)
  • GitHub Check: website-deploy-preview
  • GitHub Check: Summary
🔇 Additional comments (1)
website/docs/troubleshoot/errors.mdx (1)

95-153: No duplicate section—console snippet is intentional

The second occurrence of “A change in the backend configuration has been detected, which may require migrating existing state” appears as part of the console output example, not as a duplicated heading or section. You can safely ignore the suggestion to remove it.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (2)
website/docs/core-concepts/components/terraform/backends.mdx (2)

296-305: Fix backend key: “gcp” → “gcs” for Google Cloud Storage examples

The docs consistently refer to the backend as “gcs”, but the example YAML/JSON blocks use “gcp”. This will mislead users to configure the wrong key.

Apply this diff:

@@
-      backend:
-        gcp:
-          prefix: "my-component"
+      backend:
+        gcs:
+          prefix: "my-component"
@@
-      "gcp": {
+      "gcs": {
         "bucket": "tf-state",
         "prefix": "my-component"
       }

Also applies to: 318-323


52-55: Correct contradiction about local backend locking

Above, Line 47 states the local backend “locks that state using system APIs,” but this bullet says it lacks locking. The issue is not the absence of locks, but that locking is local-only and not shared across machines.

Apply this wording tweak:

-- **No Concurrency and Locking**: Local backend lacks locking, leading to race conditions when multiple users modify the state.
+- **Local-only locking**: The local backend uses OS file locks on a single host and does not provide shared locking across machines, so concurrent runs across users can still race.
♻️ Duplicate comments (1)
website/docs/troubleshoot/errors.mdx (1)

147-151: Verify internal link to CLI configuration exists

Past review flagged this link as broken when it was /cli/configuration/#configuration. It’s now /cli/configuration/, but we still need to ensure the target file exists.

Run from repo root:

#!/bin/bash
set -euo pipefail

# Check configuration page presence
echo "Looking for CLI configuration page..."
if find website/docs/cli -maxdepth 1 -type f \( -name 'configuration.md' -o -name 'configuration.mdx' \) | grep -q .; then
  echo "  ✓ Found:"
  find website/docs/cli -maxdepth 1 -type f \( -name 'configuration.md' -o -name 'configuration.mdx' \) | sed 's|^|    |'
else
  echo "  ✗ Missing website/docs/cli/configuration.md(x). Consider updating the link or adding the page."
fi

# Sanity-check referenced describe pages
echo ""
echo "Checking describe pages..."
for p in website/docs/cli/commands/describe/affected.mdx website/docs/cli/commands/describe/dependents.mdx; do
  [[ -f "$p" ]] && echo "  ✓ Found $p" || echo "  ✗ Missing $p"
done
🧹 Nitpick comments (5)
website/docs/core-concepts/stacks/define-components.mdx (1)

221-223: Tighten the disambiguation: explicitly call out precedence and execution behavior.

Good clarification. Minor wording tweak will make the difference unambiguous and avoid readers assuming vars.enabled affects Atmos execution.

Apply this diff to strengthen the note:

-This should not be confused with [Cloud Posse's conventions and best practices](/best-practices/terraform/) of
-having modules and components define a Terraform input named `enabled`.
-This is a general convention and `vars.enabled` is not a special variable. Atmos does not treat it differently from any other variable.
+This should not be confused with [Cloud Posse's conventions and best practices](/best-practices/terraform/) of
+having modules and components define a Terraform input named `enabled`.
+That module input is a general convention and may be surfaced in stacks as `vars.enabled`, but it does not change whether Atmos executes or renders the component.
+Only `metadata.enabled` controls Atmos processing. Atmos treats `vars.enabled` like any other variable.

Optional example to drive it home—want me to add this right below the note?

components:
  terraform:
    vpc:
      metadata:
        enabled: true        # Atmos will process and run terraform for this component
      vars:
        enabled: false       # Module-specific semantics (e.g., count = 0); Atmos still runs terraform
website/docs/troubleshoot/errors.mdx (3)

101-103: Tighten wording + fix double period

Rephrase for clarity and remove the trailing double period.

-The Terraform/OpenTofu error means Terraform noticed that your backend configuration (the section in your code that
-defines where and how Terraform stores state) has changed compared to what’s currently in use..
+This Terraform/OpenTofu error indicates that your backend configuration (the section in your code that
+defines where and how Terraform stores state) differs from what’s currently in use.

109-114: Restructure bullets; move non-example sentence out of the list

The last bullet is not an example; it’s an effect. Move it below the list and keep examples as bullets.

 - Switching from local to s3
 - Changing the bucket, key, or region for an S3 backend
 - Modifying a prefix or workspace config in Terraform Cloud
 - Adjusting encryption or locking settings
-- Terraform detects that the state might need to be migrated from the old backend to the new one.
+
+When any of the above changes, Terraform detects that the state might need to be migrated from the old backend to the new one.

145-151: Consider adding OpenTofu docs link

You reference Terraform docs; consider adding a link to the OpenTofu init docs alongside for parity.

I can propose exact wording once you confirm the preferred OpenTofu reference.

website/docs/core-concepts/components/terraform/backends.mdx (1)

12-14: Minor grammar: plural subject should use “their”

Terraform and OpenTofu are two subjects; prefer “their state.”

-Backends define where [Terraform](https://opentofu.org/docs/language/state/) and
-[OpenTofu](https://opentofu.org/docs/language/state/) store its state.
+Backends define where [Terraform](https://opentofu.org/docs/language/state/) and
+[OpenTofu](https://opentofu.org/docs/language/state/) store their state.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • 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 270df4e and 148e27d.

📒 Files selected for processing (10)
  • website/docs/core-concepts/components/terraform/backends.mdx (4 hunks)
  • website/docs/core-concepts/stacks/define-components.mdx (1 hunks)
  • website/docs/core-concepts/stacks/inheritance/inheritance.mdx (1 hunks)
  • website/docs/core-concepts/stacks/templates/functions/atmos.Component.mdx (1 hunks)
  • website/docs/core-concepts/stacks/templates/functions/atmos.Store.mdx (1 hunks)
  • website/docs/core-concepts/stacks/templates/templates.mdx (1 hunks)
  • website/docs/core-concepts/stacks/yaml-functions/store.mdx (1 hunks)
  • website/docs/core-concepts/stacks/yaml-functions/terraform.output.mdx (1 hunks)
  • website/docs/core-concepts/stacks/yaml-functions/terraform.state.mdx (1 hunks)
  • website/docs/troubleshoot/errors.mdx (1 hunks)
✅ Files skipped from review due to trivial changes (7)
  • website/docs/core-concepts/stacks/templates/functions/atmos.Store.mdx
  • website/docs/core-concepts/stacks/inheritance/inheritance.mdx
  • website/docs/core-concepts/stacks/templates/functions/atmos.Component.mdx
  • website/docs/core-concepts/stacks/templates/templates.mdx
  • website/docs/core-concepts/stacks/yaml-functions/store.mdx
  • website/docs/core-concepts/stacks/yaml-functions/terraform.output.mdx
  • website/docs/core-concepts/stacks/yaml-functions/terraform.state.mdx
🧰 Additional context used
📓 Path-based instructions (1)
website/**

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

website/**: Update website documentation in the website/ directory when adding new features
Follow the website's documentation structure and style
Keep website code in the website/ directory
Follow the existing website architecture and style
Document new features on the website
Include examples and use cases in website documentation

Files:

  • website/docs/core-concepts/stacks/define-components.mdx
  • website/docs/core-concepts/components/terraform/backends.mdx
  • website/docs/troubleshoot/errors.mdx
🧠 Learnings (2)
📓 Common learnings
Learnt from: Listener430
PR: cloudposse/atmos#934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: CR
PR: cloudposse/atmos#0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-07-01T02:22:25.901Z
Learning: Clearly describe the changes in the PR description
Learnt from: aknysh
PR: cloudposse/atmos#944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
📚 Learning: 2025-01-16T11:41:35.531Z
Learnt from: osterman
PR: cloudposse/atmos#942
File: internal/exec/describe_affected_utils.go:802-807
Timestamp: 2025-01-16T11:41:35.531Z
Learning: When checking if a component is enabled in Atmos, use standardized helper function that includes logging. The function should check the `enabled` field in the component's metadata section and log a trace message when skipping disabled components.

Applied to files:

  • website/docs/core-concepts/stacks/define-components.mdx
🪛 LanguageTool
website/docs/core-concepts/components/terraform/backends.mdx

[grammar] ~182-~182: There might be a mistake here.
Context: ... will deep-merge the backend configurations from the `_de...

(QB_NEW_EN)


[grammar] ~252-~252: There might be a mistake here.
Context: ... from the _defaults.yaml manifests and from the component itself, and will gene...

(QB_NEW_EN)


[grammar] ~311-~311: There might be a mistake here.
Context: ... from the _defaults.yaml manifests and from the component itself, and will gene...

(QB_NEW_EN)


[grammar] ~367-~367: There might be a mistake here.
Context: ... from the _defaults.yaml manifests and from the component itself, and will gene...

(QB_NEW_EN)

website/docs/troubleshoot/errors.mdx

[grammar] ~101-~101: There might be a mistake here.
Context: ...iguration (the section in your code that defines where and how Terraform stores s...

(QB_NEW_EN)


[grammar] ~110-~110: There might be a mistake here.
Context: ...bucket, key, or region for an S3 backend - Modifying a prefix or workspace config i...

(QB_NEW_EN)


[grammar] ~111-~111: There might be a mistake here.
Context: ...x or workspace config in Terraform Cloud - Adjusting encryption or locking settings...

(QB_NEW_EN)


[grammar] ~112-~112: There might be a mistake here.
Context: ...Adjusting encryption or locking settings - Terraform detects that the state might n...

(QB_NEW_EN)


[grammar] ~117-~117: There might be a mistake here.
Context: ...e — it prompts you to confirm migration. Typically, you’ll see a message like: `...

(QB_NEW_EN)


[style] ~139-~139: Consider using the more polite verb “ask” (“tell” implies ordering/instructing someone).
Context: ...it_run_reconfigure: true ``` This will tell Atmos to run `terraform init -reconfigu...

(TELL_ASK)


[grammar] ~140-~140: There might be a mistake here.
Context: ...figuration and configures a new backend, preventing migration of any existing sta...

(QB_NEW_EN)


[grammar] ~147-~147: There might be a mistake here.
Context: ..., refer to: - terraform init command - [Terraform Backend Initialization](https:...

(QB_NEW_EN)


[grammar] ~148-~148: There might be a mistake here.
Context: ...nit) - Terraform Backend Initialization - [Atmos CLI configuration](/cli/configurat...

(QB_NEW_EN)


[grammar] ~149-~149: There might be a mistake here.
Context: ...itialization) - Atmos CLI configuration - [Atmos Terraform/OpenTofu commands](/cli/...

(QB_NEW_EN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Build (macos-latest, macos)
  • GitHub Check: Build (ubuntu-latest, linux)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Analyze (go)
  • GitHub Check: Lint (golangci)
  • GitHub Check: website-deploy-preview
  • GitHub Check: Summary
🔇 Additional comments (1)
website/docs/core-concepts/components/terraform/backends.mdx (1)

182-184: All old anchors have been updated and no lingering #terraform-backend-inheritance references remain.
Great work catching the stray “-or” fix and updating the deep-merge links to point at #backend-inheritance. No further edits needed here—this is good to merge.

coderabbitai[bot]
coderabbitai bot previously approved these changes Aug 24, 2025
osterman
osterman previously approved these changes Aug 24, 2025
@aknysh aknysh dismissed stale reviews from osterman and coderabbitai[bot] via 69e15ce August 24, 2025 18:37
coderabbitai[bot]
coderabbitai bot previously approved these changes Aug 24, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (12)
cmd/describe_affected_test.go (6)

60-66: Clarify the coupling between --upload and include flags

The expectation that Upload: true implies IncludeDependents: true and IncludeSettings: true is fine if intentional. If this coupling is incidental (or will change), consider documenting it in the test to avoid future brittleness.


97-116: Add the --exclude-locked flag to the test FlagSet

To keep this unit test in parity with the CLI and the PR objective, wire the new flag into the local FlagSet so SetDescribeAffectedFlagValueInCliArgs can populate it.

 fs.Bool("include-settings", false, "Include settings")
 fs.Bool("upload", false, "Upload")
 fs.String("clone-target-ref", "", "Clone target ref")
+fs.Bool("exclude-locked", false, "Exclude components with metadata.locked: true")
 fs.Bool("process-templates", false, "Process templates")
 fs.Bool("process-functions", false, "Process YAML functions")
 fs.Bool("skip", false, "Skip")

28-90: Expand table tests: explicitly disabled processing and exclude-locked

Add two cases to cover key paths:

  • When users explicitly set --process-templates=false and --process-functions=false, args should reflect false.
  • When users set --exclude-locked=true, args should reflect true (assuming DescribeAffectedCmdArgs has ExcludeLocked).
   tests := []struct {
     name          string
     setFlags      func(*pflag.FlagSet)
     expected      *exec.DescribeAffectedCmdArgs
     expectedPanic bool
     panicMessage  string
   }{
@@
     {
       name: "Set format explicitly, no override",
       setFlags: func(fs *pflag.FlagSet) {
         fs.Set("format", "json")
       },
       expected: &exec.DescribeAffectedCmdArgs{
         Format:               "json",
         ProcessTemplates:     true,
         ProcessYamlFunctions: true,
       },
     },
+    {
+      name: "Explicitly disable processing flags",
+      setFlags: func(fs *pflag.FlagSet) {
+        fs.Set("process-templates", "false") // mark as changed
+        fs.Set("process-functions", "false") // mark as changed
+      },
+      expected: &exec.DescribeAffectedCmdArgs{
+        Format:               "json",
+        ProcessTemplates:     false,
+        ProcessYamlFunctions: false,
+      },
+    },
+    {
+      name: "Exclude locked components",
+      setFlags: func(fs *pflag.FlagSet) {
+        fs.Set("exclude-locked", "true")
+      },
+      expected: &exec.DescribeAffectedCmdArgs{
+        Format:               "json",
+        ProcessTemplates:     true,
+        ProcessYamlFunctions: true,
+        ExcludeLocked:        true,
+      },
+    },
   }

If ExcludeLocked is modeled elsewhere, we can tailor the assertion accordingly.


20-26: Assert that defaults actually reach the executor

Strengthen the mock to validate ProcessTemplates/ProcessYamlFunctions are true at the boundary.

-describeAffectedMock.EXPECT().Execute(gomock.Any()).Return(nil)
+describeAffectedMock.EXPECT().
+  Execute(gomock.AssignableToTypeOf(&exec.DescribeAffectedCmdArgs{})).
+  DoAndReturn(func(args *exec.DescribeAffectedCmdArgs) error {
+    assert.True(t, args.ProcessTemplates, "ProcessTemplates should default to true")
+    assert.True(t, args.ProcessYamlFunctions, "ProcessYamlFunctions should default to true")
+    return nil
+  })

145-161: Prefer t.Setenv over os.Setenv + manual cleanup

Use testing.T’s helpers for cleaner setup/teardown.

-err := os.Setenv("ATMOS_CLI_CONFIG_PATH", stacksPath)
-assert.NoError(t, err, "Setting 'ATMOS_CLI_CONFIG_PATH' environment variable should execute without error")
-
-err = os.Setenv("ATMOS_BASE_PATH", stacksPath)
-assert.NoError(t, err, "Setting 'ATMOS_BASE_PATH' environment variable should execute without error")
-
-// Unset ENV variables after testing
-defer func() {
-  os.Unsetenv("ATMOS_CLI_CONFIG_PATH")
-  os.Unsetenv("ATMOS_BASE_PATH")
-}()
+t.Setenv("ATMOS_CLI_CONFIG_PATH", stacksPath)
+t.Setenv("ATMOS_BASE_PATH", stacksPath)

121-131: Remove unused panic harness or add a case that exercises it

No table entry sets expectedPanic. Either delete this block to reduce noise or add a negative test that triggers the panic path.

cmd/describe_dependents_test.go (6)

58-61: Default mismatch: test expects JSON, flag help says YAML.

The test expects Format: "json" when no flags change, but the flag is declared with default "yaml" and the help mentions YAML default. This is confusing and brittle.

  • Either the CLI default is JSON (preferred per PR objectives), in which case update the flag definition/help here to "json".
  • Or the CLI default is YAML, in which case update the expectation.

Suggested fix (align test flag with JSON default):

-      fs.StringP("format", "f", "yaml", "Specify the output format (`yaml` is default)")
+      fs.StringP("format", "f", "json", "Specify the output format (`json` is default)")

Also applies to: 75-76


16-31: Verify that Execute receives defaulted processing flags.

Right now the test only verifies that Execute is called. It doesn’t assert the new defaults are actually propagated. Capture the arg and assert both flags are true.

 func TestDescribeDependents(t *testing.T) {
   ctrl := gomock.NewController(t)
+  t.Cleanup(ctrl.Finish)
   describeDependentsMock := exec.NewMockDescribeDependentsExec(ctrl)
-  describeDependentsMock.EXPECT().Execute(gomock.Any()).Return(nil)
+  describeDependentsMock.EXPECT().
+    Execute(gomock.AssignableToTypeOf(exec.DescribeDependentsExecProps{})).
+    Do(func(p exec.DescribeDependentsExecProps) {
+      assert.True(t, p.ProcessTemplates, "ProcessTemplates should default to true")
+      assert.True(t, p.ProcessYamlFunctions, "ProcessYamlFunctions should default to true")
+    }).
+    Return(nil)

72-89: Avoid brittle struct-wide equality; assert only relevant fields.

Comparing the entire DescribeDependentsExecProps makes the test fragile as the struct evolves (e.g., Skip, IncludeSettings). It can also break on nil vs empty-slice semantics.

Replace with field-level assertions:

-      assert.NoError(t, err)
-      assert.Equal(t, tt.expected, describeDependentArgs)
+      assert.NoError(t, err)
+      assert.Equal(t, tt.expected.Format, describeDependentArgs.Format)
+      assert.Equal(t, tt.expected.ProcessTemplates, describeDependentArgs.ProcessTemplates)
+      assert.Equal(t, tt.expected.ProcessYamlFunctions, describeDependentArgs.ProcessYamlFunctions)

75-78: Define the new flags in the test FlagSet and add a negative-case test.

Currently the test never sets --process-templates/--process-functions flags to false. Define them in the FlagSet and add a table case to validate disabling processing.

       fs := pflag.NewFlagSet("test", pflag.ContinueOnError)
-      fs.StringP("format", "f", "yaml", "Specify the output format (`yaml` is default)")
+      fs.StringP("format", "f", "json", "Specify the output format (`json` is default)")
       fs.StringP("output", "o", "list", "Specify the output type (`list` is default)")
       fs.StringP("query", "q", "", "Specify a query to filter the output")
+      fs.Bool("process-templates", true, "Process templates in components and dependents")
+      fs.Bool("process-functions", true, "Process YAML functions in components and dependents")
+      fs.StringSlice("skip", nil, "List of components to skip")
       tt.setFlags(fs)

And extend the table with a negative-case:

       {
         name: "Set invalid format, no override",
         setFlags: func(fs *pflag.FlagSet) {
           fs.Set("format", "invalid_format")
         },
         expectedErr: true,
       },
+      {
+        name: "Disable processing flags",
+        setFlags: func(fs *pflag.FlagSet) {
+          fs.Set("process-templates", "false")
+          fs.Set("process-functions", "false")
+        },
+        expected: &exec.DescribeDependentsExecProps{
+          Format:               "json",
+          ProcessTemplates:     false,
+          ProcessYamlFunctions: false,
+        },
+      },

91-108: Use t.Setenv for hermetic env handling.

t.Setenv is simpler and auto-cleans per test, avoiding manual defers.

 func TestDescribeDependentsCmd_Error(t *testing.T) {
   stacksPath := "../tests/fixtures/scenarios/terraform-apply-affected"
-
-  err := os.Setenv("ATMOS_CLI_CONFIG_PATH", stacksPath)
-  assert.NoError(t, err, "Setting 'ATMOS_CLI_CONFIG_PATH' environment variable should execute without error")
-
-  err = os.Setenv("ATMOS_BASE_PATH", stacksPath)
-  assert.NoError(t, err, "Setting 'ATMOS_BASE_PATH' environment variable should execute without error")
-
-  // Unset ENV variables after testing
-  defer func() {
-    os.Unsetenv("ATMOS_CLI_CONFIG_PATH")
-    os.Unsetenv("ATMOS_BASE_PATH")
-  }()
+  t.Setenv("ATMOS_CLI_CONFIG_PATH", stacksPath)
+  t.Setenv("ATMOS_BASE_PATH", stacksPath)

If you apply this, also drop the unused os import.


3-14: Drop unused import after switching to t.Setenv.

If you adopt t.Setenv, remove os from imports to keep golangci-lint happy.

 import (
-  "os"
   "testing"
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • 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 69e15ce and 2c69ca5.

📒 Files selected for processing (2)
  • cmd/describe_affected_test.go (4 hunks)
  • cmd/describe_dependents_test.go (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
cmd/*.go

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

cmd/*.go: Implement each Cobra command in a separate file under the cmd/ directory
Use kebab-case for command-line flags
Provide comprehensive help text for all commands and flags
Include examples in command help
Provide meaningful feedback to users in command implementation
Include progress indicators for long-running operations
Provide clear error messages to users
Include troubleshooting hints when appropriate
Log detailed errors for debugging

Files:

  • cmd/describe_dependents_test.go
  • cmd/describe_affected_test.go
**/*.go

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

**/*.go: Use Viper for managing configuration, environment variables, and flags
Use interfaces for external dependencies to facilitate mocking
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)
Consider using a custom error type for domain-specific errors
Follow standard Go coding style
Use gofmt and goimports to format code
Prefer short, descriptive variable names
Use snake_case for environment variables
Document all exported functions, types, and methods
Document complex logic with inline comments
Follow Go's documentation conventions
Use Viper for configuration management
Support configuration via files, environment variables, and flags
Follow the precedence order: flags > environment variables > config file > defaults

Files:

  • cmd/describe_dependents_test.go
  • cmd/describe_affected_test.go
**/*_test.go

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

**/*_test.go: Every new feature must include comprehensive unit tests
Test both happy paths and error conditions
Use table-driven tests for testing multiple scenarios
Include integration tests for command flows
Test CLI end-to-end when possible
Use test fixtures for complex inputs
Consider using testify/mock for creating mock implementations

Files:

  • cmd/describe_dependents_test.go
  • cmd/describe_affected_test.go
🧠 Learnings (2)
📓 Common learnings
Learnt from: Listener430
PR: cloudposse/atmos#934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: aknysh
PR: cloudposse/atmos#944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
Learnt from: CR
PR: cloudposse/atmos#0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-07-01T02:22:25.901Z
Learning: Clearly describe the changes in the PR description
📚 Learning: 2025-06-23T02:14:30.937Z
Learnt from: aknysh
PR: cloudposse/atmos#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/describe_affected_test.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Build (ubuntu-latest, linux)
  • GitHub Check: Analyze (go)
  • GitHub Check: Lint (golangci)
  • GitHub Check: website-deploy-preview
  • GitHub Check: Summary
🔇 Additional comments (5)
cmd/describe_affected_test.go (3)

45-52: Defaults for processing flags are asserted correctly

Expecting ProcessTemplates: true and ProcessYamlFunctions: true by default aligns with the PR objective and prevents regressions.


74-77: LGTM on default format and processing flags

Asserting Format: "json" by default and that processing flags remain enabled is consistent with the new behavior.

Also applies to: 85-88


17-18: No changes needed: Go version ≥1.20
go.mod declares go 1.24.5 (line 3), so t.Chdir is fully supported.

cmd/describe_dependents_test.go (2)

47-50: Defaults for new processing flags are exercised.

Good call asserting ProcessTemplates and ProcessYamlFunctions default to true when another flag is changed. This guards the intended default behavior.


58-61: Skip slice remains nil by default—no deep-equality risk

The setSliceOfStringsFlagIfChanged helper only assigns to describe.Skip when the --skip flag is explicitly changed, so a newly allocated &DescribeDependentsExecProps{} leaves Skip as the nil zero-value rather than []string{}. No initializer in setFlagsForDescribeDependentsCmd forcibly creates an empty slice, so deep-equality comparisons won’t be broken by unexpected []string{}nil mismatches.

coderabbitai[bot]
coderabbitai bot previously approved these changes Aug 24, 2025
@aknysh aknysh requested a review from osterman August 24, 2025 19:44
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (9)
internal/exec/describe_dependents_test.go (9)

40-45: Assert new flag defaults are forwarded by Execute()

Nice update to the mock signature to include the new flags. Add quick assertions to ensure DescribeDependentsExec forwards the intended defaults (processTemplates/processFunctions=true, skip=nil) and the same config pointer. This catches regressions in flag plumbing.

Apply this diff inside the mock:

 mockExecuteDescribeDependents := func(config *schema.AtmosConfiguration, component, stack string, includeSettings bool, processTemplates bool, processFunctions bool, skip []string) ([]schema.Dependent, error) {
+   assert.Equal(t, atmosConfig, config)
    assert.Equal(t, "test-component", component)
    assert.Equal(t, "test-stack", stack)
    assert.False(t, includeSettings)
+   assert.True(t, processTemplates)
+   assert.True(t, processFunctions)
+   assert.Nil(t, skip)
    return dependents, nil
 }

If helpful, I can add a focused test that toggles these flags and validates pass-through.


105-111: Mirror assertions for flag defaults in the query path

This path should also assert processTemplates/processFunctions default to true and skip is nil to keep coverage consistent.

 executeDescribeDependents: func(atmosConfig *schema.AtmosConfiguration, component, stack string, includeSettings bool, processTemplates bool, processFunctions bool, skip []string) ([]schema.Dependent, error) {
+  assert.True(t, processTemplates)
+  assert.True(t, processFunctions)
+  assert.Nil(t, skip)
   return dependents, nil
 },

135-140: Good negative test for plumbing errors

This ensures Execute short-circuits on executeDescribeDependents failure. Optionally, add a control to prove evaluateYqExpression is not invoked when upstream fails (e.g., set a panic in a stub if called). Not required, just a guard against accidental reordering.


263-265: Avoid writing artifacts to repo root in format/file matrix

The first case writes output.json to CWD. Use t.TempDir to isolate filesystem effects and avoid CI flakes.

Here’s a minimal tweak for the per-test file path:

// before building props
file := tc.file
if file != "" {
  file = filepath.Join(t.TempDir(), filepath.Base(tc.file))
}

// in props
File: file,

684-702: Sorting: add t.Parallel for speed and isolation

The test is pure and deterministic—safe to parallelize.

 func TestSortDependentsByStackSlug_BasicOrder(t *testing.T) {
+  t.Parallel()
   deps := []schema.Dependent{

704-714: Nil/empty cases well covered; can parallelize

Same rationale as above.

 func TestSortDependentsByStackSlugRecursive_EmptyAndNil(t *testing.T) {
+  t.Parallel()
   // nil slice

716-749: Recursive sort: great coverage of nested ordering

Consider t.Parallel here as well.

 func TestSortDependentsByStackSlugRecursive_BasicAndNested(t *testing.T) {
+  t.Parallel()
   // Unsorted tree

751-765: Tie stability verified

Good use of SliceStable behavior. Also safe to parallelize.

 func TestSortDependentsByStackSlugRecursive_TieStabilityAtNestedLevel(t *testing.T) {
+  t.Parallel()
   // Children have identical (Stack, Component) → identical StackSlug; order should be stable.

40-45: Add explicit coverage for non-default flags and skip propagation

Right now we validate defaults. Add one focused test proving that DescribeDependentsExec forwards IncludeSettings=true, ProcessTemplates=false, ProcessYamlFunctions=false, and a non-empty Skip slice to ExecuteDescribeDependents. Keeps the new flags from regressing.

Here’s a small test you can drop in:

func TestDescribeDependentsExec_Execute_ForwardsFlagsAndSkip(t *testing.T) {
  t.Parallel()
  atmosConfig := &schema.AtmosConfiguration{}
  called := false
  skipIn := []string{"aws-profile", "lock"}
  exec := &describeDependentsExec{
    atmosConfig: atmosConfig,
    executeDescribeDependents: func(cfg *schema.AtmosConfiguration, component, stack string, includeSettings, processTemplates, processFunctions bool, skip []string) ([]schema.Dependent, error) {
      called = true
      assert.Equal(t, atmosConfig, cfg)
      assert.Equal(t, "c", component)
      assert.Equal(t, "s", stack)
      assert.True(t, includeSettings)
      assert.False(t, processTemplates)
      assert.False(t, processFunctions)
      assert.Equal(t, skipIn, skip)
      return []schema.Dependent{{Component: "x", Stack: "s"}}, nil
    },
    isTTYSupportForStdout: func() bool { return false },
    newPageCreator:        pager.NewMockPageCreator(gomock.NewController(t)),
    evaluateYqExpression:  func(_ *schema.AtmosConfiguration, data any, _ string) (any, error) { return data, nil },
  }

  err := exec.Execute(&DescribeDependentsExecProps{
    Component:           "c",
    Stack:               "s",
    Format:              "yaml",
    IncludeSettings:     true,
    ProcessTemplates:    false,
    ProcessYamlFunctions:false,
    Skip:                skipIn,
  })
  require.NoError(t, err)
  require.True(t, called)
}

Also applies to: 105-111

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • 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 2c69ca5 and 45aef2b.

📒 Files selected for processing (1)
  • internal/exec/describe_dependents_test.go (9 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

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

**/*.go: Use Viper for managing configuration, environment variables, and flags
Use interfaces for external dependencies to facilitate mocking
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)
Consider using a custom error type for domain-specific errors
Follow standard Go coding style
Use gofmt and goimports to format code
Prefer short, descriptive variable names
Use snake_case for environment variables
Document all exported functions, types, and methods
Document complex logic with inline comments
Follow Go's documentation conventions
Use Viper for configuration management
Support configuration via files, environment variables, and flags
Follow the precedence order: flags > environment variables > config file > defaults

Files:

  • internal/exec/describe_dependents_test.go
**/*_test.go

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

**/*_test.go: Every new feature must include comprehensive unit tests
Test both happy paths and error conditions
Use table-driven tests for testing multiple scenarios
Include integration tests for command flows
Test CLI end-to-end when possible
Use test fixtures for complex inputs
Consider using testify/mock for creating mock implementations

Files:

  • internal/exec/describe_dependents_test.go
🧠 Learnings (7)
📓 Common learnings
Learnt from: Listener430
PR: cloudposse/atmos#934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: aknysh
PR: cloudposse/atmos#944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
Learnt from: CR
PR: cloudposse/atmos#0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-07-01T02:22:25.901Z
Learning: Clearly describe the changes in the PR description
📚 Learning: 2025-08-16T23:32:40.412Z
Learnt from: aknysh
PR: cloudposse/atmos#1405
File: internal/exec/describe_dependents_test.go:455-456
Timestamp: 2025-08-16T23:32:40.412Z
Learning: In the cloudposse/atmos Go codebase, `InitCliConfig` returns a `schema.AtmosConfiguration` value (not a pointer), while `ExecuteDescribeDependents` expects a `*schema.AtmosConfiguration` pointer parameter. Therefore, when passing the result of `InitCliConfig` to `ExecuteDescribeDependents`, use `&atmosConfig` to pass the address of the value.

Applied to files:

  • internal/exec/describe_dependents_test.go
📚 Learning: 2025-07-01T02:22:25.901Z
Learnt from: CR
PR: cloudposse/atmos#0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-07-01T02:22:25.901Z
Learning: Applies to **/*_test.go : Consider using testify/mock for creating mock implementations

Applied to files:

  • internal/exec/describe_dependents_test.go
📚 Learning: 2025-07-01T02:22:25.901Z
Learnt from: CR
PR: cloudposse/atmos#0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-07-01T02:22:25.901Z
Learning: Applies to **/*_test.go : Test both happy paths and error conditions

Applied to files:

  • internal/exec/describe_dependents_test.go
📚 Learning: 2025-07-01T02:22:25.901Z
Learnt from: CR
PR: cloudposse/atmos#0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-07-01T02:22:25.901Z
Learning: Applies to **/*.go : Use interfaces for external dependencies to facilitate mocking

Applied to files:

  • internal/exec/describe_dependents_test.go
📚 Learning: 2025-08-16T23:33:07.477Z
Learnt from: aknysh
PR: cloudposse/atmos#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:

  • internal/exec/describe_dependents_test.go
📚 Learning: 2025-07-01T02:22:25.901Z
Learnt from: CR
PR: cloudposse/atmos#0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-07-01T02:22:25.901Z
Learning: Applies to **/*_test.go : Use table-driven tests for testing multiple scenarios

Applied to files:

  • internal/exec/describe_dependents_test.go
🧬 Code graph analysis (1)
internal/exec/describe_dependents_test.go (2)
pkg/schema/schema.go (2)
  • AtmosConfiguration (25-60)
  • Dependent (813-828)
internal/exec/describe_dependents.go (1)
  • ExecuteDescribeDependents (105-350)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Build (macos-latest, macos)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Build (ubuntu-latest, linux)
  • GitHub Check: Analyze (go)
  • GitHub Check: Lint (golangci)
  • GitHub Check: website-deploy-preview
  • GitHub Check: Summary
🔇 Additional comments (7)
internal/exec/describe_dependents_test.go (7)

7-7: Import addition is appropriate.

strings is used by mk; minimal and justified.


175-182: YQ error path looks good

Covers the query-evaluation failure cleanly. No changes needed.


205-207: Empty results path is covered

Good to see a dedicated test for zero dependents.


460-461: Correct: pass pointer to ExecuteDescribeDependents

Good adherence to the InitCliConfig value vs. pointer API. Using &atmosConfig is required here.


660-661: Correct pointer usage (repeat scenario)

Same as Line 460—this prevents a type mismatch and aligns with prior learnings.


668-676: Helper mk is concise and mirrors production slug logic

ReplaceAll matches fmt.Sprintf("%s-%s", stack, strings.Replace(name,"/","-",-1)). Looks good.


678-683: withChildren helper is clear

Makes the nested-sort tests readable. No changes needed.

@aknysh aknysh merged commit 7a4abbc into main Aug 25, 2025
52 checks passed
@aknysh aknysh deleted the update-describe-affected-11 branch August 25, 2025 02:15
@mergify mergify bot removed the needs-cloudposse Needs Cloud Posse assistance label Aug 25, 2025
Copy link

These changes were released in v1.188.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
minor New features that do not break anything size/xl Extra large size PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants