diff --git a/command/fix.go b/command/fix.go index e908dc52e..2d9bcce37 100644 --- a/command/fix.go +++ b/command/fix.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/mitchellh/packer/fix" + "github.com/mitchellh/packer/template" ) type FixCommand struct { @@ -16,7 +17,9 @@ type FixCommand struct { } func (c *FixCommand) Run(args []string) int { + var flagValidate bool flags := c.Meta.FlagSet("fix", FlagSetNone) + flags.BoolVar(&flagValidate, "validate", true, "") flags.Usage = func() { c.Ui.Say(c.Help()) } if err := flags.Parse(args); err != nil { return 1 @@ -80,6 +83,28 @@ func (c *FixCommand) Run(args []string) int { result = strings.Replace(result, `\u003c`, "<", -1) result = strings.Replace(result, `\u003e`, ">", -1) c.Ui.Say(result) + + if flagValidate { + // Attemot to parse and validate the template + tpl, err := template.Parse(strings.NewReader(result)) + if err != nil { + c.Ui.Error(fmt.Sprintf( + "Error! Fixed template fails to parse: %s\n\n"+ + "This is usually caused by an error in the input template.\n"+ + "Please fix the error and try again.", + err)) + return 1 + } + if err := tpl.Validate(); err != nil { + c.Ui.Error(fmt.Sprintf( + "Error! Fixed template failed to validate: %s\n\n"+ + "This is usually caused by an error in the input template.\n"+ + "Please fix the error and try again.", + err)) + return 1 + } + } + return 0 } @@ -102,6 +127,10 @@ Fixes that are run: pp-vagrant-override Replaces old-style provider overrides for the Vagrant post-processor to new-style as of Packer 0.5.0. virtualbox-rename Updates "virtualbox" builders to "virtualbox-iso" + +Options: + + -validate=true If true (default), validates the fixed template. ` return strings.TrimSpace(helpText) diff --git a/command/fix_test.go b/command/fix_test.go new file mode 100644 index 000000000..1bf6f1900 --- /dev/null +++ b/command/fix_test.go @@ -0,0 +1,58 @@ +package command + +import ( + "path/filepath" + "testing" +) + +func TestFix_noArgs(t *testing.T) { + c := &PushCommand{Meta: testMeta(t)} + code := c.Run(nil) + if code != 1 { + t.Fatalf("bad: %#v", code) + } +} + +func TestFix_multiArgs(t *testing.T) { + c := &PushCommand{Meta: testMeta(t)} + code := c.Run([]string{"one", "two"}) + if code != 1 { + t.Fatalf("bad: %#v", code) + } +} + +func TestFix(t *testing.T) { + c := &FixCommand{ + Meta: testMeta(t), + } + + args := []string{filepath.Join(testFixture("fix"), "template.json")} + if code := c.Run(args); code != 0 { + fatalCommand(t, c.Meta) + } +} + +func TestFix_invalidTemplate(t *testing.T) { + c := &FixCommand{ + Meta: testMeta(t), + } + + args := []string{filepath.Join(testFixture("fix-invalid"), "template.json")} + if code := c.Run(args); code != 1 { + fatalCommand(t, c.Meta) + } +} + +func TestFix_invalidTemplateDisableValidation(t *testing.T) { + c := &FixCommand{ + Meta: testMeta(t), + } + + args := []string{ + "-validate=false", + filepath.Join(testFixture("fix-invalid"), "template.json"), + } + if code := c.Run(args); code != 0 { + fatalCommand(t, c.Meta) + } +} diff --git a/command/test-fixtures/fix-invalid/template.json b/command/test-fixtures/fix-invalid/template.json new file mode 100644 index 000000000..ea50c5dcf --- /dev/null +++ b/command/test-fixtures/fix-invalid/template.json @@ -0,0 +1,3 @@ +{ + "hello": "world" +} diff --git a/command/test-fixtures/fix/template.json b/command/test-fixtures/fix/template.json new file mode 100644 index 000000000..63b0f9037 --- /dev/null +++ b/command/test-fixtures/fix/template.json @@ -0,0 +1,7 @@ +{ + "builders": [{"type": "dummy"}], + + "push": { + "name": "foo/bar" + } +}