Skip to content

Fix plan output relative #4492

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open

Conversation

james03160927
Copy link
Contributor

@james03160927 james03160927 commented Jul 1, 2025

Description

Fixes #4430.

This pull request introduces enhancements to the handling of module paths, adds new test fixtures for validating Terragrunt plans, and implements a new integration test for verifying terragrunt plan --all functionality. Below is a summary of the most important changes:

Enhancements to module path handling: Updated getPlanFilePath in configstack/module.go to ensure opts.WorkingDir is converted to an absolute path before calling filepath.Rel, improving compatibility with absolute module paths.

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

  • New Features
    • Added new test fixtures for private DNS zone, resource group, and virtual network configurations.
    • Introduced integration test to verify plan output files are generated for multiple modules.
  • Tests
    • Implemented integration test to ensure correct plan outputs are created in the expected directories.

Copy link

vercel bot commented Jul 1, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
terragrunt-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 11, 2025 4:33pm

Copy link
Contributor

coderabbitai bot commented Jul 1, 2025

📝 Walkthrough

"""

Walkthrough

New Terraform and Terragrunt fixture directories for private-dns-zone, resource-group, and vnet are added, each with minimal configuration and a variable/output for terragrunt_dir. An integration test is introduced to verify that terragrunt plan --all --out-dir with --working-dir outputs plan files to the correct subdirectories.

Changes

Files Change Summary
test/fixtures/plan-output/private-dns-zone/main.tf
test/fixtures/plan-output/resource-group/main.tf
test/fixtures/plan-output/vnet/main.tf
Added Terraform files with terragrunt_dir variable and output.
test/fixtures/plan-output/private-dns-zone/terragrunt.hcl
test/fixtures/plan-output/resource-group/terragrunt.hcl
test/fixtures/plan-output/vnet/terragrunt.hcl
Added Terragrunt configurations setting terragrunt_dir input and source as current dir.
test/integration_test.go Added integration test TestTerragruntPlanAllOutput to verify correct plan file output paths.
internal/runner/common/unit.go Modified getPlanFilePath to use absolute working directory path before computing relative path.

Sequence Diagram(s)

sequenceDiagram
    participant TestRunner as TestTerragruntPlanAllOutput
    participant Terragrunt as terragrunt CLI
    participant FS as Filesystem

    TestRunner->>FS: Setup fixture environment and output directory
    TestRunner->>Terragrunt: Run 'terragrunt plan --all --out-dir plans --working-dir .'
    Terragrunt->>FS: Generate plan files in plans/vnet/, plans/resource-group/, plans/private-dns-zone/
    TestRunner->>FS: Assert plan files exist in expected subdirectories
Loading

Assessment against linked issues

Objective Addressed Explanation
Ensure terragrunt plan --all --out-dir with --working-dir outputs plan files to correct subfolders (#4430)
Add integration test to verify plan output structure with and without --working-dir (#4430)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Modified getPlanFilePath in internal/runner/common/unit.go (lines related to filepath.Abs usage) This change improves path handling but is not explicitly required by the linked issue objectives.

Possibly related PRs

Suggested reviewers

  • denis256
  • yhakbar
    """

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0755da and 841d6d2.

📒 Files selected for processing (1)
  • test/integration_test.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/integration_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). (14)
  • GitHub Check: Build (windows/amd64)
  • GitHub Check: Test OIDC (GHA AWS)
  • GitHub Check: Build (windows/386)
  • GitHub Check: Build (linux/386)
  • GitHub Check: Build (darwin/amd64)
  • GitHub Check: Build (windows/amd64)
  • GitHub Check: Build (darwin/arm64)
  • GitHub Check: Build (linux/arm64)
  • GitHub Check: Build (linux/amd64)
  • GitHub Check: Test (ubuntu)
  • GitHub Check: Test (macos)
  • GitHub Check: Run pre-commit hooks
  • GitHub Check: build-and-test
  • GitHub Check: Pull Request has non-contributor approval
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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 (3)
configstack/module.go (1)

137-142: Good fix for relative path computation, but address the linting issue.

The logic correctly converts the working directory to an absolute path before computing the relative path, which resolves the issue with filepath.Rel() when dealing with absolute module paths. The fallback to the original working directory on error is appropriate defensive programming.

However, there's a pipeline failure indicating that assignments should be cuddled with other assignments (WSL linting rule).

