Merge pull request #9381 from hashicorp/fix_9377_regression

Fix build/validate -except flag for JSON and HCL2
This commit is contained in:
Megan Marsh 2020-06-09 09:24:07 -07:00 committed by GitHub
commit 1c028489ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 259 additions and 20 deletions

View file

@ -368,29 +368,61 @@ func TestBuildExceptFileCommaFlags(t *testing.T) {
c := &BuildCommand{
Meta: testMetaFile(t),
}
args := []string{
"-parallel-builds=1",
"-except=chocolate,vanilla",
filepath.Join(testFixture("build-only"), "template.json"),
tc := []struct {
name string
args []string
expectedFiles []string
buildNotExpectedFiles []string
postProcNotExpectedFiles []string
}{
{
name: "JSON: except build and post-processor",
args: []string{
"-parallel-builds=1",
"-except=chocolate,vanilla,tomato",
filepath.Join(testFixture("build-only"), "template.json"),
},
expectedFiles: []string{"apple.txt", "cherry.txt", "peach.txt"},
buildNotExpectedFiles: []string{"chocolate.txt", "vanilla.txt", "tomato.txt", "unnamed.txt"},
postProcNotExpectedFiles: []string{"pear.txt, banana.txt"},
},
{
name: "HCL2: except build and post-processor",
args: []string{
"-parallel-builds=1",
"-except=file.chocolate,file.vanilla,tomato",
filepath.Join(testFixture("build-only"), "template.pkr.hcl"),
},
expectedFiles: []string{"apple.txt", "cherry.txt", "peach.txt"},
buildNotExpectedFiles: []string{"chocolate.txt", "vanilla.txt", "tomato.txt", "unnamed.txt"},
postProcNotExpectedFiles: []string{"pear.txt, banana.txt"},
},
}
defer cleanup()
for _, tt := range tc {
t.Run(tt.name, func(t *testing.T) {
defer cleanup()
if code := c.Run(args); code != 0 {
fatalCommand(t, c.Meta)
}
if code := c.Run(tt.args); code != 0 {
fatalCommand(t, c.Meta)
}
for _, f := range []string{"chocolate.txt", "vanilla.txt", "tomato.txt",
"unnamed.txt"} {
if fileExists(f) {
t.Errorf("Expected NOT to find %s", f)
}
}
for _, f := range []string{"apple.txt", "cherry.txt", "pear.txt", "peach.txt"} {
if !fileExists(f) {
t.Errorf("Expected to find %s", f)
}
for _, f := range tt.buildNotExpectedFiles {
if fileExists(f) {
t.Errorf("build not skipped: Expected NOT to find %s", f)
}
}
for _, f := range tt.postProcNotExpectedFiles {
if fileExists(f) {
t.Errorf("post-processor not skipped: Expected NOT to find %s", f)
}
}
for _, f := range tt.expectedFiles {
if !fileExists(f) {
t.Errorf("Expected to find %s", f)
}
}
})
}
}
@ -605,6 +637,7 @@ func cleanup(moreFiles ...string) {
os.RemoveAll("cherry.txt")
os.RemoveAll("apple.txt")
os.RemoveAll("peach.txt")
os.RemoveAll("banana.txt")
os.RemoveAll("pear.txt")
os.RemoveAll("tomato.txt")
os.RemoveAll("unnamed.txt")

View file

@ -37,6 +37,11 @@
"name": "pear",
"type": "shell-local",
"inline": [ "echo pear > pear.txt" ]
},
{
"name": "banana",
"type": "shell-local",
"inline": [ "echo pear > banana.txt" ]
}
],
[

View file

@ -0,0 +1,54 @@
source "file" "chocolate" {
content = "chocolate"
target = "chocolate.txt"
}
source "file" "vanilla" {
content = "vanilla"
target = "vanilla.txt"
}
source "file" "cherry" {
content = "cherry"
target = "cherry.txt"
}
build {
sources = [
"sources.file.chocolate",
"sources.file.vanilla",
"sources.file.cherry",
]
post-processor "shell-local" {
name = "apple"
inline = [ "echo apple > apple.txt" ]
}
post-processor "shell-local" {
name = "peach"
inline = [ "echo apple > peach.txt" ]
}
post-processor "shell-local" {
name = "pear"
inline = [ "echo apple > pear.txt" ]
}
post-processor "shell-local" {
name = "banana"
inline = [ "echo apple > banana.txt" ]
}
post-processor "shell-local" {
only = ["vanilla"]
name = "tomato"
inline = [ "echo apple > tomato.txt" ]
}
post-processor "shell-local" {
only = ["chocolate"]
inline = [ "echo apple > unnamed.txt" ]
}
}

View file

@ -0,0 +1,39 @@
{
"builders": [
{
"name": "chocolate",
"type": "file",
"target": "chocolate.txt",
"content": "chocolate"
},
{
"type": "file",
"name": "vanilla"
}
],
"post-processors": [
[
{
"name": "apple",
"type": "shell-local",
"inline": [
"echo apple 'apple'"
]
}
],
[
{
"name": "pear",
"type": "shell-local",
"inline": [
"echo apple 'pear'"
]
},
{
"name": "banana",
"type": "shell-local"
}
]
],
"min_packer_version": "101.0.0"
}

View file

@ -0,0 +1,28 @@
source "file" "chocolate" {
content = "chocolate"
target = "chocolate.txt"
}
source "file" "vanilla" {
content = "vanilla"
}
build {
sources = [
"source.file.chocolate",
"source.file.vanilla"
]
post-processor "shell-local" {
name = "apple"
inline = [ "echo apple 'apple'" ]
}
post-processor "shell-local" {
name = "pear"
inline = [ "echo apple 'pear'" ]
}
post-processor "shell-local" {
name = "banana"
}
}

View file

@ -98,3 +98,58 @@ func TestValidateCommandBadVersion(t *testing.T) {
}
t.Log(stdout)
}
func TestValidateCommandExcept(t *testing.T) {
tt := []struct {
name string
args []string
exitCode int
}{
{
name: "JSON: validate except build and post-processor",
args: []string{
"-except=vanilla,pear",
filepath.Join(testFixture("validate"), "validate_except.json"),
},
},
{
name: "JSON: fail validate except build and post-processor",
args: []string{
"-except=chocolate,apple",
filepath.Join(testFixture("validate"), "validate_except.json"),
},
exitCode: 1,
},
{
name: "HCL2: validate except build and post-processor",
args: []string{
"-except=file.vanilla,pear",
filepath.Join(testFixture("validate"), "validate_except.pkr.hcl"),
},
},
{
name: "HCL2: fail validation except build and post-processor",
args: []string{
"-except=file.chocolate,apple",
filepath.Join(testFixture("validate"), "validate_except.pkr.hcl"),
},
exitCode: 1,
},
}
c := &ValidateCommand{
Meta: testMetaFile(t),
}
c.CoreConfig.Version = "102.0.0"
for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
defer cleanup()
tc := tc
if code := c.Run(tc.args); code != tc.exitCode {
fatalCommand(t, c.Meta)
}
})
}
}

