diff --git a/packer/ui.go b/packer/ui.go index badee90e5..7605575b3 100644 --- a/packer/ui.go +++ b/packer/ui.go @@ -6,6 +6,17 @@ import ( "log" ) +type UiColor uint + +const ( + UiColorRed UiColor = 31 + UiColorGreen = 32 + UiColorYellow = 33 + UiColorBlue = 34 + UiColorMagenta = 35 + UiColorCyan = 36 +) + // The Ui interface handles all communication for Packer with the outside // world. This sort of control allows us to strictly control how output // is formatted and various levels of output. @@ -15,6 +26,12 @@ type Ui interface { Error(string) } +// ColoredUi is a UI that is colored using terminal colors. +type ColoredUi struct { + Color UiColor + Ui Ui +} + // PrefixedUi is a UI that wraps another UI implementation and adds a // prefix to all the messages going out. type PrefixedUi struct { @@ -30,6 +47,22 @@ type ReaderWriterUi struct { Writer io.Writer } +func (u *ColoredUi) Say(message string) { + u.Ui.Say(u.colorize(message)) +} + +func (u *ColoredUi) Message(message string) { + u.Ui.Message(u.colorize(message)) +} + +func (u *ColoredUi) Error(message string) { + u.Ui.Error(u.colorize(message)) +} + +func (u *ColoredUi) colorize(message string) string { + return fmt.Sprintf("\033[0;%d;40m%s\033[0m", u.Color, message) +} + func (u *PrefixedUi) Say(message string) { u.Ui.Say(fmt.Sprintf("%s: %s", u.SayPrefix, message)) } diff --git a/packer/ui_test.go b/packer/ui_test.go index 69d480917..9f84af489 100644 --- a/packer/ui_test.go +++ b/packer/ui_test.go @@ -13,6 +13,16 @@ func testUi() *ReaderWriterUi { } } +func TestColoredUi(t *testing.T) { + assert := asserts.NewTestingAsserts(t, true) + + bufferUi := testUi() + ui := &ColoredUi{UiColorRed, bufferUi} + + ui.Say("foo") + assert.Equal(readWriter(bufferUi), "\033[0;31;40mfoo\033[0m\n", "should have color") +} + func TestPrefixedUi(t *testing.T) { assert := asserts.NewTestingAsserts(t, true) @@ -29,6 +39,14 @@ func TestPrefixedUi(t *testing.T) { assert.Equal(readWriter(bufferUi), "mitchell: bar\n", "should have prefix") } +func TestColoredUi_ImplUi(t *testing.T) { + var raw interface{} + raw = &ColoredUi{} + if _, ok := raw.(Ui); !ok { + t.Fatalf("ColoredUi must implement Ui") + } +} + func TestPrefixedUi_ImplUi(t *testing.T) { var raw interface{} raw = &PrefixedUi{}