Update BuildBlock with valid HCL2Ref (#12167)

While looking into #11932 I found that Packer will throw an error when
an unknown source is referenced from within the sources attribute for
a build block. The hcl.Diagnostics error includes a Subject, which
should highlight where in the HCL2 configuration file the unknown source resides.
But when creating the BuildBlock no HCL2Ref data is copied over, thus the
Subject is displayed with with zero value for an hcl.Range type.

This change updates the build creation logic to copy the HCL2Ref data
from the build block at decode time so that it can be properly
referenced downstream.

Closes #11932

Failure due to change in output
```
--- FAIL: TestValidateCommand_ShowLineNumForMissing (0.00s)
    --- FAIL: TestValidateCommand_ShowLineNumForMissing/test-fixtures/validate-invalid/missing_build_block.pkr.hcl (0.00s)
        validate_test.go:377: Unexpected output:   (
                """
                Error: Unknown source file.cho

            -     on  line 0:
            +     on test-fixtures/validate-invalid/missing_build_block.pkr.hcl line 6:
                  (source code not available)

                ... // 4 identical lines
                """
              )
        validate_test.go:379:
FAIL
FAIL    github.com/hashicorp/packer/command     1.002s
```
pull/12173/head
Wilken Rivera 3 years ago committed by GitHub
parent 50a356529a
commit 9002ac263f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,6 +1,7 @@
package command
import (
"fmt"
"path/filepath"
"testing"
@ -341,3 +342,42 @@ func TestValidateCommand_VarFilesDisableWarnOnUndeclared(t *testing.T) {
})
}
}
func TestValidateCommand_ShowLineNumForMissing(t *testing.T) {
tt := []struct {
path string
exitCode int
extraArgs []string
}{
{path: filepath.Join(testFixture("validate-invalid"), "missing_build_block.pkr.hcl"), exitCode: 1},
}
for _, tc := range tt {
t.Run(tc.path, func(t *testing.T) {
c := &ValidateCommand{
Meta: TestMetaFile(t),
}
tc := tc
args := tc.extraArgs
args = append(args, tc.path)
if code := c.Run(args); code != tc.exitCode {
fatalCommand(t, c.Meta)
}
stdout, stderr := GetStdoutAndErrFromTestMeta(t, c.Meta)
expected := fmt.Sprintf(`Error: Unknown source file.cho
on %s line 6:
(source code not available)
Known: [file.chocolate]
`, tc.path)
if diff := cmp.Diff(expected, stderr); diff != "" {
t.Errorf("Unexpected output: %s", diff)
}
t.Log(stdout)
})
}
}

@ -87,22 +87,26 @@ type Builds []*BuildBlock
// decodeBuildConfig is called when a 'build' block has been detected. It will
// load the references to the contents of the build block.
func (p *Parser) decodeBuildConfig(block *hcl.Block, cfg *PackerConfig) (*BuildBlock, hcl.Diagnostics) {
build := &BuildBlock{}
body := block.Body
var b struct {
Name string `hcl:"name,optional"`
Description string `hcl:"description,optional"`
FromSources []string `hcl:"sources,optional"`
Config hcl.Body `hcl:",remain"`
}
body := block.Body
diags := gohcl.DecodeBody(body, cfg.EvalContext(LocalContext, nil), &b)
if diags.HasErrors() {
return nil, diags
}
build := &BuildBlock{
HCL2Ref: newHCL2Ref(block, b.Config),
}
build.Name = b.Name
build.Description = b.Description
build.HCL2Ref.DefRange = block.DefRange
// Expose build.name during parsing of pps and provisioners
ectx := cfg.EvalContext(BuildContext, nil)

Loading…
Cancel
Save