Skip to content

Conversation

@denis256
Copy link
Member

@denis256 denis256 commented Dec 1, 2025

Description

Based on PR: #4758

  • fixed CICD failures
  • added regression tests

Fixes #4757.

TODOs

Read the Gruntwork contribution guidelines.

  • I authored this code entirely myself
  • I am submitting code based on open source software (e.g. MIT, MPL-2.0, Apache)]
  • I am adding or upgrading a dependency or adapted code and confirm it has a compatible open source license
  • Update the docs.
  • Run the relevant tests successfully, including pre-commit checks.
  • Include release notes. If this PR is backward incompatible, include a migration guide.

Release Notes (draft)

Added / Removed / Updated [X].

Migration Guide

Summary by CodeRabbit

  • Bug Fixes

    • Fixed shallow merge behavior for Terraform copy filters (include_in_copy and exclude_from_copy). Child configurations now properly override parent settings instead of being ignored, and explicit empty filters are now respected to clear parent values.
  • Tests

    • Added comprehensive test coverage for copy filter merging scenarios in configuration inheritance.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 1, 2025

📝 Walkthrough

Walkthrough

Implements shallow-merge support for Terraform include_in_copy and exclude_from_copy lists. Adds mergeListArgPreserveEmpty helper to preserve explicitly empty child lists during config merging, modifies TerragruntConfig.Merge to use this helper, and adds comprehensive unit and integration tests validating shallow and deep merge scenarios.

Changes

Cohort / File(s) Summary
Merge logic enhancement
config/include.go
Adds mergeListArgPreserveEmpty helper function to merge list-valued Terraform arguments, ensuring child-provided empty lists override parent values in shallow merge. Applies this to IncludeInCopy and ExcludeFromCopy in TerragruntConfig.Merge.
Unit tests
config/include_test.go
Expands TestMergeConfigIntoIncludedConfig and TestDeepMergeConfigIntoIncludedConfig with 8+ test cases covering child-only lists, parent-only lists, list override behavior, explicit empty list clearing, and duplicate preservation in both shallow and deep merge contexts.
Regression test fixtures
test/fixtures/regressions/shallow-merge-copy-filters-4757/{app,both-set,shared}/terragrunt.hcl, test/fixtures/regressions/shallow-merge-copy-filters-4757/shared/parent*.hcl
Creates test fixture hierarchy with parent configs defining copy filters and child configs exercising override and nil-parent scenarios; includes shared/parent.hcl, shared/parent-with-filters.hcl, app/terragrunt.hcl, and both-set/terragrunt.hcl.
Integration regression tests
test/integration_regressions_test.go
Adds TestShallowMergeCopyFilters with subtests validating that child exclude_from_copy/include_in_copy values are preserved when parent is nil and completely override parent values in shallow merge.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • config/include.go – New mergeListArgPreserveEmpty helper and its integration into Merge require careful logic review to confirm empty-list preservation behaves correctly across shallow/deep merge scenarios.
  • config/include_test.go – Multiple new test cases with overlapping scenarios; verify test data and assertions cover intended shallow vs. deep merge semantics.
  • Test fixtures – Verify HCL syntax and configuration hierarchy matches issue reproduction steps.
  • Integration test – Confirm JSON output parsing and assertions align with expected shallow-merge behavior.

Possibly related PRs

Suggested reviewers

  • yhakbar
  • wakeful

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'fix: shallow merge configuration fixes' is vague and generic, using non-specific language ('configuration fixes') that doesn't clearly communicate the actual change being fixed. Use a more specific title like 'fix: preserve child include_in_copy/exclude_from_copy in shallow merge' to clearly indicate what shallow merge behavior is being addressed.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description follows the template structure and includes the issue reference (#4757), but the release notes section has only a placeholder ('Added / Removed / Updated [X].') without specific details about what was changed.
Linked Issues check ✅ Passed The code changes directly address issue #4757 by implementing mergeListArgPreserveEmpty to preserve child include_in_copy/exclude_from_copy lists in shallow merge, adding comprehensive test coverage for both shallow and deep merge scenarios.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing shallow merge behavior for include_in_copy/exclude_from_copy lists; test fixtures and regression tests directly validate the fix without introducing unrelated modifications.
✨ 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 4757-shallow-merge-fix

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.

@vercel
Copy link

vercel bot commented Dec 1, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
terragrunt-docs Ready Ready Preview Comment Dec 1, 2025 5:26pm

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 (4)
config/include.go (1)

665-683: mergeListArgPreserveEmpty correctly distinguishes nil vs explicit empty lists

The helper cleanly encodes the desired behavior:

  • childListArg == nil → no-op (inherit parent).
  • len(*childListArg) == 0 → set a non-nil empty slice (explicit clear).
  • Non-empty child list → override with a copied slice (no aliasing to child).

Implementation is sound and pointer-safe; no changes required.

config/include_test.go (2)

153-182: Shallow-merge tests thoroughly cover copy-filter edge cases

The added cases exercise all key scenarios for IncludeInCopy / ExcludeFromCopy under shallow merge (child-only, parent-only, both-set, explicit clears, and parent-without-lists). They align with the new mergeListArgPreserveEmpty behavior and should prevent regressions.


334-369: Deep-merge tests validate concatenation semantics and duplicates

These cases accurately encode current DeepMerge behavior: parent vs child list combinations are concatenated in the expected order, nil vs empty lists behave correctly, and duplicates are intentionally preserved. Comments are clear enough, despite the slightly confusing “parent/child” wording relative to source/target.

test/integration_regressions_test.go (1)

