From bb698217f8cf3657762f506fe37b52a3ce85f9fa Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 11 Oct 2014 17:35:32 -0700 Subject: [PATCH] command: split on \r too --- command/hook_ui.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/command/hook_ui.go b/command/hook_ui.go index c8911fd71..9c8603698 100644 --- a/command/hook_ui.go +++ b/command/hook_ui.go @@ -175,6 +175,7 @@ func (h *UiHook) ProvisionOutput( prefix := fmt.Sprintf("%s (%s): ", id, provId) s := bufio.NewScanner(strings.NewReader(msg)) + s.Split(scanLines) for s.Scan() { buf.WriteString(fmt.Sprintf("%s%s\n", prefix, s.Text())) } @@ -205,3 +206,33 @@ func (h *UiHook) init() { // underlying reader/writer that is in place. h.ui = &cli.ConcurrentUi{Ui: h.Ui} } + +// scanLines is basically copied from the Go standard library except +// we've modified it to also fine `\r`. +func scanLines(data []byte, atEOF bool) (advance int, token []byte, err error) { + if atEOF && len(data) == 0 { + return 0, nil, nil + } + if i := bytes.IndexByte(data, '\n'); i >= 0 { + // We have a full newline-terminated line. + return i + 1, dropCR(data[0:i]), nil + } + if i := bytes.IndexByte(data, '\r'); i >= 0 { + // We have a full newline-terminated line. + return i + 1, dropCR(data[0:i]), nil + } + // If we're at EOF, we have a final, non-terminated line. Return it. + if atEOF { + return len(data), dropCR(data), nil + } + // Request more data. + return 0, nil, nil +} + +// dropCR drops a terminal \r from the data. +func dropCR(data []byte) []byte { + if len(data) > 0 && data[len(data)-1] == '\r' { + return data[0 : len(data)-1] + } + return data +}