Skip to content

Commit

Permalink
allow to set pkr variables from env, from local files and from
Browse files Browse the repository at this point in the history
arguments
  • Loading branch information
azr committed Jan 14, 2020
1 parent 64d4267 commit e8e58f4
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 73 deletions.
2 changes: 1 addition & 1 deletion command/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (c *BuildCommand) GetBuildsFromHCL(path string) ([]packer.Build, int) {
PostProcessorsSchemas: c.CoreConfig.Components.PostProcessorStore,
}

builds, diags := parser.Parse(path)
builds, diags := parser.Parse(path, c.flagVars)
{
// write HCL errors/diagnostics if any.
b := bytes.NewBuffer(nil)
Expand Down
3 changes: 2 additions & 1 deletion hcl2template/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func getBasicParser() *Parser {

type parseTestArgs struct {
filename string
vars map[string]string
}

type parseTest struct {
Expand All @@ -54,7 +55,7 @@ func testParse(t *testing.T, tests []parseTest) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotCfg, gotDiags := tt.parser.parse(tt.args.filename)
gotCfg, gotDiags := tt.parser.parse(tt.args.filename, tt.args.vars)
if tt.parseWantDiags == (gotDiags == nil) {
t.Fatalf("Parser.parse() unexpected diagnostics. %s", gotDiags)
}
Expand Down
89 changes: 64 additions & 25 deletions hcl2template/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package hcl2template

import (
"fmt"
"os"

"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclparse"
Expand Down Expand Up @@ -39,44 +40,82 @@ type Parser struct {
}

const (
hcl2FileExt = ".pkr.hcl"
hcl2JsonFileExt = ".pkr.json"
hcl2FileExt = ".pkr.hcl"
hcl2JsonFileExt = ".pkr.json"
hcl2VarFileExt = ".auto.pkrvars.hcl"
hcl2VarJsonFileExt = ".auto.pkrvars.json"
)

func (p *Parser) parse(filename string) (*PackerConfig, hcl.Diagnostics) {

hclFiles, jsonFiles, diags := GetHCL2Files(filename)
func (p *Parser) parse(filename string, vars map[string]string) (*PackerConfig, hcl.Diagnostics) {

var files []*hcl.File
for _, filename := range hclFiles {
f, moreDiags := p.ParseHCLFile(filename)
diags = append(diags, moreDiags...)
files = append(files, f)
}
for _, filename := range jsonFiles {
f, moreDiags := p.ParseJSONFile(filename)
diags = append(diags, moreDiags...)
files = append(files, f)
}
if diags.HasErrors() {
return nil, diags
var diags hcl.Diagnostics

// parse config files
{
hclFiles, jsonFiles, moreDiags := GetHCL2Files(filename, hcl2FileExt, hcl2JsonFileExt)
if len(hclFiles)+len(jsonFiles) == 0 {
diags = append(moreDiags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Could not find any config file in " + filename,
Detail: "A config file must be suffixed with `.pkr.hcl` or " +
"`.pkr.json`. A folder can be referenced.",
})
}
for _, filename := range hclFiles {
f, moreDiags := p.ParseHCLFile(filename)
diags = append(diags, moreDiags...)
files = append(files, f)
}
for _, filename := range jsonFiles {
f, moreDiags := p.ParseJSONFile(filename)
diags = append(diags, moreDiags...)
files = append(files, f)
}
if diags.HasErrors() {
return nil, diags
}
}

// decode variable blocks
cfg := &PackerConfig{}
for _, file := range files {
diags = append(diags, p.parseInputVariables(file, cfg)...)
{
for _, file := range files {
diags = append(diags, p.decodeInputVariables(file, cfg)...)
}
for _, file := range files {
diags = append(diags, p.decodeLocalVariables(file, cfg)...)
}
}
for _, file := range files {
diags = append(diags, p.parseLocalVariables(file, cfg)...)

// parse var files
{
hclVarFiles, jsonVarFiles, moreDiags := GetHCL2Files(filename, hcl2VarFileExt, hcl2VarJsonFileExt)
diags = append(diags, moreDiags...)
var varFiles []*hcl.File
for _, filename := range hclVarFiles {
f, moreDiags := p.ParseHCLFile(filename)
diags = append(diags, moreDiags...)
varFiles = append(varFiles, f)
}
for _, filename := range jsonVarFiles {
f, moreDiags := p.ParseJSONFile(filename)
diags = append(diags, moreDiags...)
varFiles = append(varFiles, f)
}

diags = append(diags, cfg.InputVariables.collectVariableValues(os.Environ(), varFiles, vars)...)
}

// decode the actual content
for _, file := range files {
diags = append(diags, p.parseConfig(file, cfg)...)
diags = append(diags, p.decodeConfig(file, cfg)...)
}

return cfg, diags
}

func (p *Parser) parseInputVariables(f *hcl.File, cfg *PackerConfig) hcl.Diagnostics {
func (p *Parser) decodeInputVariables(f *hcl.File, cfg *PackerConfig) hcl.Diagnostics {
var diags hcl.Diagnostics

content, moreDiags := f.Body.Content(configSchema)
Expand All @@ -96,7 +135,7 @@ func (p *Parser) parseInputVariables(f *hcl.File, cfg *PackerConfig) hcl.Diagnos
return diags
}

func (p *Parser) parseLocalVariables(f *hcl.File, cfg *PackerConfig) hcl.Diagnostics {
func (p *Parser) decodeLocalVariables(f *hcl.File, cfg *PackerConfig) hcl.Diagnostics {
var diags hcl.Diagnostics

content, moreDiags := f.Body.Content(configSchema)
Expand All @@ -113,7 +152,7 @@ func (p *Parser) parseLocalVariables(f *hcl.File, cfg *PackerConfig) hcl.Diagnos
return diags
}

func (p *Parser) parseConfig(f *hcl.File, cfg *PackerConfig) hcl.Diagnostics {
func (p *Parser) decodeConfig(f *hcl.File, cfg *PackerConfig) hcl.Diagnostics {
var diags hcl.Diagnostics

content, moreDiags := f.Body.Content(configSchema)
Expand Down
12 changes: 6 additions & 6 deletions hcl2template/types.build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func TestParse_build(t *testing.T) {
tests := []parseTest{
{"basic build no src",
defaultParser,
parseTestArgs{"testdata/build/basic.pkr.hcl"},
parseTestArgs{"testdata/build/basic.pkr.hcl", nil},
&PackerConfig{
Builds: Builds{
&BuildBlock{
Expand Down Expand Up @@ -45,7 +45,7 @@ func TestParse_build(t *testing.T) {
},
{"untyped provisioner",
defaultParser,
parseTestArgs{"testdata/build/provisioner_untyped.pkr.hcl"},
parseTestArgs{"testdata/build/provisioner_untyped.pkr.hcl", nil},
&PackerConfig{
Builds: nil,
},
Expand All @@ -55,7 +55,7 @@ func TestParse_build(t *testing.T) {
},
{"inexistent provisioner",
defaultParser,
parseTestArgs{"testdata/build/provisioner_inexistent.pkr.hcl"},
parseTestArgs{"testdata/build/provisioner_inexistent.pkr.hcl", nil},
&PackerConfig{
Builds: nil,
},
Expand All @@ -65,7 +65,7 @@ func TestParse_build(t *testing.T) {
},
{"untyped post-processor",
defaultParser,
parseTestArgs{"testdata/build/post-processor_untyped.pkr.hcl"},
parseTestArgs{"testdata/build/post-processor_untyped.pkr.hcl", nil},
&PackerConfig{
Builds: nil,
},
Expand All @@ -75,7 +75,7 @@ func TestParse_build(t *testing.T) {
},
{"inexistent post-processor",
defaultParser,
parseTestArgs{"testdata/build/post-processor_inexistent.pkr.hcl"},
parseTestArgs{"testdata/build/post-processor_inexistent.pkr.hcl", nil},
&PackerConfig{
Builds: nil,
},
Expand All @@ -85,7 +85,7 @@ func TestParse_build(t *testing.T) {
},
{"invalid source",
defaultParser,
parseTestArgs{"testdata/build/invalid_source_reference.pkr.hcl"},
parseTestArgs{"testdata/build/invalid_source_reference.pkr.hcl", nil},
&PackerConfig{
Builds: nil,
},
Expand Down
4 changes: 2 additions & 2 deletions hcl2template/types.packer_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ func (p *Parser) getBuilds(cfg *PackerConfig) ([]packer.Build, hcl.Diagnostics)
//
// Parse then return a slice of packer.Builds; which are what packer core uses
// to run builds.
func (p *Parser) Parse(path string) ([]packer.Build, hcl.Diagnostics) {
cfg, diags := p.parse(path)
func (p *Parser) Parse(path string, vars map[string]string) ([]packer.Build, hcl.Diagnostics) {
cfg, diags := p.parse(path, vars)
if diags.HasErrors() {
return nil, diags
}
Expand Down
10 changes: 5 additions & 5 deletions hcl2template/types.packer_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestParser_complete(t *testing.T) {
tests := []parseTest{
{"working build",
defaultParser,
parseTestArgs{"testdata/complete"},
parseTestArgs{"testdata/complete", nil},
&PackerConfig{
InputVariables: Variables{
"foo": Variable{},
Expand Down Expand Up @@ -61,22 +61,22 @@ func TestParser_complete(t *testing.T) {
},
{"dir with no config files",
defaultParser,
parseTestArgs{"testdata/empty"},
parseTestArgs{"testdata/empty", nil},
nil,
true, true,
nil,
false,
},
{name: "inexistent dir",
parser: defaultParser,
args: parseTestArgs{"testdata/inexistent"},
args: parseTestArgs{"testdata/inexistent", nil},
parseWantCfg: nil,
parseWantDiags: true,
parseWantDiagHasErrors: true,
},
{name: "folder named build.pkr.hcl with an unknown src",
parser: defaultParser,
args: parseTestArgs{"testdata/build.pkr.hcl"},
args: parseTestArgs{"testdata/build.pkr.hcl", nil},
parseWantCfg: &PackerConfig{
Builds: Builds{
&BuildBlock{
Expand All @@ -98,7 +98,7 @@ func TestParser_complete(t *testing.T) {
},
{name: "unknown block type",
parser: defaultParser,
args: parseTestArgs{"testdata/unknown"},
args: parseTestArgs{"testdata/unknown", nil},
parseWantCfg: &PackerConfig{},
parseWantDiags: true,
parseWantDiagHasErrors: true,
Expand Down
10 changes: 5 additions & 5 deletions hcl2template/types.source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func TestParse_source(t *testing.T) {
tests := []parseTest{
{"two basic sources",
defaultParser,
parseTestArgs{"testdata/sources/basic.pkr.hcl"},
parseTestArgs{"testdata/sources/basic.pkr.hcl", nil},
&PackerConfig{
Sources: map[SourceRef]*Source{
SourceRef{
Expand All @@ -30,31 +30,31 @@ func TestParse_source(t *testing.T) {
},
{"untyped source",
defaultParser,
parseTestArgs{"testdata/sources/untyped.pkr.hcl"},
parseTestArgs{"testdata/sources/untyped.pkr.hcl", nil},
&PackerConfig{},
true, true,
nil,
false,
},
{"unnamed source",
defaultParser,
parseTestArgs{"testdata/sources/unnamed.pkr.hcl"},
parseTestArgs{"testdata/sources/unnamed.pkr.hcl", nil},
&PackerConfig{},
true, true,
nil,
false,
},
{"inexistent source",
defaultParser,
parseTestArgs{"testdata/sources/inexistent.pkr.hcl"},
parseTestArgs{"testdata/sources/inexistent.pkr.hcl", nil},
&PackerConfig{},
true, true,
nil,
false,
},
{"duplicate source",
defaultParser,
parseTestArgs{"testdata/sources/duplicate.pkr.hcl"},
parseTestArgs{"testdata/sources/duplicate.pkr.hcl", nil},
&PackerConfig{
Sources: map[SourceRef]*Source{
SourceRef{
Expand Down
Loading

0 comments on commit e8e58f4

Please sign in to comment.