ensure we record diagnostics from nested modules
When loading nested modules, the child module diagnostics were dropped in the recursive function. This mean that the config from the submodules wasn't fully loaded, even though no errors were reported to the user. This caused further problems if the plan was stored in a plan file, when means only the partial configuration was stored for the subsequent apply operation, which would result in unexplained "Resource node has no configuration attached" errors later on. Also due to the child module diagnostics being lost, any newly added nested modules would be silently ignored until `init` was run again manually.
This commit is contained in:
parent
9ebcbe1d60
commit
8111050c66
|
@ -76,6 +76,7 @@ func buildChildModules(parent *Config, walker ModuleWalker) (map[string]*Config,
|
||||||
}
|
}
|
||||||
|
|
||||||
child.Children, modDiags = buildChildModules(child, walker)
|
child.Children, modDiags = buildChildModules(child, walker)
|
||||||
|
diags = append(diags, modDiags...)
|
||||||
|
|
||||||
ret[call.Name] = child
|
ret[call.Name] = child
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,3 +69,48 @@ func TestBuildConfig(t *testing.T) {
|
||||||
t.Fatalf("child_a.child_c is same object as child_b.child_c; should not be")
|
t.Fatalf("child_a.child_c is same object as child_b.child_c; should not be")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBuildConfigDiags(t *testing.T) {
|
||||||
|
parser := NewParser(nil)
|
||||||
|
mod, diags := parser.LoadConfigDir("testdata/nested-errors")
|
||||||
|
assertNoDiagnostics(t, diags)
|
||||||
|
if mod == nil {
|
||||||
|
t.Fatal("got nil root module; want non-nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
versionI := 0
|
||||||
|
cfg, diags := BuildConfig(mod, ModuleWalkerFunc(
|
||||||
|
func(req *ModuleRequest) (*Module, *version.Version, hcl.Diagnostics) {
|
||||||
|
// For the sake of this test we're going to just treat our
|
||||||
|
// SourceAddr as a path relative to our fixture directory.
|
||||||
|
// A "real" implementation of ModuleWalker should accept the
|
||||||
|
// various different source address syntaxes Terraform supports.
|
||||||
|
sourcePath := filepath.Join("testdata/nested-errors", req.SourceAddr)
|
||||||
|
|
||||||
|
mod, diags := parser.LoadConfigDir(sourcePath)
|
||||||
|
version, _ := version.NewVersion(fmt.Sprintf("1.0.%d", versionI))
|
||||||
|
versionI++
|
||||||
|
return mod, version, diags
|
||||||
|
},
|
||||||
|
))
|
||||||
|
|
||||||
|
wantDiag := `testdata/nested-errors/child_c/child_c.tf:5,1-8: ` +
|
||||||
|
`Unsupported block type; Blocks of type "invalid" are not expected here.`
|
||||||
|
assertExactDiagnostics(t, diags, []string{wantDiag})
|
||||||
|
|
||||||
|
// we should still have module structure loaded
|
||||||
|
var got []string
|
||||||
|
cfg.DeepEach(func(c *Config) {
|
||||||
|
got = append(got, fmt.Sprintf("%s %s", strings.Join(c.Path, "."), c.Version))
|
||||||
|
})
|
||||||
|
sort.Strings(got)
|
||||||
|
want := []string{
|
||||||
|
" <nil>",
|
||||||
|
"child_a 1.0.0",
|
||||||
|
"child_a.child_c 1.0.1",
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(got, want) {
|
||||||
|
t.Fatalf("wrong result\ngot: %swant: %s", spew.Sdump(got), spew.Sdump(want))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
module "child_c" {
|
||||||
|
source = "child_c"
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
output "hello" {
|
||||||
|
value = "hello"
|
||||||
|
}
|
||||||
|
|
||||||
|
invalid "block" "type " {
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
module "child_a" {
|
||||||
|
source = "child_a"
|
||||||
|
}
|
Loading…
Reference in New Issue