vbauerster / mpb

multi progress bar for Go cli applications
The Unlicense
2.29k stars 123 forks source link

Adding color to one bar on abort adds colors to others in barExtenderRev example #125

Open mmellin opened 1 year ago

mmellin commented 1 year ago

I would like to add some color to the rendered bars, and I like the example barExtenderRev for my purposes. My purpose is to add red color to only the failed task bar, and expect the color of everything else to stay the same. What I am seeing is that when the task is aborted, other tasks and both bars change color to red as well.

I am trying to follow along with the middleware but the workflow is a bit convoluted. Any guidance would be appreciated.

$ go run _examples/barExtenderRev/main.go 
✓  Taksk 00: Done
✓  Taksk 01: Done
✗  Taksk 02: FAILED  <===== I want to color only this line Red
   Taksk 03

current:   [-----------------------------------------------------------------------------------------------------]  0 %
TOTAL(2/4) [==================================>------------------------------------------------------------------] 35 %

What I am seeing:

$ go run _examples/barExtenderRev/main.go 
✓  Taksk 00: Done    <===== RED
✓  Taksk 01: Done
✗  Taksk 02: FAILED <===== RED 
   Taksk 03 <====== Also RED

current:   [-----------------------------------------------------------------------------------------------------]  0 %
TOTAL(2/4) [==================================>------------------------------------------------------------------] 35 % <======== BOTH bars are red

My code changes for v8:

$ git diff _examples/barExtenderRev/main.go
diff --git a/_examples/barExtenderRev/main.go b/_examples/barExtenderRev/main.go
index d0544c1..eeea6b5 100644
--- a/_examples/barExtenderRev/main.go
+++ b/_examples/barExtenderRev/main.go
@@ -7,6 +7,7 @@ import (
        "sync/atomic"
        "time"

+       "github.com/fatih/color"
        "github.com/vbauerster/mpb/v8"
        "github.com/vbauerster/mpb/v8/decor"
 )
@@ -70,19 +71,31 @@ func main() {

        tb.SetTotal(total, false)

-       for _, t := range tasks {
+       aborting := false
+       for i, t := range tasks {

-       p.Wait()
+       // p.Wait()
 }

 func middleware(base mpb.BarFiller, id uint32) mpb.BarFiller {
        var done bool
+       red := color.New(color.FgRed).SprintFunc()
        fn := func(w io.Writer, st decor.Statistics) error {
                if !done {
                        cur := atomic.LoadUint32(&curTask) == id
@@ -91,12 +104,18 @@ func middleware(base mpb.BarFiller, id uint32) mpb.BarFiller {
                                return err
                        }
                        if !st.Completed {
-                               _, err := fmt.Fprintf(w, "=> Taksk %02d\n", id)
-                               return err
+                               if st.Aborted {
+                                       _, err := fmt.Fprintf(w, red("✗  Taksk %02d: FAILED\n"), id)
+                                       return err
+                               } else {
+                                       _, err := fmt.Fprintf(w, "=> Taksk %02d\n", id)
+                                       return err
+                               }
                        }
                        done = cur
                }
-               _, err := fmt.Fprintf(w, "   Taksk %02d: Done!\n", id)
+
+               _, err := fmt.Fprintf(w, "✓  Taksk %02d: Done\n", id)
                return err
        }
        if base == nil {
@@ -132,3 +151,9 @@ func complete(tb *mpb.Bar, t *task) {
        }
        bar.Wait()
 }
+
+func abort(tb *mpb.Bar, t *task) {
+       bar := t.bar
+       bar.Abort(false)
+       bar.Wait()
+}
(END)
vbauerster commented 1 year ago

This sounds like closing escape sequence is not applied.