diff --git a/command/build/command.go b/command/build/command.go index 35601bed1..e252b0e98 100644 --- a/command/build/command.go +++ b/command/build/command.go @@ -9,7 +9,7 @@ type Command byte func (Command) Run(env packer.Environment, args []string) int { if len(args) != 1 { - // TODO: Error message + env.Ui().Error("A single template argument is required.\n") return 1 } diff --git a/packer/rpc/ui.go b/packer/rpc/ui.go index ed5450285..710428057 100644 --- a/packer/rpc/ui.go +++ b/packer/rpc/ui.go @@ -22,11 +22,23 @@ type UiSayArgs struct { Vars []interface{} } +func (u *Ui) Error(format string, a ...interface{}) { + args := &UiSayArgs{format, a} + u.client.Call("Ui.Error", args, new(interface{})) +} + func (u *Ui) Say(format string, a ...interface{}) { args := &UiSayArgs{format, a} u.client.Call("Ui.Say", args, new(interface{})) } +func (u *UiServer) Error(args *UiSayArgs, reply *interface{}) error { + u.ui.Error(args.Format, args.Vars...) + + *reply = nil + return nil +} + func (u *UiServer) Say(args *UiSayArgs, reply *interface{}) error { u.ui.Say(args.Format, args.Vars...) diff --git a/packer/rpc/ui_test.go b/packer/rpc/ui_test.go index 1b275cfdb..d15568dbf 100644 --- a/packer/rpc/ui_test.go +++ b/packer/rpc/ui_test.go @@ -7,11 +7,20 @@ import ( ) type testUi struct { + errorCalled bool + errorFormat string + errorVars []interface{} sayCalled bool sayFormat string sayVars []interface{} } +func (u *testUi) Error(format string, a ...interface{}) { + u.errorCalled = true + u.errorFormat = format + u.errorVars = a +} + func (u *testUi) Say(format string, a ...interface{}) { u.sayCalled = true u.sayFormat = format @@ -36,7 +45,10 @@ func TestUiRPC(t *testing.T) { } uiClient := &Ui{client} - uiClient.Say("format", "arg0", 42) + uiClient.Error("format", "arg0", 42) + assert.Equal(ui.errorFormat, "format", "format should be correct") + + uiClient.Say("format", "arg0", 42) assert.Equal(ui.sayFormat, "format", "format should be correct") } diff --git a/packer/ui.go b/packer/ui.go index c8ee559d8..372102b89 100644 --- a/packer/ui.go +++ b/packer/ui.go @@ -8,6 +8,7 @@ import "io" // is formatted and various levels of output. type Ui interface { Say(format string, a ...interface{}) + Error(format string, a...interface{}) } // The ReaderWriterUi is a UI that writes and reads from standard Go @@ -20,3 +21,7 @@ type ReaderWriterUi struct { func (rw *ReaderWriterUi) Say(format string, a ...interface{}) { fmt.Fprintf(rw.Writer, format, a...) } + +func (rw *ReaderWriterUi) Error(format string, a ...interface{}) { + fmt.Fprintf(rw.Writer, format, a...) +} diff --git a/packer/ui_test.go b/packer/ui_test.go index 2fa0fa9e1..aab719959 100644 --- a/packer/ui_test.go +++ b/packer/ui_test.go @@ -13,6 +13,18 @@ func testUi() *ReaderWriterUi { } } +func TestReaderWriterUi_Error(t *testing.T) { + assert := asserts.NewTestingAsserts(t, true) + + bufferUi := testUi() + + bufferUi.Error("foo") + assert.Equal(readWriter(bufferUi), "foo", "basic output") + + bufferUi.Error("%d", 5) + assert.Equal(readWriter(bufferUi), "5", "formatting") +} + func TestReaderWriterUi_Say(t *testing.T) { assert := asserts.NewTestingAsserts(t, true)