Skip to content

Restore public API for terraform-provider-utils component config - #2078

Merged
Andriy Knysh (aknysh) merged 4 commits into
mainfrom
aknysh/update-for-utils-provider-1
Feb 16, 2026
Merged

Andriy Knysh (aknysh) merged 4 commits into
mainfrom
aknysh/update-for-utils-provider-1

Conversation

@aknysh

@aknysh Andriy Knysh (aknysh) commented Feb 16, 2026 •

Copy link
Copy Markdown
Member

what

  • Restore ProcessComponentInStack and ProcessComponentFromContext public functions that were deleted in v1.201.0 (PR feat: Path-based component resolution for all commands #1774)
  • Add the functions to pkg/describe (not pkg/component) to avoid an import cycle
  • These are the two functions that cloudposse/terraform-provider-utils depends on for the data "utils_component_config" data source
  • Add comprehensive tests for both functions (14 test cases)

why

  • In v1.201.0 (PR feat: Path-based component resolution for all commands #1774 — "Path-based component resolution for all commands"), pkg/component/component_processor.go was deleted entirely. This file contained ProcessComponentInStack and ProcessComponentFromContext, which are the public API consumed by cloudposse/terraform-provider-utils
  • The processing logic was moved to internal/exec, which external Go modules cannot import
  • This blocks the provider from upgrading its Atmos dependency past v1.189.0
  • Users running Atmos CLI v1.200+ with new features (stores, hooks, gomplate templates, !terraform.state/!terraform.output YAML tags) experience provider crashes ("Plugin did not respond") because the old v1.189.0 code in the provider cannot parse the newer configuration format
  • The crash affects all components using cloudposse/stack-config/yaml//modules/remote-state, which calls data "utils_component_config" internally — in one affected repo, this impacts 56 components
  • The functions are placed in pkg/describe instead of pkg/component because internal/exec now imports pkg/component (for the ComponentProvider interface and ComponentRegistry), which would create an import cycle

references

  • Atmos issue doc: docs/fixes/2026-02-15-restore-component-processor-public-api.md
  • PR feat: Path-based component resolution for all commands #1774 — "Path-based component resolution for all commands" (deleted pkg/component/component_processor.go)
  • Affected module: cloudposse/stack-config/yaml//modules/remote-state v1.8.0

Summary by CodeRabbit

  • New Features

    • Restored public APIs for processing component configurations via stack or contextual parameters.
  • Documentation

    • Added detailed guidance on the restored public API, historical context, integration notes, and usage considerations.
  • Tests

    • Added comprehensive tests for success and error scenarios, variable extraction, workspace presence, tenant variations, and cross-validation between entry points.

@aknysh Andriy Knysh (aknysh) added the patch A minor, backward compatible change label Feb 16, 2026
@aknysh
Andriy Knysh (aknysh) requested a review from a team as a code owner February 16, 2026 04:59
@aknysh Andriy Knysh (aknysh) added the patch A minor, backward compatible change label Feb 16, 2026
@github-actions github-actions Bot added the size/m Medium size PR label Feb 16, 2026
@aknysh Andriy Knysh (aknysh) self-assigned this Feb 16, 2026
@github-actions

github-actions Bot commented Feb 16, 2026 •

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@aknysh
Andriy Knysh (aknysh) force-pushed the aknysh/update-for-utils-provider-1 branch from 804e3f6 to 2baf1e4 Compare February 16, 2026 05:03
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@aknysh
Andriy Knysh (aknysh) force-pushed the aknysh/update-for-utils-provider-1 branch from 2baf1e4 to 9b14a18 Compare February 16, 2026 05:04
@coderabbitai

coderabbitai Bot commented Feb 16, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Adds public component-processing wrappers to pkg/describe: ProcessComponentInStack and ProcessComponentFromContext. They initialize CLI config, resolve stack names (template or pattern), track perf, and delegate execution to internal describe logic to return component configuration maps.

Changes

Cohort / File(s) Summary
Documentation
docs/fixes/2026-02-15-restore-component-processor-public-api.md
New doc describing restoration of the component-processor public API, package-boundary rationale, import-cycle avoidance, and integration notes for terraform-provider-utils.
Describe public API
pkg/describe/component_processor.go
Adds ComponentFromContextParams and two public functions: ProcessComponentInStack (direct stack execution) and ProcessComponentFromContext (resolves stack via template or pattern, initializes CLI config). Both perform perf tracking and delegate to an internal execution helper.
Tests
pkg/describe/component_processor_test.go
New tests covering success and error paths for both public functions, variable extraction under vars, workspace presence, tenant variations, and cross-validation between the two APIs.

Sequence Diagram

sequenceDiagram
    actor Client
    participant ParamsResolver as "StackResolution"
    participant CliConfig as "InitCliConfig"
    participant PublicAPI as "pkg/describe (Public API)"
    participant Executor as "internal/exec (Executor)"

    Client->>PublicAPI: call ProcessComponentFromContext(params) or ProcessComponentInStack(component,stack)
    PublicAPI->>ParamsResolver: resolve stack name (template or pattern) [if FromContext]
    ParamsResolver-->>PublicAPI: stackName
    PublicAPI->>CliConfig: InitCliConfig(atmosCliConfigPath, atmosBasePath)
    CliConfig-->>PublicAPI: atmosConfig
    PublicAPI->>PublicAPI: perf.Track
    PublicAPI->>Executor: ExecuteDescribeComponent(atmosConfig, component, stack)
    Executor-->>PublicAPI: component map / error
    PublicAPI-->>Client: return map / error
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

minor

Suggested reviewers

  • osterman
  • kevcube
  • nitrocode
🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: restoring public API functions for component config processing needed by terraform-provider-utils.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch aknysh/update-for-utils-provider-1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented Feb 16, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.61538% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.31%. Comparing base (ed0c334) to head (8b46708).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
pkg/describe/component_processor.go 84.61% 5 Missing and 3 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2078      +/-   ##
==========================================
+ Coverage   76.30%   76.31%   +0.01%     
==========================================
  Files         802      803       +1     
  Lines       75522    75574      +52     
==========================================
+ Hits        57628    57678      +50     
- Misses      14311    14312       +1     
- Partials     3583     3584       +1     
Flag Coverage Δ
unittests 76.31% <84.61%> (+0.01%) ⬆️

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

Files with missing lines Coverage Δ
pkg/describe/component_processor.go 84.61% <84.61%> (ø)

... and 3 files with indirect coverage changes

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In `@docs/fixes/2026-02-15-restore-component-processor-public-api.md`:
- Around line 88-93: The fenced code block containing the error message "Error:
Plugin did not respond\n  with
module.iam_roles.module.account_map.data.utils_component_config.config[0],\n 
The plugin encountered an error, and failed to respond to the\n 
plugin.(*GRPCProvider).ReadDataSource call." needs a language identifier; update
the triple-backtick fence that surrounds that error sample to include a language
token (e.g., ```text or ```plain) so the block is properly tagged for static
analysis and rendering.
- Line 115: The docs claim both function signatures are preserved but only
ProcessComponentInStack is unchanged; ProcessComponentFromContext changed from
positional parameters to a single options struct—update the docs to state this
explicitly by noting that ProcessComponentFromContext now accepts a struct
(e.g., Options/Request type) instead of positional args while
ProcessComponentInStack remains unchanged, and include the new struct name and
its fields so callers know the breaking signature change.
- Around line 106-108: The provider update is more than an import change: the
function ProcessComponentFromContext in pkg/describe now accepts a single
*ComponentFromContextParams instead of seven positional string args, so update
the provider call sites to construct and pass a ComponentFromContextParams
struct literal (populating the same seven fields) and call
ProcessComponentFromContext(*ComponentFromContextParams) from the new
pkg/describe import; search for calls to ProcessComponentFromContext in the
provider and replace the positional-arg invocation with a struct literal
matching ComponentFromContextParams fields.

In `@pkg/describe/component_processor_test.go`:
- Around line 12-31: In TestProcessComponentInStack, replace the initial
assert.Nil/ assert.NotNil checks on the result of ProcessComponentInStack with
require.Nil/ require.NotNil so the test stops immediately if
ProcessComponentInStack fails (avoiding passing a nil result into
u.ConvertToYAML); do the same pattern for the other tests that assert then
immediately use the result (e.g., the similar block around lines referenced in
the review). Also update the test imports to include testify/require.

In `@pkg/describe/component_processor.go`:
- Around line 61-62: ProcessComponentFromContext currently dereferences params
without a nil guard which causes a panic if callers pass nil; add an early
nil-check at the top of ProcessComponentFromContext to return a clear error
(e.g., fmt.Errorf or errors.New) when params == nil before calling perf.Track or
accessing params fields, so callers get a controlled error instead of a panic.
Ensure the function signature and returned types (map[string]any, error) are
preserved and update any callers/tests if they relied on panic behavior.
🧹 Nitpick comments (3)
pkg/describe/component_processor.go (1)

61-103: Double InitCliConfig call in ProcessComponentFromContext.

ProcessComponentFromContext initializes config at line 69, uses it to resolve the stack name (lines 74-101), then delegates to ProcessComponentInStack at line 103 — which calls InitCliConfig again at line 42. Config parsing runs twice per invocation.

Consider refactoring so the resolved atmosConfig is reused. For example, extract the core logic of ProcessComponentInStack into a private helper that accepts an already-initialized atmosConfig, and call that helper from both public functions.

Sketch
+func processComponentInStackWithConfig(
+	atmosConfig *schema.AtmosConfiguration,
+	component string,
+	stack string,
+) (map[string]any, error) {
+	return e.ExecuteDescribeComponent(&e.ExecuteDescribeComponentParams{
+		AtmosConfig:          atmosConfig,
+		Component:            component,
+		Stack:                stack,
+		ProcessTemplates:     true,
+		ProcessYamlFunctions: true,
+	})
+}

Then ProcessComponentFromContext calls processComponentInStackWithConfig with the config it already has.

pkg/describe/component_processor_test.go (2)

22-30: Duplicated debug-on-failure cleanup block.

The same t.Cleanup block with YAML logging appears four times. A small helper would reduce noise:

func logOnFailure(t *testing.T, result map[string]any) {
    t.Helper()
    resultYaml, _ := u.ConvertToYAML(result)
    t.Cleanup(func() {
        if t.Failed() {
            if resultYaml != "" {
                t.Logf("Component section:\n%s", resultYaml)
            } else {
                t.Logf("Component section (raw): %+v", result)
            }
        }
    })
}

Also applies to: 89-97, 202-210, 223-231


61-75: Consider table-driven tests for the error cases.

TestProcessComponentInStackInvalidComponent, TestProcessComponentInStackInvalidStack, TestProcessComponentFromContextInvalidComponent, and TestProcessComponentFromContextInvalidContext all follow the same shape: call → assert error. These consolidate well into a table.

Also applies to: 117-135

Comment thread docs/fixes/2026-02-15-restore-component-processor-public-api.md Outdated
Comment thread docs/fixes/2026-02-15-restore-component-processor-public-api.md Outdated
Comment thread docs/fixes/2026-02-15-restore-component-processor-public-api.md Outdated
Comment thread pkg/describe/component_processor_test.go Outdated
Comment thread pkg/describe/component_processor.go
- Extract processComponentInStackWithConfig to avoid double InitCliConfig
- Add nil guard on ProcessComponentFromContext params
- Extract logOnFailure test helper to deduplicate cleanup blocks
- Consolidate error cases into table-driven tests
- Increase test coverage (name_template branch, default branch, nil params)
- Fix fenced code block language identifier in docs
- Clarify signature change and provider update scope in docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added size/l Large size PR and removed size/m Medium size PR labels Feb 16, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
pkg/describe/component_processor_test.go (1)

229-260: Use filepath.Join for test fixture paths.

The hardcoded "../../tests/fixtures/scenarios/locals-logical-names" string uses forward slashes, which the coding guidelines flag. Same pattern appears at lines 245, 263, and 275. Consider:

Proposed fix
-	atmosCliConfigPath := "../../tests/fixtures/scenarios/locals-logical-names"
+	atmosCliConfigPath := filepath.Join("..", "..", "tests", "fixtures", "scenarios", "locals-logical-names")

As per coding guidelines: "Never use forward slash concatenation in tests - always use filepath.Join() with separate arguments."

pkg/describe/component_processor.go (1)

60-62: Use the existing ErrNilParam sentinel instead of dynamic error.

A suitable static error sentinel already exists at errors/errors.go:657: errUtils.ErrNilParam ("parameter cannot be nil"). Replace the dynamic fmt.Errorf with this sentinel to align with project guidelines for consistent error handling.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Feb 16, 2026
- Use errUtils.ErrNilParam sentinel instead of dynamic fmt.Errorf
- Use filepath.Join for test fixture paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@aknysh
Andriy Knysh (aknysh) merged commit 082335d into main Feb 16, 2026
57 of 59 checks passed
@aknysh
Andriy Knysh (aknysh) deleted the aknysh/update-for-utils-provider-1 branch February 16, 2026 18:32
@github-actions

Copy link
Copy Markdown

These changes were released in v1.206.3-rc.0.

@github-actions

Copy link
Copy Markdown

These changes were released in v1.207.0.

@github-actions

Copy link
Copy Markdown

These changes were released in v1.208.0-rc.0.

@github-actions

Copy link
Copy Markdown

These changes were released in v1.208.0-test.15.

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/l Large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants