packer: Add MachineReadableUi

This commit is contained in:
Mitchell Hashimoto 2013-08-11 19:05:07 -07:00
parent edc59499e7
commit 89be12ae21
2 changed files with 85 additions and 0 deletions

View File

@ -11,6 +11,7 @@ import (
"runtime"
"strings"
"sync"
"time"
"unicode"
)
@ -63,6 +64,12 @@ type BasicUi struct {
interrupted bool
}
// MachineReadableUi is a UI that only outputs machine-readable output
// to the given Writer.
type MachineReadableUi struct {
Writer io.Writer
}
func (u *ColoredUi) Ask(query string) (string, error) {
return u.Ui.Ask(u.colorize(query, u.Color, true))
}
@ -232,3 +239,42 @@ func (rw *BasicUi) Error(message string) {
func (rw *BasicUi) Machine(t string, args ...string) {
log.Printf("machine readable: %s %#v", t, args)
}
func (u *MachineReadableUi) Ask(query string) (string, error) {
return "", errors.New("machine-readable UI can't ask")
}
func (u *MachineReadableUi) Say(message string) {
u.Machine("ui", "say", message)
}
func (u *MachineReadableUi) Message(message string) {
u.Machine("ui", "message", message)
}
func (u *MachineReadableUi) Error(message string) {
u.Machine("ui", "error", message)
}
func (u *MachineReadableUi) Machine(category string, args ...string) {
now := time.Now().UTC()
// Determine if we have a target, and set it
target := ""
commaIdx := strings.Index(category, ",")
if commaIdx > -1 {
target = category[0:commaIdx]
category = category[commaIdx+1:]
}
// Prepare the args
for i, v := range args {
args[i] = strings.Replace(v, ",", "%!(PACKER_COMMA)", -1)
}
argsString := strings.Join(args, ",")
_, err := fmt.Fprintf(u.Writer, "%d,%s,%s,%s", now.Unix(), target, category, argsString)
if err != nil {
panic(err)
}
}

View File

@ -3,6 +3,7 @@ package packer
import (
"bytes"
"cgl.tideland.biz/asserts"
"strings"
"testing"
)
@ -106,6 +107,44 @@ func TestBasicUi_Say(t *testing.T) {
assert.Equal(readWriter(bufferUi), "5\n", "formatting")
}
func TestMachineReadableUi_ImplUi(t *testing.T) {
var raw interface{}
raw = &MachineReadableUi{}
if _, ok := raw.(Ui); !ok {
t.Fatalf("MachineReadableUi must implement Ui")
}
}
func TestMachineReadableUi(t *testing.T) {
var data, expected string
buf := new(bytes.Buffer)
ui := &MachineReadableUi{Writer: buf}
ui.Machine("foo", "bar", "baz")
data = strings.SplitN(buf.String(), ",", 2)[1]
expected = ",foo,bar,baz"
if data != expected {
t.Fatalf("bad: %s", data)
}
buf.Reset()
ui.Machine("mitchellh,foo", "bar", "baz")
data = strings.SplitN(buf.String(), ",", 2)[1]
expected = "mitchellh,foo,bar,baz"
if data != expected {
t.Fatalf("bad: %s", data)
}
buf.Reset()
ui.Machine("foo", "foo,bar")
data = strings.SplitN(buf.String(), ",", 2)[1]
expected = ",foo,foo%!(PACKER_COMMA)bar"
if data != expected {
t.Fatalf("bad: %s", data)
}
}
// This reads the output from the bytes.Buffer in our test object
// and then resets the buffer.
func readWriter(ui *BasicUi) (result string) {