Codebase list golang-github-vbauerster-mpb / b3c5f02 example / gifs / simple.gif
readme Vladimir Bauer 9 years ago
10 changed file(s) with 174 addition(s) and 113 deletion(s). Raw diff Collapse all Expand all
0 # Multi Progress Bar for Go
1
2 Mutex free progress bar library, for console programs.
3
4 It is inspired by [uiprogress](https://github.com/gosuri/uiprogress) library,
5 but unlike the last one, implementation is mutex free, following Go's idiom:
6
7 > Don't communicate by sharing memory, share memory by communicating.
8
9 ## Features
10
11 * __Multiple Bars__: mpb can render multiple progress bars that can be tracked concurrently
12 * __Dynamic Addition__: Add additional progress bar at any time
13 * __Dynamic Removal__: Remove rendering progress bar at any time
14 * __Dynamic Sorting__: Sort bars by progression
15 * __Custom Decorator Functions__: Add custom functions around the bar along with helper functions
16 * __Predefined Decoratros__: Elapsed time, [Ewmaest](https://github.com/dgryski/trifles/tree/master/ewmaest) based ETA, Percentage, Bytes counter
17
18 ## Usage
19
20 Following is the simplest use case:
21
22 ```go
23 // No need to initialize sync.WaitGroup, as it is initialized implicitly
24 p := mpb.New() // Star mpb container
25 for i := 0; i < 3; i++ {
26 p.Wg.Add(1) // add wg counter
27 name := fmt.Sprintf("Bar#%d:", i)
28 bar := p.AddBar(100).PrependName(name, len(name)).AppendPercentage()
29 go func() {
30 // you can p.AddBar() here, but ordering will be non deterministic
31 for i := 0; i < 100; i++ {
32 time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
33 bar.Incr(1)
34 }
35 }()
36 }
37 p.WaitAndStop() // Wait for goroutines to finish
38 // p.AddBar(1) // panic: you cannot reuse p, create new one!
39 fmt.Println("finish")
40 ```
41
42 This will produce following:
43
44 ![example](example/gifs/simple.gif)
45
46 ### Removing bar
47
48 ![example](example/gifs/remove.gif)
49
50 The source code: [example/remove/main.go](example/remove/main.go)
51
52 ### Sorting bars by progress
53
54 ![example](example/gifs/sort.gif)
55
56 The source code: [example/sort/main.go](example/sort/main.go)
57
58 ### Multiple io
59
60 ![example](example/gifs/io-multiple.gif)
61
62 The source code: [example/io/multiple/main.go](example/io/multiple/main.go)
63
64 ## Installation
65
66 ```sh
67 $ go get -u github.com/vbauerster/mpb
68 ```
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 package main
1
2 import (
3 "fmt"
4 "math/rand"
5 "time"
6
7 "github.com/vbauerster/mpb"
8 )
9
10 const (
11 totalItem = 100
12 maxBlockSize = 14
13 )
14
15 func main() {
16 decor := func(s *mpb.Statistics) string {
17 str := fmt.Sprintf("%d/%d", s.Current, s.Total)
18 return fmt.Sprintf("%-7s", str)
19 }
20
21 p := mpb.New()
22 bar := p.AddBar(totalItem).AppendETA().PrependFunc(decor)
23 p.Wg.Add(1)
24
25 blockSize := rand.Intn(maxBlockSize) + 1
26 for i := 0; bar.InProgress(); i++ {
27 time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
28 bar.Incr(blockSize)
29 if bar.Current() > 42 {
30 p.RemoveBar(bar)
31 }
32 blockSize = rand.Intn(maxBlockSize) + 1
33 }
34
35 p.WaitAndStop()
36 fmt.Println("stop")
37 }
+0
-60
example/prependPercent/main.go less more
0 package main
1
2 import (
3 "fmt"
4 "math/rand"
5 "time"
6
7 "github.com/vbauerster/mpb"
8 )
9
10 const (
11 maxBlockSize = 12
12 )
13
14 func main() {
15
16 p := mpb.New().SetWidth(64)
17 // p := mpb.New().RefreshRate(100 * time.Millisecond).SetWidth(64)
18
19 name1 := "Bar#1:"
20 bar1 := p.AddBar(50).AppendETA().PrependPercentage(3).PrependName(name1, len(name1))
21 p.Wg.Add(1)
22 go func() {
23 blockSize := rand.Intn(maxBlockSize) + 1
24 for i := 0; i < 50; i++ {
25 time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
26 bar1.Incr(1)
27 blockSize = rand.Intn(maxBlockSize) + 1
28 }
29 }()
30
31 bar2 := p.AddBar(100).AppendETA().PrependPercentage(3).PrependName("", 0-len(name1))
32 p.Wg.Add(1)
33 go func() {
34 blockSize := rand.Intn(maxBlockSize) + 1
35 for i := 0; i < 100; i++ {
36 time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
37 bar2.Incr(1)
38 blockSize = rand.Intn(maxBlockSize) + 1
39 }
40 }()
41
42 bar3 := p.AddBar(80).AppendETA().PrependPercentage(3).PrependName("Bar#3:", 0)
43 p.Wg.Add(1)
44 go func() {
45 blockSize := rand.Intn(maxBlockSize) + 1
46 for i := 0; i < 80; i++ {
47 time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
48 bar3.Incr(1)
49 blockSize = rand.Intn(maxBlockSize) + 1
50 }
51 }()
52
53 time.Sleep(3 * time.Second)
54 p.RemoveBar(bar2)
55
56 p.WaitAndStop()
57 fmt.Println("stop")
58 // p.AddBar(1) // panic: send on closed channnel
59 }
88 )
99
1010 const (
11 totalItem = 100
12 maxBlockSize = 14
11 maxBlockSize = 12
1312 )
1413
1514 func main() {
16 decor := func(s *mpb.Statistics) string {
17 str := fmt.Sprintf("%d/%d", s.Current, s.Total)
18 return fmt.Sprintf("%-7s", str)
19 }
2015
21 p := mpb.New()
22 bar := p.AddBar(totalItem).AppendETA().PrependFunc(decor)
16 p := mpb.New().SetWidth(64)
17 // p := mpb.New().RefreshRate(100 * time.Millisecond).SetWidth(64)
18
19 name1 := "Bar#1:"
20 bar1 := p.AddBar(50).AppendETA().PrependPercentage(3).PrependName(name1, len(name1))
2321 p.Wg.Add(1)
22 go func() {
23 blockSize := rand.Intn(maxBlockSize) + 1
24 for i := 0; i < 50; i++ {
25 time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
26 bar1.Incr(1)
27 blockSize = rand.Intn(maxBlockSize) + 1
28 }
29 }()
2430
25 blockSize := rand.Intn(maxBlockSize) + 1
26 for i := 0; bar.InProgress(); i++ {
27 time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
28 bar.Incr(blockSize)
29 if bar.Current() > 42 {
30 p.RemoveBar(bar)
31 bar2 := p.AddBar(100).AppendETA().PrependPercentage(3).PrependName("", 0-len(name1))
32 p.Wg.Add(1)
33 go func() {
34 blockSize := rand.Intn(maxBlockSize) + 1
35 for i := 0; i < 100; i++ {
36 time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
37 bar2.Incr(1)
38 blockSize = rand.Intn(maxBlockSize) + 1
3139 }
32 blockSize = rand.Intn(maxBlockSize) + 1
33 }
40 }()
41
42 bar3 := p.AddBar(80).AppendETA().PrependPercentage(3).PrependName("Bar#3:", 0)
43 p.Wg.Add(1)
44 go func() {
45 blockSize := rand.Intn(maxBlockSize) + 1
46 for i := 0; i < 80; i++ {
47 time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
48 bar3.Incr(1)
49 blockSize = rand.Intn(maxBlockSize) + 1
50 }
51 }()
52
53 time.Sleep(3 * time.Second)
54 p.RemoveBar(bar2)
3455
3556 p.WaitAndStop()
3657 fmt.Println("stop")
58 // p.AddBar(1) // panic: send on closed channnel
3759 }
0 package main
1
2 import (
3 "fmt"
4 "math/rand"
5 "time"
6
7 "github.com/vbauerster/mpb"
8 )
9
10 func main() {
11 // No need to initialize sync.WaitGroup, as it is initialized implicitly
12 p := mpb.New() // Star mpb container
13 for i := 0; i < 3; i++ {
14 p.Wg.Add(1) // add wg counter
15 name := fmt.Sprintf("Bar#%d:", i)
16 bar := p.AddBar(100).PrependName(name, len(name)).AppendPercentage()
17 go func() {
18 // you can p.AddBar() here, but ordering will be non deterministic
19 for i := 0; i < 100; i++ {
20 time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
21 bar.Incr(1)
22 }
23 }()
24 }
25 p.WaitAndStop() // Wait for goroutines to finish
26 // p.AddBar(1) // panic: you cannot reuse p, create new one!
27 fmt.Println("finish")
28 }
+0
-37
example/simple/simple.go less more
0 package main
1
2 import (
3 "fmt"
4 "math/rand"
5 "time"
6
7 "github.com/vbauerster/mpb"
8 )
9
10 const (
11 totalItem = 100
12 maxBlockSize = 10
13 )
14
15 func main() {
16 decor := func(s *mpb.Statistics) string {
17 str := fmt.Sprintf("%d/%d", s.Current, s.Total)
18 return fmt.Sprintf("%-7s", str)
19 }
20
21 p := mpb.New()
22 bar := p.AddBar(totalItem).AppendETA().PrependFunc(decor)
23 // if you omit the following line, bar rendering goroutine may not have a
24 // chance to coplete, thus better always use.
25 p.Wg.Add(1)
26
27 blockSize := rand.Intn(maxBlockSize) + 1
28 for i := 0; i < 100; i++ {
29 time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
30 bar.Incr(1)
31 blockSize = rand.Intn(maxBlockSize) + 1
32 }
33
34 p.WaitAndStop()
35 fmt.Println("stop")
36 }