From b1527e0a106faaf5234b8a10ed3c1190c32bbf8a Mon Sep 17 00:00:00 2001 From: Phil Estes Date: Thu, 9 Nov 2017 15:58:51 -0500 Subject: [PATCH] Handle progress line length properly for formatting Two issues with a prior PR for handling line-spanning progress bars are fixed in this PR: - corner case where output line len == term width: extra line was being added - line length calculation was including escape characters causing calculations to span lines when output was still only on one line Signed-off-by: Phil Estes --- progress/writer.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/progress/writer.go b/progress/writer.go index 8530ab3e6..54cf94688 100644 --- a/progress/writer.go +++ b/progress/writer.go @@ -4,11 +4,16 @@ import ( "bytes" "fmt" "io" + "regexp" "strings" "github.com/containerd/console" ) +var ( + regexCleanLine = regexp.MustCompile("\x1b\\[[0-9]+m[\x1b]?") +) + // Writer buffers writes until flush, at which time the last screen is cleared // and the current buffer contents are written. This is useful for // implementing progress displays, such as those implemented in docker and @@ -48,7 +53,7 @@ func (w *Writer) Flush() error { strlines := strings.Split(w.buf.String(), "\n") w.lines = -1 for _, line := range strlines { - w.lines += len(line)/int(ws.Width) + 1 + w.lines += (len(stripLine(line))-1)/int(ws.Width) + 1 } if _, err := w.w.Write(w.buf.Bytes()); err != nil { @@ -71,3 +76,7 @@ func (w *Writer) clear() error { return nil } + +func stripLine(line string) string { + return string(regexCleanLine.ReplaceAll([]byte(line), []byte{})) +}