From a06abd749371c1a1877f1a607412b09e0d64d6b7 Mon Sep 17 00:00:00 2001 From: Zhang Wei Date: Fri, 13 Oct 2017 22:41:09 +0800 Subject: [PATCH] [progress] Fix wrong display of progress bar When we try to pull an image with "ctr pull xxx", the progress bar display will flush all the screen and make it so hard to find useful information for user. This commit fixes bugs for the progress bar, by correcting "line counting" algorithm. Previous algorithm only counts number of "\n", but one line can be longer than screen width, in which case it should be counted as two lines. Also updated the screen cleaning ESC chars. Signed-off-by: Zhang Wei --- progress/writer.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/progress/writer.go b/progress/writer.go index 4138d7a52..8530ab3e6 100644 --- a/progress/writer.go +++ b/progress/writer.go @@ -4,6 +4,9 @@ import ( "bytes" "fmt" "io" + "strings" + + "github.com/containerd/console" ) // Writer buffers writes until flush, at which time the last screen is cleared @@ -38,7 +41,15 @@ func (w *Writer) Flush() error { return err } - w.lines = bytes.Count(w.buf.Bytes(), []byte("\n")) + ws, err := console.Current().Size() + if err != nil { + return fmt.Errorf("failed to get terminal width: %v", err) + } + strlines := strings.Split(w.buf.String(), "\n") + w.lines = -1 + for _, line := range strlines { + w.lines += len(line)/int(ws.Width) + 1 + } if _, err := w.w.Write(w.buf.Bytes()); err != nil { return err @@ -53,7 +64,7 @@ func (w *Writer) Flush() error { func (w *Writer) clear() error { for i := 0; i < w.lines; i++ { - if _, err := fmt.Fprintf(w.w, "\x1b[0A\x1b[2K\r"); err != nil { + if _, err := fmt.Fprintf(w.w, "\x1b[1A\x1b[2K\r"); err != nil { return err } }