From e88b800d29a6cf3d01743c1c3085956895e3f218 Mon Sep 17 00:00:00 2001 From: Naveen Mahalingam Date: Sun, 2 Oct 2022 16:21:13 -0700 Subject: [PATCH] progress: support pinned messages with multiple lines (#233) --- cmd/demo-progress/demo.go | 6 +- progress/progress.go | 15 +-- progress/progress_test.go | 8 -- progress/render.go | 21 +++-- progress/render_test.go | 194 +++++++++++++++++++------------------- progress/style.go | 2 +- progress/writer.go | 1 - 7 files changed, 117 insertions(+), 130 deletions(-) diff --git a/cmd/demo-progress/demo.go b/cmd/demo-progress/demo.go index d214b4b..087f463 100644 --- a/cmd/demo-progress/demo.go +++ b/cmd/demo-progress/demo.go @@ -90,10 +90,8 @@ func trackSomething(pw progress.Writer, idx int64, updateMessage bool) { tracker.MarkAsErrored() } pw.SetPinnedMessages( - fmt.Sprintf("Current Time: %s | Total Time: %s", - time.Now().Format(time.RFC3339), - time.Now().Sub(timeStart).Round(time.Second), - ), + fmt.Sprintf(">> Current Time: %-32s", time.Now().Format(time.RFC3339)), + fmt.Sprintf(">> Total Time: %-32s", time.Now().Sub(timeStart).Round(time.Millisecond)), ) case <-updateTicker: if updateMessage { diff --git a/progress/progress.go b/progress/progress.go index fdd683a..cf843c5 100644 --- a/progress/progress.go +++ b/progress/progress.go @@ -35,7 +35,8 @@ type Progress struct { overallTracker *Tracker overallTrackerMutex sync.RWMutex pinnedMessages []string - pinnedMessagesMutex sync.RWMutex + pinnedMessageMutex sync.RWMutex + pinnedMessageNumLines int renderInProgress bool renderInProgressMutex sync.RWMutex sortBy SortBy @@ -157,14 +158,6 @@ func (p *Progress) Log(msg string, a ...interface{}) { p.logsToRenderMutex.Unlock() } -// PinnedMessages returns the current pinned messages. -func (p *Progress) PinnedMessages() []string { - p.pinnedMessagesMutex.RLock() - defer p.pinnedMessagesMutex.RUnlock() - - return p.pinnedMessages -} - // SetAutoStop toggles the auto-stop functionality. Auto-stop set to true would // mean that the Render() function will automatically stop once all currently // active Trackers reach their final states. When set to false, the client code @@ -197,8 +190,8 @@ func (p *Progress) SetOutputWriter(writer io.Writer) { // progress bar. This method can be used to overwrite all the pinned messages. // Call this function without arguments to "clear" the pinned messages. func (p *Progress) SetPinnedMessages(messages ...string) { - p.pinnedMessagesMutex.Lock() - defer p.pinnedMessagesMutex.Unlock() + p.pinnedMessageMutex.Lock() + defer p.pinnedMessageMutex.Unlock() p.pinnedMessages = messages } diff --git a/progress/progress_test.go b/progress/progress_test.go index cb7ed56..3dd9322 100644 --- a/progress/progress_test.go +++ b/progress/progress_test.go @@ -95,14 +95,6 @@ func TestProgress_Log(t *testing.T) { assert.Len(t, p.logsToRender, 1) } -func TestProgress_PinnedMessages(t *testing.T) { - p := Progress{} - assert.Nil(t, p.pinnedMessages) - - p.pinnedMessages = []string{"pin1", "pin2"} - assert.Equal(t, []string{"pin1", "pin2"}, p.PinnedMessages()) -} - func TestProgress_SetAutoStop(t *testing.T) { p := Progress{} assert.False(t, p.autoStop) diff --git a/progress/render.go b/progress/render.go index 18f8c6c..20f510d 100644 --- a/progress/render.go +++ b/progress/render.go @@ -159,22 +159,28 @@ func (p *Progress) moveCursorToTheTop(out *strings.Builder) { numLinesToMoveUp++ } if p.style.Visibility.Pinned { - numLinesToMoveUp += len(p.pinnedMessages) + numLinesToMoveUp += p.pinnedMessageNumLines } - if numLinesToMoveUp > 0 { - out.WriteString(text.CursorUp.Sprintn(numLinesToMoveUp)) + for numLinesToMoveUp > 0 { + out.WriteString(text.CursorUp.Sprint()) + out.WriteString(text.EraseLine.Sprint()) + numLinesToMoveUp-- } } func (p *Progress) renderPinnedMessages(out *strings.Builder) { - p.pinnedMessagesMutex.RLock() - defer p.pinnedMessagesMutex.RUnlock() + p.pinnedMessageMutex.RLock() + defer p.pinnedMessageMutex.RUnlock() + numLines := len(p.pinnedMessages) for _, msg := range p.pinnedMessages { - out.WriteString(text.EraseLine.Sprint()) - out.WriteString(p.Style().Colors.Pinned.Sprint(msg)) + msg = strings.TrimSpace(msg) + out.WriteString(p.style.Colors.Pinned.Sprint(msg)) out.WriteRune('\n') + + numLines += strings.Count(msg, "\n") } + p.pinnedMessageNumLines = numLines } func (p *Progress) renderTracker(out *strings.Builder, t *Tracker, hint renderHint) { @@ -194,7 +200,6 @@ func (p *Progress) renderTracker(out *strings.Builder, t *Tracker, hint renderHi } } - out.WriteString(text.EraseLine.Sprint()) if hint.isOverallTracker { if !t.IsDone() { hint := renderHint{hideValue: true, isOverallTracker: true} diff --git a/progress/render_test.go b/progress/render_test.go index b5cd5db..bd0dbda 100644 --- a/progress/render_test.go +++ b/progress/render_test.go @@ -417,12 +417,12 @@ func TestProgress_RenderSomeTrackers_OnLeftSide(t *testing.T) { renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[K\d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms] \.\.\. Calculating Total # 1`), - regexp.MustCompile(`\x1b\[K\d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms] \.\.\. Downloading File # 2`), - regexp.MustCompile(`\x1b\[K\d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms] \.\.\. Transferring Amount # 3`), - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`\d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms] \.\.\. Calculating Total # 1`), + regexp.MustCompile(`\d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms] \.\.\. Downloading File # 2`), + regexp.MustCompile(`\d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms] \.\.\. Transferring Amount # 3`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), } out := renderOutput.String() for _, expectedOutPattern := range expectedOutPatterns { @@ -445,12 +445,12 @@ func TestProgress_RenderSomeTrackers_OnRightSide(t *testing.T) { renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), } out := renderOutput.String() for _, expectedOutPattern := range expectedOutPatterns { @@ -474,12 +474,12 @@ func TestProgress_RenderSomeTrackers_WithAutoStop(t *testing.T) { renderAndWait(pw, true) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), } out := renderOutput.String() for _, expectedOutPattern := range expectedOutPatterns { @@ -501,12 +501,12 @@ func TestProgress_RenderSomeTrackers_WithError(t *testing.T) { renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. \?\?\? \[[<#>.]{23}] \[\$\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. fail! \[\$\d+ in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. \?\?\? \[[<#>.]{23}] \[\$\d+ in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. fail! \[\$\d+ in [\d.]+ms]`), } out := renderOutput.String() for _, expectedOutPattern := range expectedOutPatterns { @@ -528,12 +528,12 @@ func TestProgress_RenderSomeTrackers_WithIndeterminateTracker(t *testing.T) { renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. \?\?\? \[[<#>.]{23}] \[\$\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. \?\?\? \[[<#>.]{23}] \[\$\d+ in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), } out := renderOutput.String() for _, expectedOutPattern := range expectedOutPatterns { @@ -557,12 +557,12 @@ func TestProgress_RenderSomeTrackers_WithLineWidth1(t *testing.T) { renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KCalc~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDown~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTran~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KCalc~ \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDown~ \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTran~ \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Calc~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), + regexp.MustCompile(`Down~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), + regexp.MustCompile(`Tran~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), + regexp.MustCompile(`Calc~ \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Down~ \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Tran~ \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), } out := renderOutput.String() for _, expectedOutPattern := range expectedOutPatterns { @@ -586,12 +586,12 @@ func TestProgress_RenderSomeTrackers_WithLineWidth2(t *testing.T) { renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KCalculating Total # 1\s{28}\.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2\s{28}\.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3\s{28}\.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KCalculating Total # 1\s{28}\.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2\s{28}\.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3\s{28}\.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1\s{28}\.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2\s{28}\.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3\s{28}\.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1\s{28}\.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2\s{28}\.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3\s{28}\.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), } out := renderOutput.String() for _, expectedOutPattern := range expectedOutPatterns { @@ -619,13 +619,13 @@ func TestProgress_RenderSomeTrackers_WithOverallTracker(t *testing.T) { renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[K\[[.#]+] \[[\d.ms]+; ~ETA: [\d.ms]+`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`\[[.#]+] \[[\d.ms]+; ~ETA: [\d.ms]+`), regexp.MustCompile(`some information about something that happened at \d\d\d\d`), } out := renderOutput.String() @@ -656,13 +656,13 @@ func TestProgress_RenderSomeTrackers_WithOverallTracker_WithoutETAOverall(t *tes renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[K\[[.#]+] \[[\d.ms]+]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`\[[.#]+] \[[\d.ms]+]`), regexp.MustCompile(`some information about something that happened at \d\d\d\d`), } out := renderOutput.String() @@ -689,12 +689,12 @@ func TestProgress_RenderSomeTrackers_WithoutOverallTracker_WithETA(t *testing.T) renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms; ~ETA: [\d]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms; ~ETA: [\d]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms; ~ETA: [\d]+ms]`), - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms; ~ETA: [\d]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms; ~ETA: [\d]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms; ~ETA: [\d]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), } out := renderOutput.String() for _, expectedOutPattern := range expectedOutPatterns { @@ -724,13 +724,13 @@ func TestProgress_RenderSomeTrackers_WithOverallTracker_WithSpeedAndSpeedOverall renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms; \d+\.\d+\w+/s]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms; \d+\.\d+KB/s]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms; \$\d+\.\d+\w+/s]`), - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms; \d+\.\d+K/s]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms; \d+\.\d+KB/s]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms; \$\d+\.\d+K/s]`), - regexp.MustCompile(`\x1b\[K\[[.#]+] \[[\d.ms]+; ~ETA: [\d.ms]+]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms; \d+\.\d+\w+/s]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms; \d+\.\d+KB/s]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms; \$\d+\.\d+\w+/s]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms; \d+\.\d+K/s]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms; \d+\.\d+KB/s]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms; \$\d+\.\d+K/s]`), + regexp.MustCompile(`\[[.#]+] \[[\d.ms]+; ~ETA: [\d.ms]+]`), regexp.MustCompile(`some information about something that happened at \d\d\d\d`), } out := renderOutput.String() @@ -761,12 +761,12 @@ func TestProgress_RenderSomeTrackers_WithoutOverallTracker_WithSpeedOnLeft(t *te renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+\.\d+\w+/s; \d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[[\d.]+(B|KB)/s; \d+(B|KB) in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+\.\d+\w+/s; \$\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. done! \[\d+\.\d+\w+/s; \d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. done! \[\d+\.\d+KB/s; \d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. done! \[\$\d+\.\d+\w+/s; \$\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+\.\d+\w+/s; \d+ in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[[\d.]+(B|KB)/s; \d+(B|KB) in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+\.\d+\w+/s; \$\d+ in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. done! \[\d+\.\d+\w+/s; \d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. done! \[\d+\.\d+KB/s; \d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. done! \[\$\d+\.\d+\w+/s; \$\d+\.\d+K in [\d.]+ms]`), } out := renderOutput.String() for _, expectedOutPattern := range expectedOutPatterns { @@ -798,13 +798,13 @@ func TestProgress_RenderSomeTrackers_WithOverallTracker_WithSpeedOverall_Without renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KCalculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDownloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTransferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[K\[[.#]+] \[\d+.\d+\w+/s; [\d.ms]+; ~ETA: [\d.ms]+]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), + regexp.MustCompile(`Calculating Total # 1 \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Downloading File # 2 \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Transferring Amount # 3 \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`\[[.#]+] \[\d+.\d+\w+/s; [\d.ms]+; ~ETA: [\d.ms]+]`), regexp.MustCompile(`some information about something that happened at \d\d\d\d`), } out := renderOutput.String() @@ -831,13 +831,13 @@ func TestProgress_RenderSomeTrackers_WithPinMessage_OneLine(t *testing.T) { renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KPIN`), - regexp.MustCompile(`\x1b\[KCalc~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDown~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTran~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KCalc~ \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDown~ \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTran~ \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`PIN`), + regexp.MustCompile(`Calc~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), + regexp.MustCompile(`Down~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), + regexp.MustCompile(`Tran~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), + regexp.MustCompile(`Calc~ \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Down~ \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Tran~ \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), } out := renderOutput.String() for _, expectedOutPattern := range expectedOutPatterns { @@ -863,14 +863,14 @@ func TestProgress_RenderSomeTrackers_WithPinMessage_MultiLines(t *testing.T) { renderAndWait(pw, false) expectedOutPatterns := []*regexp.Regexp{ - regexp.MustCompile(`\x1b\[KPIN`), - regexp.MustCompile(`\x1b\[KPIN2`), - regexp.MustCompile(`\x1b\[KCalc~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDown~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTran~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KCalc~ \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KDown~ \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), - regexp.MustCompile(`\x1b\[KTran~ \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`PIN`), + regexp.MustCompile(`PIN2`), + regexp.MustCompile(`Calc~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`), + regexp.MustCompile(`Down~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`), + regexp.MustCompile(`Tran~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`), + regexp.MustCompile(`Calc~ \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`), + regexp.MustCompile(`Down~ \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`), + regexp.MustCompile(`Tran~ \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`), } out := renderOutput.String() for _, expectedOutPattern := range expectedOutPatterns { diff --git a/progress/style.go b/progress/style.go index 536f308..50f1945 100644 --- a/progress/style.go +++ b/progress/style.go @@ -139,7 +139,7 @@ var ( Message: text.Colors{text.FgWhite}, Error: text.Colors{text.FgRed}, Percent: text.Colors{text.FgHiRed}, - Pinned: text.Colors{text.BgHiBlack, text.Bold, text.Underline}, + Pinned: text.Colors{text.BgHiBlack, text.FgWhite, text.Bold}, Stats: text.Colors{text.FgHiBlack}, Time: text.Colors{text.FgGreen}, Tracker: text.Colors{text.FgYellow}, diff --git a/progress/writer.go b/progress/writer.go index 153273a..71863f1 100644 --- a/progress/writer.go +++ b/progress/writer.go @@ -16,7 +16,6 @@ type Writer interface { LengthDone() int LengthInQueue() int Log(msg string, a ...interface{}) - PinnedMessages() []string SetAutoStop(autoStop bool) SetMessageWidth(width int) SetNumTrackersExpected(numTrackers int)