Skip to content

Commit e168d93

Browse files
Backport of Ensure that SourceBundleParser always receives a relative path for the Source Directory into v1.14 (#38124)
* backport of commit 8a63ac9 * backport of commit 1ed50c2 * backport of commit 4fe0dd4 * backport of commit 0f25b99 * backport of commit 9a9938d * Backport changelog entry for SourceBundleParser#LoadConfigDir bug fix into 1.14 * Delete BUG FIXES-20260116-101253.yaml --------- Co-authored-by: Abdurahman Abdelgany <abdu.abdelgany@hashicorp.com>
1 parent 9b44631 commit e168d93

File tree

3 files changed

+74
-16
lines changed

3 files changed

+74
-16
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
kind: BUG FIXES
2+
body: 'Fixed an issue where terraform stacks validate was failing to resolve relative paths for modules'
3+
time: 2026-01-16T10:12:53.854705-05:00
4+
custom:
5+
Issue: "38025"

internal/configs/source_bundle_parser.go

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,28 +68,35 @@ func (p *SourceBundleParser) LoadConfigDir(source sourceaddrs.FinalSource) (*Mod
6868
return nil, diags
6969
}
7070

71-
// The result of sources.LocalPathForSource is an absolute path, but we
71+
// The result of sources.LocalPathForSource can be an absolute path, but we
7272
// don't actually want to pass an absolute path for a module's SourceDir;
7373
// doing so will cause the value of `path.module` in Terraform configs to
7474
// differ across plans and applies, since tfc-agent performs plans and
7575
// applies in temporary directories. Instead, we try to resolve a relative
7676
// path from Terraform's working directory, which should always be a
7777
// reasonable SourceDir value.
78-
workDir, err := os.Getwd()
79-
if err != nil {
80-
diags = diags.Append(&hcl.Diagnostic{
81-
Severity: hcl.DiagError,
82-
Summary: "Cannot resolve working directory",
83-
Detail: fmt.Sprintf("Failed to resolve current working directory: %s. This is a bug in Terraform - please report it.", err),
84-
})
85-
}
86-
relativeSourceDir, err := filepath.Rel(workDir, sourceDir)
87-
if err != nil {
88-
diags = diags.Append(&hcl.Diagnostic{
89-
Severity: hcl.DiagError,
90-
Summary: "Cannot resolve relative path",
91-
Detail: fmt.Sprintf("Failed to resolve relative path to module directory: %s. This is a bug in Terraform - please report it.", err),
92-
})
78+
var relativeSourceDir string
79+
if filepath.IsAbs(sourceDir) {
80+
workDir, err := os.Getwd()
81+
if err != nil {
82+
diags = diags.Append(&hcl.Diagnostic{
83+
Severity: hcl.DiagError,
84+
Summary: "Cannot resolve working directory",
85+
Detail: fmt.Sprintf("Failed to resolve current working directory: %s. This is a bug in Terraform - please report it.", err),
86+
})
87+
}
88+
89+
relativeSourceDir, err = filepath.Rel(workDir, sourceDir)
90+
if err != nil {
91+
diags = diags.Append(&hcl.Diagnostic{
92+
Severity: hcl.DiagError,
93+
Summary: "Cannot resolve relative path",
94+
Detail: fmt.Sprintf("Failed to resolve relative path to module directory: %s. This is a bug in Terraform - please report it.", err),
95+
})
96+
}
97+
} else {
98+
// sourceDir is already relative, use it as-is
99+
relativeSourceDir = sourceDir
93100
}
94101
mod.SourceDir = relativeSourceDir
95102

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: BUSL-1.1
3+
4+
package configs
5+
6+
import (
7+
"path/filepath"
8+
"testing"
9+
10+
"github.com/hashicorp/go-slug/sourceaddrs"
11+
"github.com/hashicorp/go-slug/sourcebundle"
12+
)
13+
14+
// TestSourceBundleParser_LoadConfigDir_WithRelativePath tests that when
15+
// LocalPathForSource returns a relative path, LoadConfigDir correctly uses
16+
// it as-is without attempting to convert it.
17+
func TestSourceBundleParser_LoadConfigDir_WithRelativePath(t *testing.T) {
18+
// Use the basics-bundle from stacks testdata which has a component with has a relative source.
19+
bundlePath := "../stacks/stackconfig/testdata/basics-bundle"
20+
bundle, err := sourcebundle.OpenDir(bundlePath)
21+
if err != nil {
22+
t.Fatalf("failed to open source bundle: %s", err)
23+
}
24+
25+
source := sourceaddrs.MustParseSource("../stacks/stackconfig/testdata/basics-bundle").(sourceaddrs.FinalSource)
26+
27+
// Create a SourceBundleParser and load the config directory.
28+
parser := NewSourceBundleParser(bundle)
29+
mod, diags := parser.LoadConfigDir(source)
30+
31+
if diags.HasErrors() {
32+
t.Fatalf("unexpected errors: %s", diags.Error())
33+
}
34+
35+
if mod == nil {
36+
t.Fatal("expected non-nil module")
37+
}
38+
39+
// Verify that the SourceDir is set and that it's a relative path.
40+
if mod.SourceDir == "" {
41+
t.Error("expected SourceDir to be set, but it was empty")
42+
}
43+
if filepath.IsAbs(mod.SourceDir) {
44+
t.Errorf("expected SourceDir to be relative, but got absolute path: %s", mod.SourceDir)
45+
}
46+
}

0 commit comments

Comments
 (0)