444-521: Integration test robustly covers shallow merge copy-filter regression

TestShallowMergeCopyFilters exercises both the “parent nil, child set” and “both set, child wins” cases via terragrunt render --json, asserting on terraform.source, exclude_from_copy, and include_in_copy. The structure and assertions closely mirror the reported bug, so this should effectively guard against regressions.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1fe9079 and 5ca82a4.

📒 Files selected for processing (7)
  • config/include.go (2 hunks)
  • config/include_test.go (2 hunks)
  • test/fixtures/regressions/shallow-merge-copy-filters-4757/app/terragrunt.hcl (1 hunks)
  • test/fixtures/regressions/shallow-merge-copy-filters-4757/both-set/terragrunt.hcl (1 hunks)
  • test/fixtures/regressions/shallow-merge-copy-filters-4757/shared/parent-with-filters.hcl (1 hunks)
  • test/fixtures/regressions/shallow-merge-copy-filters-4757/shared/parent.hcl (1 hunks)
  • test/integration_regressions_test.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

⚙️ CodeRabbit configuration file

Review the Go code for quality and correctness. Make sure that the Go code follows best practices, is performant, and is easy to understand and maintain.

Files:

  • config/include.go
  • config/include_test.go
  • test/integration_regressions_test.go
🧠 Learnings (2)
📚 Learning: 2025-02-10T23:20:04.295Z
Learnt from: yhakbar
Repo: gruntwork-io/terragrunt PR: 3868
File: docs-starlight/patches/@astrojs%[email protected]:33-33
Timestamp: 2025-02-10T23:20:04.295Z
Learning: In Terragrunt projects, all `.hcl` files can be assumed to be Terragrunt configurations by default, with specific exceptions like `.terraform.lock.hcl` that need explicit handling.

Applied to files:

  • test/fixtures/regressions/shallow-merge-copy-filters-4757/both-set/terragrunt.hcl
  • test/fixtures/regressions/shallow-merge-copy-filters-4757/app/terragrunt.hcl
📚 Learning: 2025-11-03T04:40:01.000Z
Learnt from: ThisGuyCodes
Repo: gruntwork-io/terragrunt PR: 5041
File: test/fixtures/hclvalidate/valid/duplicate-attributes-in-required-providers/main.tf:2-7
Timestamp: 2025-11-03T04:40:01.000Z
Learning: In the terragrunt repository, test fixtures under test/fixtures/hclvalidate/valid/ are intentionally testing that INPUT validation succeeds even when Terraform code contains syntax errors or other issues unrelated to input validation (e.g., duplicate attributes, circular references, invalid locals). The "valid" designation means "valid for input validation purposes" not "syntactically valid Terraform/OpenTofu code".

Applied to files:

  • config/include_test.go
  • test/integration_regressions_test.go
🧬 Code graph analysis (1)
test/integration_regressions_test.go (2)
test/helpers/package.go (3)
  • CleanupTerraformFolder (882-889)
  • CopyEnvironment (89-105)
  • RunTerragruntCommand (965-969)
util/file.go (1)
  • JoinPath (626-628)
⏰ 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). (1)
  • GitHub Check: Pull Request has non-contributor approval
🔇 Additional comments (5)
test/fixtures/regressions/shallow-merge-copy-filters-4757/shared/parent.hcl (1)

1-3: Fixture parent.hcl correctly defines shared module source

Source path matches the integration test expectations for the shallow-merge copy-filters regression; no issues.

config/include.go (1)

308-310: Shallow merge now correctly preserves/overrides copy filters

Using mergeListArgPreserveEmpty for IncludeInCopy and ExcludeFromCopy in Merge fixes the shallow-merge bug: child-provided lists (including explicit empties) now override parent lists without concatenation, matching the intended semantics for issue #4757.

test/fixtures/regressions/shallow-merge-copy-filters-4757/shared/parent-with-filters.hcl (1)

2-6: Parent-with-filters fixture correctly defines source and copy filters

Source and parent copy filters are well-formed and match the regression test scenarios for “both_set_child_wins”; nothing to change here.

test/fixtures/regressions/shallow-merge-copy-filters-4757/both-set/terragrunt.hcl (1)

1-8: Child fixture for “both_set” correctly overrides parent filters

The include path and child terraform copy filters line up with the integration test’s “both_set_child_wins” expectations; configuration is minimal and appropriate for the regression.

test/fixtures/regressions/shallow-merge-copy-filters-4757/app/terragrunt.hcl (1)

2-9: App fixture correctly models parent-without-filters scenario

The include and terraform blocks accurately represent the “parent Terraform present, child sets filters” case targeted by the regression test; no adjustments needed.

Copy link
Contributor

@ThisGuyCodes ThisGuyCodes left a comment

Choose a reason for hiding this comment

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

either the name + docstring is wrong, or the implimentation needs to be changed to do an actual merge

Comment on lines +669 to +683
func mergeListArgPreserveEmpty(childListArg *[]string, parentListArg **[]string) {
if childListArg == nil {
return
}

if len(*childListArg) == 0 {
empty := make([]string, 0)
*parentListArg = &empty

return
}

copied := append([]string(nil), *childListArg...)
*parentListArg = &copied
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Either this function is wrong, or the name + docstring is. This doesn't merge the two lists under any circumstances; it either:

  • replaces the parent list with a new empty list if the child list is empty (couldn't we just use the existing one instead of allocating a new one?)
  • replaces the parent list with the non-empty child list
  • leaves the parent list alone if the child list is nil

none of these are a "merge"

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Terraform block include_in_copy / exclude_from_copy doesn't work as expected in shallow include merge

3 participants