diff --git a/hcl2template/parser.go b/hcl2template/parser.go index 6f7467da5..cf7af9fd4 100644 --- a/hcl2template/parser.go +++ b/hcl2template/parser.go @@ -101,6 +101,11 @@ func (p *Parser) parse(filename string, vars map[string]string) (*PackerConfig, } } + _, moreDiags := cfg.InputVariables.Values() + diags = append(diags, moreDiags...) + _, moreDiags = cfg.LocalVariables.Values() + diags = append(diags, moreDiags...) + // parse var files { hclVarFiles, jsonVarFiles, moreDiags := GetHCL2Files(filename, hcl2VarFileExt, hcl2VarJsonFileExt) diff --git a/hcl2template/types.build.go b/hcl2template/types.build.go index 47f833ddf..09b663525 100644 --- a/hcl2template/types.build.go +++ b/hcl2template/types.build.go @@ -60,6 +60,9 @@ func (p *Parser) decodeBuildConfig(block *hcl.Block) (*BuildBlock, hcl.Diagnosti Config hcl.Body `hcl:",remain"` } diags := gohcl.DecodeBody(block.Body, nil, &b) + if diags.HasErrors() { + return nil, diags + } for _, buildFrom := range b.FromSources { ref := sourceRefFromString(buildFrom) @@ -84,6 +87,9 @@ func (p *Parser) decodeBuildConfig(block *hcl.Block) (*BuildBlock, hcl.Diagnosti content, moreDiags := b.Config.Content(buildSchema) diags = append(diags, moreDiags...) + if diags.HasErrors() { + return nil, diags + } for _, block := range content.Blocks { switch block.Type { case buildProvisionerLabel: diff --git a/hcl2template/types.packer_config.go b/hcl2template/types.packer_config.go index 6e003d50a..e68405643 100644 --- a/hcl2template/types.packer_config.go +++ b/hcl2template/types.packer_config.go @@ -30,11 +30,13 @@ type PackerConfig struct { // decoder in order to tell what is the actual value of a var or a local and // the list of defined functions. func (cfg *PackerConfig) EvalContext() *hcl.EvalContext { + v, _ := cfg.InputVariables.Values() + l, _ := cfg.LocalVariables.Values() ectx := &hcl.EvalContext{ Functions: Functions(cfg.Basedir), Variables: map[string]cty.Value{ - "var": cty.ObjectVal(cfg.InputVariables.Values()), - "local": cty.ObjectVal(cfg.LocalVariables.Values()), + "var": cty.ObjectVal(v), + "local": cty.ObjectVal(l), }, } return ectx diff --git a/hcl2template/types.variables.go b/hcl2template/types.variables.go index d05d3a841..cb74ff602 100644 --- a/hcl2template/types.variables.go +++ b/hcl2template/types.variables.go @@ -56,10 +56,11 @@ func (v *Variable) Value() (cty.Value, *hcl.Diagnostic) { return value, nil } } - return cty.NilVal, &hcl.Diagnostic{ + + return cty.UnknownVal(v.Type), &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Unset variable", - Detail: "A used variable must be set; see " + + Detail: "A used variable must be set or have a default value; see " + "https://packer.io/docs/configuration/from-1.5/syntax.html for details.", Context: v.block.DefRange.Ptr(), } @@ -67,12 +68,15 @@ func (v *Variable) Value() (cty.Value, *hcl.Diagnostic) { type Variables map[string]*Variable -func (variables Variables) Values() map[string]cty.Value { +func (variables Variables) Values() (map[string]cty.Value, hcl.Diagnostics) { res := map[string]cty.Value{} + var diags hcl.Diagnostics for k, v := range variables { - res[k], _ = v.Value() + var diag *hcl.Diagnostic + res[k], diag = v.Value() + diags = append(diags, diag) } - return res + return res, diags } // decodeConfig decodes a "variables" section the way packer 1 used to diff --git a/hcl2template/types.variables_test.go b/hcl2template/types.variables_test.go index fc6e6706d..c54c48978 100644 --- a/hcl2template/types.variables_test.go +++ b/hcl2template/types.variables_test.go @@ -10,7 +10,6 @@ import ( "github.com/zclconf/go-cty/cty/convert" "github.com/hashicorp/hcl/v2" - "github.com/hashicorp/packer/builder/null" "github.com/hashicorp/packer/packer" ) @@ -119,12 +118,8 @@ func TestParse_variables(t *testing.T) { }, }, false, false, - []packer.Build{ - &packer.CoreBuild{ - Builder: &null.Builder{}, - }, - }, - false, + []packer.Build{}, + true, }, } testParse(t, tests)