From b422d8da8f1d1e51da6cfff4890e6a08252da7c5 Mon Sep 17 00:00:00 2001 From: Nghia Tran Date: Fri, 20 Feb 2015 19:18:30 -0800 Subject: [PATCH] engine.Tail() to ignore trailing whitespaces. In its current form, if an error message has two trailing "\n" instead of one, an empty line is resulted (see engine/job.go for an example of such usages). Skipping all trailing whitespaces will give a better error message. Signed-off-by: Nghia Tran --- engine/streams.go | 20 +++++++++++--------- engine/streams_test.go | 5 +++++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/engine/streams.go b/engine/streams.go index ec703c96fa..216fb8980a 100644 --- a/engine/streams.go +++ b/engine/streams.go @@ -5,7 +5,9 @@ import ( "fmt" "io" "io/ioutil" + "strings" "sync" + "unicode" ) type Output struct { @@ -16,25 +18,25 @@ type Output struct { } // Tail returns the n last lines of a buffer -// stripped out of the last \n, if any +// stripped out of trailing white spaces, if any. +// // if n <= 0, returns an empty string func Tail(buffer *bytes.Buffer, n int) string { if n <= 0 { return "" } - bytes := buffer.Bytes() - if len(bytes) > 0 && bytes[len(bytes)-1] == '\n' { - bytes = bytes[:len(bytes)-1] - } - for i := buffer.Len() - 2; i >= 0; i-- { - if bytes[i] == '\n' { + s := strings.TrimRightFunc(buffer.String(), unicode.IsSpace) + i := len(s) - 1 + for ; i >= 0 && n > 0; i-- { + if s[i] == '\n' { n-- if n == 0 { - return string(bytes[i+1:]) + break } } } - return string(bytes) + // when i == -1, return the whole string which is s[0:] + return s[i+1:] } // NewOutput returns a new Output object with no destinations attached. diff --git a/engine/streams_test.go b/engine/streams_test.go index 5cfd5d0e6c..476a721baf 100644 --- a/engine/streams_test.go +++ b/engine/streams_test.go @@ -111,6 +111,11 @@ func TestTail(t *testing.T) { "Two\nThree", "One\nTwo\nThree", } + tests["One\nTwo\n\n\n"] = []string{ + "", + "Two", + "One\nTwo", + } for input, outputs := range tests { for n, expectedOutput := range outputs { output := Tail(bytes.NewBufferString(input), n)