Apply this diff to fix the linting issue:

 	// module path will be an absolute path so working dir should absolute too so that Rel() can work
 	wdir, err := filepath.Abs(opts.WorkingDir)
 	if err != nil {
 		wdir = opts.WorkingDir
 	}
+
 	path, _ := filepath.Rel(wdir, module.Path)
test/fixtures/plan-output/private-dns-zone/main.tf (1)

1-5: Specify variable type for clarity

Even in test fixtures, it’s generally a good habit to declare the variable’s type (e.g., string) and an optional description so that terraform validate surfaces clear metadata.
Example:

variable "terragrunt_dir" {
  type        = string
  description = "Path to the module directory supplied by Terragrunt"
}
test/fixtures/plan-output/resource-group/main.tf (1)

1-5: Mirror variable metadata across fixtures

For consistency with other modules (and to help automated linting), add type and description blocks to the terragrunt_dir variable here as well, mirroring the suggestion made for private-dns-zone/main.tf.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 75ffd55 and 89e345c.

📒 Files selected for processing (8)
  • configstack/module.go (1 hunks)
  • test/fixtures/plan-output/private-dns-zone/main.tf (1 hunks)
  • test/fixtures/plan-output/private-dns-zone/terragrunt.hcl (1 hunks)
  • test/fixtures/plan-output/resource-group/main.tf (1 hunks)
  • test/fixtures/plan-output/resource-group/terragrunt.hcl (1 hunks)
  • test/fixtures/plan-output/vnet/main.tf (1 hunks)
  • test/fixtures/plan-output/vnet/terragrunt.hcl (1 hunks)
  • test/integration_test.go (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.go`: 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.

**/*.go: 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.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • configstack/module.go
  • test/integration_test.go
🧠 Learnings (7)
test/fixtures/plan-output/vnet/terragrunt.hcl (3)
Learnt from: yhakbar
PR: gruntwork-io/terragrunt#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.
Learnt from: partcyborg
PR: gruntwork-io/terragrunt#3974
File: config/config_partial.go:448-456
Timestamp: 2025-03-06T23:44:09.413Z
Learning: The TerragruntConfig struct in config/config.go does contain an Engine field that's used to store engine configuration data.
Learnt from: levkohimins
PR: gruntwork-io/terragrunt#3723
File: cli/commands/stack/action.go:160-160
Timestamp: 2025-02-10T13:36:19.542Z
Learning: The project uses a custom error package `github.com/gruntwork-io/terragrunt/internal/errors` which provides similar functionality to `fmt.Errorf` but includes stack traces. Prefer using this package's error functions (e.g., `errors.Errorf`, `errors.New`) over the standard library's error handling.
test/fixtures/plan-output/resource-group/main.tf (1)
Learnt from: yhakbar
PR: gruntwork-io/terragrunt#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.
test/fixtures/plan-output/vnet/main.tf (1)
Learnt from: yhakbar
PR: gruntwork-io/terragrunt#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.
test/fixtures/plan-output/private-dns-zone/main.tf (1)
Learnt from: yhakbar
PR: gruntwork-io/terragrunt#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.
test/fixtures/plan-output/resource-group/terragrunt.hcl (3)
Learnt from: yhakbar
PR: gruntwork-io/terragrunt#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.
Learnt from: partcyborg
PR: gruntwork-io/terragrunt#3974
File: config/config_partial.go:448-456
Timestamp: 2025-03-06T23:44:09.413Z
Learning: The TerragruntConfig struct in config/config.go does contain an Engine field that's used to store engine configuration data.
Learnt from: levkohimins
PR: gruntwork-io/terragrunt#3723
File: cli/commands/stack/action.go:160-160
Timestamp: 2025-02-10T13:36:19.542Z
Learning: The project uses a custom error package `github.com/gruntwork-io/terragrunt/internal/errors` which provides similar functionality to `fmt.Errorf` but includes stack traces. Prefer using this package's error functions (e.g., `errors.Errorf`, `errors.New`) over the standard library's error handling.
test/fixtures/plan-output/private-dns-zone/terragrunt.hcl (3)
Learnt from: yhakbar
PR: gruntwork-io/terragrunt#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.
Learnt from: partcyborg
PR: gruntwork-io/terragrunt#3974
File: config/config_partial.go:448-456
Timestamp: 2025-03-06T23:44:09.413Z
Learning: The TerragruntConfig struct in config/config.go does contain an Engine field that's used to store engine configuration data.
Learnt from: levkohimins
PR: gruntwork-io/terragrunt#3723
File: cli/commands/stack/action.go:160-160
Timestamp: 2025-02-10T13:36:19.542Z
Learning: The project uses a custom error package `github.com/gruntwork-io/terragrunt/internal/errors` which provides similar functionality to `fmt.Errorf` but includes stack traces. Prefer using this package's error functions (e.g., `errors.Errorf`, `errors.New`) over the standard library's error handling.
test/integration_test.go (1)

undefined

<retrieved_learning>
Learnt from: levkohimins
PR: #3723
File: cli/commands/stack/action.go:160-160
Timestamp: 2025-02-10T13:36:19.542Z
Learning: The project uses a custom error package github.com/gruntwork-io/terragrunt/internal/errors which provides similar functionality to fmt.Errorf but includes stack traces. Prefer using this package's error functions (e.g., errors.Errorf, errors.New) over the standard library's error handling.
</retrieved_learning>

🧬 Code Graph Analysis (1)
test/integration_test.go (2)
test/helpers/package.go (3)
  • CleanupTerraformFolder (713-720)
  • CopyEnvironment (84-97)
  • RunTerragruntCommand (786-790)
util/file.go (1)
  • FileExists (58-61)
🪛 GitHub Actions: Lint
configstack/module.go

[error] 142-142: golangci-lint wsl: assignments should only be cuddled with other assignments

test/integration_test.go

[error] 4203-4203: golangci-lint usetesting: os.Chdir() could be replaced by t.Chdir() in TestTerragruntPlanAllOutput


[error] 4205-4205: golangci-lint usetesting: os.Chdir() could be replaced by t.Chdir() in TestTerragruntPlanAllOutput

🪛 GitHub Actions: Strict Lint
configstack/module.go

[error] 231-231: Cyclomatic complexity for function FindWhereWorkingDirIsIncluded is 11, exceeding max of 10.


[error] 454-454: Cyclomatic complexity for function flagUnitsThatAreIncluded is 13, exceeding max of 10.


[error] 635-635: Global variable 'existingModules' detected (gochecknoglobals).

test/integration_test.go

[error] 3806-3806: Lint error: declaration has 3 blank identifiers (dogsled).


[error] 905-905: Use of 'fmt.Printf' forbidden by pattern (forbidigo).


[error] 4219-4219: Use of 'fmt.Printf' forbidden by pattern (forbidigo).


[error] 1409-2508: Multiple type assertions must be checked (forcetypeassert).


[error] 281-3943: Function length exceeds limit (funlen).


[error] 1583-3998: Multiple unnecessary trailing newlines detected (whitespace).

⏰ Context from checks skipped due to timeout of 90000ms (21)
  • GitHub Check: Test (Windows)
  • GitHub Check: Build (windows/386)
  • GitHub Check: Build (darwin/amd64)
  • GitHub Check: Build (windows/amd64)
  • GitHub Check: Build (linux/arm64)
  • GitHub Check: Test (AWS with Latest OSS Terraform)
  • GitHub Check: Test (Mock)
  • GitHub Check: Build (darwin/amd64)
  • GitHub Check: Test (CAS)
  • GitHub Check: Test (AWS with Latest Terraform)
  • GitHub Check: Test (Provider Cache with Tofu)
  • GitHub Check: Test (Provider Cache with Latest Terraform)
  • GitHub Check: Test (Fixtures with Latest Terraform)
  • GitHub Check: Test (GCP)
  • GitHub Check: Test (AWSGCP)
  • GitHub Check: Test (Fixtures with OpenTofu)
  • GitHub Check: Test (Fixtures with Latest OSS Terraform)
  • GitHub Check: Test (Tflint)
  • GitHub Check: Test (ubuntu)
  • GitHub Check: Test (macos)
  • GitHub Check: build-and-test
🔇 Additional comments (5)
test/fixtures/plan-output/private-dns-zone/terragrunt.hcl (1)

1-7: LGTM! Well-structured test fixture.

The Terragrunt configuration is appropriate for testing plan output functionality. The simple setup with source pointing to current directory and terragrunt_dir input aligns well with the test requirements.

test/fixtures/plan-output/vnet/terragrunt.hcl (1)

1-7: LGTM! Consistent test fixture pattern.

The configuration follows the same pattern as other test fixtures in the plan-output directory, which ensures consistency in the test setup. The minimal configuration is appropriate for testing plan output functionality.

test/fixtures/plan-output/resource-group/terragrunt.hcl (1)

1-7: LGTM! Maintains consistent test fixture pattern.

The configuration is identical to the other test fixtures in the plan-output directory, which ensures uniform behavior during integration testing. This consistency is valuable for comprehensive validation of the plan output functionality.

test/fixtures/plan-output/vnet/main.tf (1)

1-5: LGTM! Simple and effective test fixture.

The Terraform configuration is minimal yet complete for testing purposes. The variable declaration without a default value ensures it must be provided via Terragrunt inputs, and the output allows verification of the value. This works perfectly with the corresponding terragrunt.hcl file.

test/integration_test.go (1)

95-95: LGTM! Test fixture constant is properly added.

The new test fixture constant follows the existing naming convention and is correctly placed with other fixture constants.

@denis256
Copy link
Member

denis256 commented Jul 2, 2025

Looks like are failing tests related to TestTfPath

@yhakbar
Copy link
Collaborator

yhakbar commented Jul 2, 2025

TestTfPath

Might be my fault. Let me update the PR and see if that fixes it.

@james03160927
Copy link
Contributor Author

I don't see TestTfPath test failing when I search for "FAIL:" from the failing checks below. @yhakbar

@denis256
Copy link
Member

denis256 commented Jul 4, 2025

Looks like after runner-pool changes got merged, branch have conflicts on configstack/module.go

- Keep both TestTerragruntPlanAllOutput and TestMixedStackConfigIgnored test functions
- Remove configstack/module.go as it was refactored to internal/runner in main
- Make working directory absolute before calculating relative paths in getPlanFilePath
- This ensures filepath.Rel() works correctly when both paths are absolute
- Fixes TestTerragruntPlanAllOutput test that was failing due to incorrect plan file paths
- Use t.Chdir() instead of manual directory change with cleanup
- Use t.Logf() instead of fmt.Printf() for test output
- Remove t.Parallel() since t.Chdir() requires non-parallel execution
@james03160927
Copy link
Contributor Author

HI @denis256 @yhakbar, should be good for another review.

@denis256
Copy link
Member

denis256 commented Jul 7, 2025

Looks like it is failing on lint

test/integration_test.go:4263:1: Function TestTerragruntPlanAllOutput missing the call to method parallel (paralleltest)
func TestTerragruntPlanAllOutput(t *testing.T) {
^
internal/runner/common/unit.go:98:2: assignments should only be cuddled with other assignments (wsl)
	path, err := filepath.Rel(wdir, unit.Path)
	^
internal/runner/common/unit.go:99:2: only one cuddle assignment allowed before if statement (wsl)
	if err != nil {
	^
3 issues:
* paralleltest: 1
* wsl: 2
level=info msg="Memory: 626 samples, avg is 1971.2MB, max is 3164.3MB"

@james03160927 ^

- Remove extra blank line in TestTerragruntPlanAllOutput function
- Add proper spacing in unit.go to resolve wsl cuddling violations
@james03160927
Copy link
Contributor Author

james03160927 commented Jul 8, 2025

Looks like it is failing on lint

test/integration_test.go:4263:1: Function TestTerragruntPlanAllOutput missing the call to method parallel (paralleltest)
func TestTerragruntPlanAllOutput(t *testing.T) {
^
internal/runner/common/unit.go:98:2: assignments should only be cuddled with other assignments (wsl)
	path, err := filepath.Rel(wdir, unit.Path)
	^
internal/runner/common/unit.go:99:2: only one cuddle assignment allowed before if statement (wsl)
	if err != nil {
	^
3 issues:
* paralleltest: 1
* wsl: 2
level=info msg="Memory: 626 samples, avg is 1971.2MB, max is 3164.3MB"

@james03160927 ^

Hi @denis256, one of the previous lint comment suggested to use t.Chdir() and it seems like we cannot use t.Parallel() if I follow the previous lint suggestion. Do you prefer me to use t.Parallel() and ignore the comment about using t.Chdir()`

Original change here: dc489ee

@yhakbar
Copy link
Collaborator

yhakbar commented Jul 8, 2025

Looks like it is failing on lint

test/integration_test.go:4263:1: Function TestTerragruntPlanAllOutput missing the call to method parallel (paralleltest)
func TestTerragruntPlanAllOutput(t *testing.T) {
^
internal/runner/common/unit.go:98:2: assignments should only be cuddled with other assignments (wsl)
	path, err := filepath.Rel(wdir, unit.Path)
	^
internal/runner/common/unit.go:99:2: only one cuddle assignment allowed before if statement (wsl)
	if err != nil {
	^
3 issues:
* paralleltest: 1
* wsl: 2
level=info msg="Memory: 626 samples, avg is 1971.2MB, max is 3164.3MB"

@james03160927 ^

Hi @denis256, one of the previous lint comment suggested to use t.Chdir() and it seems like we cannot use t.Parallel() if I follow the previous lint suggestion. Do you prefer me to use t.Parallel() and ignore the comment about using t.Chdir()`

Original change here: dc489ee

Why use chdir at all instead of using working-dir?

@james03160927
Copy link
Contributor Author

james03160927 commented Jul 10, 2025

Looks like it is failing on lint

test/integration_test.go:4263:1: Function TestTerragruntPlanAllOutput missing the call to method parallel (paralleltest)
func TestTerragruntPlanAllOutput(t *testing.T) {
^
internal/runner/common/unit.go:98:2: assignments should only be cuddled with other assignments (wsl)
	path, err := filepath.Rel(wdir, unit.Path)
	^
internal/runner/common/unit.go:99:2: only one cuddle assignment allowed before if statement (wsl)
	if err != nil {
	^
3 issues:
* paralleltest: 1
* wsl: 2
level=info msg="Memory: 626 samples, avg is 1971.2MB, max is 3164.3MB"

@james03160927 ^

Hi @denis256, one of the previous lint comment suggested to use t.Chdir() and it seems like we cannot use t.Parallel() if I follow the previous lint suggestion. Do you prefer me to use t.Parallel() and ignore the comment about using t.Chdir()`
Original change here: dc489ee

Why use chdir at all instead of using working-dir?

Hi Denis and Yousif, thanks for pointing that out.

I originally used t.Chdir() because when running terragrunt plan, the current working directory influences where the plan output (e.g., modules like vnet, private-dns-zone, resource-group) is placed under the --out-dir.

To reproduce the original issue deterministically, we need to run terragrunt plan from within the fixture directory — the directory that contains the actual Terragrunt configuration. If we don’t chdir into that directory, Terragrunt generates output paths under something like /tmp/test//{vnet, ...}, which varies depending on how the test is run and where the fixture is located. That makes it hard to assert on the output structure.

By explicitly chdiring into the fixture dir, the generated output goes under the expected /tmp/test/{vnet, private-dns-zone, resource-group}, making the test predictable and easier to validate.

I saw an earlier lint suggestion to use t.Chdir(), which unfortunately conflicts with t.Parallel(), since t.Chdir() is not safe for parallel tests. I’m happy to follow whichever approach you prefer:
• Use t.Parallel() and do not use t.Chdir() - dc489ee (previous approach)
• Or keep t.Chdir() and skip t.Parallel()

Let me know which direction you’d prefer. Thanks!

@yhakbar
Copy link
Collaborator

yhakbar commented Jul 10, 2025

@james03160927

Let me know which direction you’d prefer. Thanks!

I don't think you're going to like my response here, but neither! 😁

I think we should be using t.Parallel, and removing the dependency on the process current working directory. If we're not using --working-dir internally with --out-dir to determine where plan files should go, that's the bug we need to tackle.

There should be no difference in the binary between changing directories before running Terragrunt and running Terragrunt with --working-dir. By preserving that, we can improve our testing and predictability (as you have been running into, changing the process working directory is a side-effect that can impact other parts of the application running concurrently unexpectedly).

@james03160927
Copy link
Contributor Author

Hi @yhakbar, made the change according to your suggestion. PTAL when you get a chance.

@pseudomorph
Copy link
Contributor

@yhakbar - Might it make more sense to add a setter to the WorkingDir flag? The default working dir is an absolute path when not specified.

Seems like there are a few different issues related to the abs/rel pathing for working dir.

@pseudomorph
Copy link
Contributor

I've figured a top-level fix which allows the tests here to pass and addresses issues I was seeing with using --working-dir with the find command.

I'll cut an issue for the find matter. Should I post a patch here, or cut a different PR?

@james03160927
Copy link
Contributor Author

I've figured a top-level fix which allows the tests here to pass and addresses issues I was seeing with using --working-dir with the find command.

I'll cut an issue for the find matter. Should I post a patch here, or cut a different PR?

OH interesting. Feel free to contribute to this PR and we can work on things together. Thanks a lot @pseudomorph

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.

terragrunt plan when outputting planfiles with --working-dir does not send to correct folder
4 participants