get builds from PackerConfig instead of parser
to allow just reading the config and to not start anything. This will allow to later on run `validate --syntax-only`. Note that none of the builder/provisioner/post-processor config will be read but simply ignored. HCL2 still needs the body to be properly formatted and it should detect most syntax errors.
This commit is contained in:
parent
2df21496b3
commit
5c2b8da63b
@ -104,7 +104,7 @@ func (c *BuildCommand) GetBuildsFromHCL(path string) ([]packer.Build, int) {
|
||||
PostProcessorsSchemas: c.CoreConfig.Components.PostProcessorStore,
|
||||
}
|
||||
|
||||
builds, diags := parser.Parse(path, c.varFiles, c.flagVars, c.CoreConfig.Only, c.CoreConfig.Except)
|
||||
cfg, diags := parser.Parse(path, c.varFiles, c.flagVars)
|
||||
{
|
||||
// write HCL errors/diagnostics if any.
|
||||
b := bytes.NewBuffer(nil)
|
||||
@ -122,6 +122,24 @@ func (c *BuildCommand) GetBuildsFromHCL(path string) ([]packer.Build, int) {
|
||||
ret = 1
|
||||
}
|
||||
|
||||
builds, diags := cfg.GetBuilds(c.CoreConfig.Only, c.CoreConfig.Except)
|
||||
{
|
||||
// write HCL errors/diagnostics if any.
|
||||
b := bytes.NewBuffer(nil)
|
||||
err := hcl.NewDiagnosticTextWriter(b, parser.Files(), 80, false).WriteDiagnostics(diags)
|
||||
if err != nil {
|
||||
c.Ui.Error("could not write diagnostic: " + err.Error())
|
||||
return nil, 1
|
||||
}
|
||||
if b.Len() != 0 {
|
||||
c.Ui.Message(b.String())
|
||||
}
|
||||
}
|
||||
ret = 0
|
||||
if diags.HasErrors() {
|
||||
ret = 1
|
||||
}
|
||||
|
||||
return builds, ret
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,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, tt.args.varFiles, tt.args.vars)
|
||||
gotCfg, gotDiags := tt.parser.Parse(tt.args.filename, tt.args.varFiles, tt.args.vars)
|
||||
if tt.parseWantDiags == (gotDiags == nil) {
|
||||
t.Fatalf("Parser.parse() unexpected %q diagnostics.", gotDiags)
|
||||
}
|
||||
@ -116,7 +116,7 @@ func testParse(t *testing.T, tests []parseTest) {
|
||||
return
|
||||
}
|
||||
|
||||
gotBuilds, gotDiags := gotCfg.getBuilds(nil, nil)
|
||||
gotBuilds, gotDiags := gotCfg.GetBuilds(nil, nil)
|
||||
if tt.getBuildsWantDiags == (gotDiags == nil) {
|
||||
t.Fatalf("Parser.getBuilds() unexpected diagnostics. %s", gotDiags)
|
||||
}
|
||||
|
@ -52,7 +52,11 @@ const (
|
||||
hcl2VarJsonFileExt = ".auto.pkrvars.json"
|
||||
)
|
||||
|
||||
func (p *Parser) parse(filename string, varFiles []string, argVars map[string]string) (*PackerConfig, hcl.Diagnostics) {
|
||||
// Parse will Parse HCL file(s) in path. Path can be a folder or a file.
|
||||
//
|
||||
// Parse will first Parse variables and then the rest; so that interpolation
|
||||
// can happen.
|
||||
func (p *Parser) Parse(filename string, varFiles []string, argVars map[string]string) (*PackerConfig, hcl.Diagnostics) {
|
||||
|
||||
var files []*hcl.File
|
||||
var diags hcl.Diagnostics
|
||||
|
@ -7,8 +7,6 @@ import (
|
||||
"github.com/hashicorp/packer/helper/common"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
)
|
||||
|
||||
// PackerConfig represents a loaded Packer HCL config. It will contain
|
||||
@ -253,10 +251,10 @@ func (cfg *PackerConfig) getCoreBuildPostProcessors(source *SourceBlock, blocks
|
||||
return res, diags
|
||||
}
|
||||
|
||||
// getBuilds will return a list of packer Build based on the HCL2 parsed build
|
||||
// GetBuilds returns a list of packer Build based on the HCL2 parsed build
|
||||
// blocks. All Builders, Provisioners and Post Processors will be started and
|
||||
// configured.
|
||||
func (cfg *PackerConfig) getBuilds(onlyGlobs []glob.Glob, exceptGlobs []glob.Glob) ([]packer.Build, hcl.Diagnostics) {
|
||||
func (cfg *PackerConfig) GetBuilds(only, except []string) ([]packer.Build, hcl.Diagnostics) {
|
||||
res := []packer.Build{}
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
@ -276,7 +274,11 @@ func (cfg *PackerConfig) getBuilds(onlyGlobs []glob.Glob, exceptGlobs []glob.Glo
|
||||
buildName := fmt.Sprintf("%s.%s", src.Type, src.Name)
|
||||
|
||||
// -only
|
||||
if len(onlyGlobs) > 0 {
|
||||
if len(only) > 0 {
|
||||
onlyGlobs, diags := convertFilterOption(only, "only")
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
include := false
|
||||
for _, onlyGlob := range onlyGlobs {
|
||||
if onlyGlob.Match(buildName) {
|
||||
@ -290,7 +292,11 @@ func (cfg *PackerConfig) getBuilds(onlyGlobs []glob.Glob, exceptGlobs []glob.Glo
|
||||
}
|
||||
|
||||
// -except
|
||||
if len(exceptGlobs) > 0 {
|
||||
if len(except) > 0 {
|
||||
exceptGlobs, diags := convertFilterOption(except, "except")
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
exclude := false
|
||||
for _, exceptGlob := range exceptGlobs {
|
||||
if exceptGlob.Match(buildName) {
|
||||
@ -356,60 +362,3 @@ func (cfg *PackerConfig) getBuilds(onlyGlobs []glob.Glob, exceptGlobs []glob.Glo
|
||||
}
|
||||
return res, diags
|
||||
}
|
||||
|
||||
// Convert -only and -except globs to glob.Glob instances.
|
||||
func convertFilterOption(patterns []string, optionName string) ([]glob.Glob, hcl.Diagnostics) {
|
||||
var globs []glob.Glob
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
for _, pattern := range patterns {
|
||||
g, err := glob.Compile(pattern)
|
||||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Summary: fmt.Sprintf("Invalid -%s pattern %s: %s", optionName, pattern, err),
|
||||
Severity: hcl.DiagError,
|
||||
})
|
||||
}
|
||||
globs = append(globs, g)
|
||||
}
|
||||
|
||||
return globs, diags
|
||||
}
|
||||
|
||||
// Parse will parse HCL file(s) in path. Path can be a folder or a file.
|
||||
//
|
||||
// Parse will first parse variables and then the rest; so that interpolation
|
||||
// can happen.
|
||||
//
|
||||
// For each build block a packer.Build will be started, and for each builder,
|
||||
// all provisioners and post-processors will be started.
|
||||
//
|
||||
// Parse then return a slice of packer.Builds; which are what packer core uses
|
||||
// to run builds.
|
||||
func (p *Parser) Parse(path string, varFiles []string, argVars map[string]string, onlyBuilds []string, exceptBuilds []string) ([]packer.Build, hcl.Diagnostics) {
|
||||
var onlyGlobs []glob.Glob
|
||||
if len(onlyBuilds) > 0 {
|
||||
og, diags := convertFilterOption(onlyBuilds, "only")
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
onlyGlobs = og
|
||||
}
|
||||
|
||||
var exceptGlobs []glob.Glob
|
||||
if len(exceptBuilds) > 0 {
|
||||
eg, diags := convertFilterOption(exceptBuilds, "except")
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
exceptGlobs = eg
|
||||
}
|
||||
|
||||
cfg, diags := p.parse(path, varFiles, argVars)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
builds, moreDiags := cfg.getBuilds(onlyGlobs, exceptGlobs)
|
||||
return builds, append(diags, moreDiags...)
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
package hcl2template
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
)
|
||||
|
||||
@ -88,3 +90,22 @@ func GetHCL2Files(filename, hclSuffix, jsonSuffix string) (hclFiles, jsonFiles [
|
||||
|
||||
return hclFiles, jsonFiles, diags
|
||||
}
|
||||
|
||||
// Convert -only and -except globs to glob.Glob instances.
|
||||
func convertFilterOption(patterns []string, optionName string) ([]glob.Glob, hcl.Diagnostics) {
|
||||
var globs []glob.Glob
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
for _, pattern := range patterns {
|
||||
g, err := glob.Compile(pattern)
|
||||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Summary: fmt.Sprintf("Invalid -%s pattern %s: %s", optionName, pattern, err),
|
||||
Severity: hcl.DiagError,
|
||||
})
|
||||
}
|
||||
globs = append(globs, g)
|
||||
}
|
||||
|
||||
return globs, diags
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user