diff --git a/command/build_test.go b/command/build_test.go index 76e49d65a..63c76f7e7 100644 --- a/command/build_test.go +++ b/command/build_test.go @@ -17,6 +17,106 @@ import ( shell_local "github.com/hashicorp/packer/provisioner/shell-local" ) +func TestBuild_VarArgs(t *testing.T) { + tc := []struct { + name string + args []string + expectedCode int + fileCheck + }{ + { + name: "json - json varfile sets an apple env var", + args: []string{ + "-var-file=" + filepath.Join(testFixture("var-arg"), "apple.json"), + filepath.Join(testFixture("var-arg"), "fruit_builder.json"), + }, + fileCheck: fileCheck{expected: []string{"apple.txt"}}, + }, + + { + name: "json - arg sets a pear env var", + args: []string{ + "-var=fruit=pear", + filepath.Join(testFixture("var-arg"), "fruit_builder.json"), + }, + fileCheck: fileCheck{expected: []string{"pear.txt"}}, + }, + + { + name: "json - inexistent var file errs", + args: []string{ + "-var-file=" + filepath.Join(testFixture("var-arg"), "potato.json"), + filepath.Join(testFixture("var-arg"), "fruit_builder.json"), + }, + expectedCode: 1, + fileCheck: fileCheck{notExpected: []string{"potato.txt"}}, + }, + + { + name: "hcl - inexistent json var file errs", + args: []string{ + "-var-file=" + filepath.Join(testFixture("var-arg"), "potato.json"), + testFixture("var-arg"), + }, + expectedCode: 1, + fileCheck: fileCheck{notExpected: []string{"potato.txt"}}, + }, + + { + name: "hcl - inexistent hcl var file errs", + args: []string{ + "-var-file=" + filepath.Join(testFixture("var-arg"), "potato.hcl"), + testFixture("var-arg"), + }, + expectedCode: 1, + fileCheck: fileCheck{notExpected: []string{"potato.hcl"}}, + }, + + { + name: "hcl - auto varfile sets a chocolate env var", + args: []string{ + testFixture("var-arg"), + }, + fileCheck: fileCheck{expected: []string{"chocolate.txt"}}, + }, + + { + name: "hcl - hcl varfile sets a apple env var", + args: []string{ + "-var-file=" + filepath.Join(testFixture("var-arg"), "apple.hcl"), + testFixture("var-arg"), + }, + fileCheck: fileCheck{expected: []string{"apple.txt"}}, + }, + + { + name: "hcl - json varfile sets a apple env var", + args: []string{ + "-var-file=" + filepath.Join(testFixture("var-arg"), "apple.json"), + testFixture("var-arg"), + }, + fileCheck: fileCheck{expected: []string{"apple.txt"}}, + }, + + { + name: "hcl - arg sets a tomato env var", + args: []string{ + "-var=fruit=tomato", + testFixture("var-arg"), + }, + fileCheck: fileCheck{expected: []string{"tomato.txt"}}, + }, + } + + for _, tt := range tc { + t.Run(tt.name, func(t *testing.T) { + run(t, tt.args, tt.expectedCode) + defer cleanup() + tt.fileCheck.verify(t) + }) + } +} + func TestBuildOnlyFileCommaFlags(t *testing.T) { c := &BuildCommand{ Meta: testMetaFile(t), @@ -217,6 +317,35 @@ func TestBuildWithNonExistingBuilder(t *testing.T) { } } +func run(t *testing.T, args []string, expectedCode int) { + t.Helper() + + c := &BuildCommand{ + Meta: testMetaFile(t), + } + + if code := c.Run(args); code != expectedCode { + fatalCommand(t, c.Meta) + } +} + +type fileCheck struct { + expected, notExpected []string +} + +func (fc fileCheck) verify(t *testing.T) { + for _, f := range fc.expected { + if !fileExists(f) { + t.Errorf("Expected to find %s", f) + } + } + for _, f := range fc.notExpected { + if fileExists(f) { + t.Errorf("Expected to not find %s", f) + } + } +} + // fileExists returns true if the filename is found func fileExists(filename string) bool { if _, err := os.Stat(filename); err == nil { diff --git a/command/meta.go b/command/meta.go index 8d28a1924..bdd40883f 100644 --- a/command/meta.go +++ b/command/meta.go @@ -50,6 +50,9 @@ func (m *Meta) Core(tpl *template.Template) (*packer.Core, error) { return nil, err } } + if m.flagVars == nil { + m.flagVars = map[string]string{} + } for k, v := range *fj { m.flagVars[k] = v } diff --git a/command/test-fixtures/var-arg/apple.hcl b/command/test-fixtures/var-arg/apple.hcl new file mode 100644 index 000000000..0a54a34f6 --- /dev/null +++ b/command/test-fixtures/var-arg/apple.hcl @@ -0,0 +1,2 @@ + +fruit = "apple" diff --git a/command/test-fixtures/var-arg/apple.json b/command/test-fixtures/var-arg/apple.json new file mode 100644 index 000000000..125836e31 --- /dev/null +++ b/command/test-fixtures/var-arg/apple.json @@ -0,0 +1,3 @@ +{ + "fruit": "apple" +} diff --git a/command/test-fixtures/var-arg/chocolate.auto.pkrvars.hcl b/command/test-fixtures/var-arg/chocolate.auto.pkrvars.hcl new file mode 100644 index 000000000..51149d6c8 --- /dev/null +++ b/command/test-fixtures/var-arg/chocolate.auto.pkrvars.hcl @@ -0,0 +1,2 @@ + +fruit = "chocolate" // is that even a fruit !? diff --git a/command/test-fixtures/var-arg/fruit_builder.json b/command/test-fixtures/var-arg/fruit_builder.json new file mode 100644 index 000000000..abda09077 --- /dev/null +++ b/command/test-fixtures/var-arg/fruit_builder.json @@ -0,0 +1,20 @@ +{ + "variables": { + "fruit": "" + }, + "builders": [ + { + "communicator": "none", + "type": "null" + } + ], + "post-processors": [ + [ + { + "name": "apple", + "type": "shell-local", + "inline": [ "echo {{ user `fruit` }} > {{ user `fruit` }}.txt" ] + } + ] + ] +} diff --git a/command/test-fixtures/var-arg/fuit_builder.pkr.hcl b/command/test-fixtures/var-arg/fuit_builder.pkr.hcl new file mode 100644 index 000000000..8aff9951d --- /dev/null +++ b/command/test-fixtures/var-arg/fuit_builder.pkr.hcl @@ -0,0 +1,18 @@ + +variable "fruit" { + type = string +} + +source "null" "builder" { + communicator = "none" +} + +build { + sources = [ + "source.null.builder", + ] + + provisioner "shell-local" { + inline = ["echo ${var.fruit} > ${var.fruit}.txt"] + } +} diff --git a/hcl2template/parser.go b/hcl2template/parser.go index 35061f932..d7d2591ba 100644 --- a/hcl2template/parser.go +++ b/hcl2template/parser.go @@ -130,11 +130,17 @@ func (p *Parser) parse(filename string, varFiles []string, argVars map[string]st for _, filename := range hclVarFiles { f, moreDiags := p.ParseHCLFile(filename) diags = append(diags, moreDiags...) + if moreDiags.HasErrors() { + continue + } varFiles = append(varFiles, f) } for _, filename := range jsonVarFiles { f, moreDiags := p.ParseJSONFile(filename) diags = append(diags, moreDiags...) + if moreDiags.HasErrors() { + continue + } varFiles = append(varFiles, f) }