diff --git a/hcl2template/types.datasource.go b/hcl2template/types.datasource.go index 51719204c..d35294187 100644 --- a/hcl2template/types.datasource.go +++ b/hcl2template/types.datasource.go @@ -17,6 +17,7 @@ import ( type DatasourceBlock struct { Type string DSName string + Dependencies []refString value cty.Value block *hcl.Block diff --git a/hcl2template/types.packer_config.go b/hcl2template/types.packer_config.go index 70fade66f..ae27d4ecc 100644 --- a/hcl2template/types.packer_config.go +++ b/hcl2template/types.packer_config.go @@ -245,25 +245,27 @@ func (c *PackerConfig) evaluateLocalVariables(locals []*LocalBlock) hcl.Diagnost // attributes, as HCL2 expressions are not allowed in a block's labels. vars := FilterTraversalsByType(local.Expr.Variables(), "local") - var localDeps []*LocalBlock + var localDeps []refString for _, v := range vars { // Some local variables may be locally aliased as // `local`, which if len(v) < 2 { continue } - varName := v[1].(hcl.TraverseAttr).Name - block, err := c.localByName(varName) + + depRef, err := NewRefStringFromDep(v) if err != nil { diags = diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Missing variable dependency", - Detail: fmt.Sprintf("The expression for variable %q depends on local.%s, which is not defined.", - local.Name, varName), + Summary: "failed to extract dependency name from traversal ref", + Detail: fmt.Sprintf("while preparing for evaluation of local variable %q, "+ + "a dependency was unable to be converted to a refString. "+ + "This is likely a Packer bug, please consider reporting it.", local.Name), }) continue } - localDeps = append(localDeps, block) + + localDeps = append(localDeps, depRef) } local.dependencies = localDeps } @@ -325,7 +327,17 @@ func (c *PackerConfig) recursivelyEvaluateLocalVariable(local *LocalBlock, depth var diags hcl.Diagnostics for _, dep := range local.dependencies { - localDiags := c.recursivelyEvaluateLocalVariable(dep, depth+1) + locBlock, err := c.getComponentByRef(dep) + if err != nil { + return diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "failed to get local variable", + Detail: fmt.Sprintf("While evaluating %q, its dependency %q was not found, is it defined?", + local.Name, dep.String()), + }) + } + + localDiags := c.recursivelyEvaluateLocalVariable(locBlock.(*LocalBlock), depth+1) diags = diags.Extend(localDiags) } diff --git a/hcl2template/types.variables.go b/hcl2template/types.variables.go index 3e7f9e1cb..b9fb0776b 100644 --- a/hcl2template/types.variables.go +++ b/hcl2template/types.variables.go @@ -35,7 +35,7 @@ type LocalBlock struct { // // Only `local`/`locals` will be referenced here as we execute all the // same component types at once. - dependencies []*LocalBlock + dependencies []refString // evaluated toggles to true if it has been evaluated. // // We use this to determine if we're ready to get the value of the