View file

@ -4,6 +4,7 @@ import (
"fmt"
"strings"
"github.com/gobwas/glob"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/packer/helper/common"
@ -37,6 +38,9 @@ type PackerConfig struct {
provisionersSchemas packer.ProvisionerStore
postProcessorsSchemas packer.PostProcessorStore
except []glob.Glob
only []glob.Glob
}
type ValidationOptions struct {
@ -244,6 +248,23 @@ func (cfg *PackerConfig) getCoreBuildPostProcessors(source SourceBlock, blocks [
if ppb.OnlyExcept.Skip(source.Type + "." + source.Name) {
continue
}
name := ppb.PName
if name == "" {
name = ppb.PType
}
// -except
exclude := false
for _, exceptGlob := range cfg.except {
if exceptGlob.Match(name) {
exclude = true
break
}
}
if exclude {
break
}
postProcessor, moreDiags := cfg.startPostProcessor(source, ppb, ectx, generatedVars)
diags = append(diags, moreDiags...)
if moreDiags.HasErrors() {
@ -289,6 +310,7 @@ func (cfg *PackerConfig) GetBuilds(opts packer.GetBuildsOptions) ([]packer.Build
if diags.HasErrors() {
return nil, diags
}
cfg.only = onlyGlobs
include := false
for _, onlyGlob := range onlyGlobs {
if onlyGlob.Match(buildName) {
@ -307,6 +329,7 @@ func (cfg *PackerConfig) GetBuilds(opts packer.GetBuildsOptions) ([]packer.Build
if diags.HasErrors() {
return nil, diags
}
cfg.except = exceptGlobs
exclude := false
for _, exceptGlob := range exceptGlobs {
if exceptGlob.Match(buildName) {

View file

@ -133,6 +133,8 @@ func (c *Core) BuildNames(only, except []string) []string {
sort.Strings(only)
sort.Strings(except)
c.except = except
c.only = only
r := make([]string, 0, len(c.builds))
for n := range c.builds {
@ -319,7 +321,7 @@ func (c *Core) Build(n string) (Build, error) {
}
}
if foundExcept {
continue
break
}
// Get the post-processor