uiprogress
A Go library to render progress bars in terminal applications. It provides a set of flexible features with a customizable API.
Progress bars improve readability for terminal applications with long outputs by providing a concise feedback loop.
Features
- Multiple Bars: uiprogress can render multiple progress bars that can be tracked concurrently
- Dynamic Addition: Add additional progress bars any time, even after the progress tracking has started
- Prepend and Append Functions: Append or prepend completion percent and time elapsed to the progress bars
- Custom Decorator Functions: Add custom functions around the bar along with helper functions
Usage
To start listening for progress bars, call uiprogress.Start()
and add a progress bar using uiprogress.AddBar(total int)
. Update the progress using bar.Incr()
or bar.Set(n int)
. Full source code for the below example is available at example/simple/simple.go
uiprogress.Start()
bar := uiprogress.AddBar(100)
bar.AppendCompleted()
bar.PrependElapsed()
for bar.Incr() {
time.Sleep(time.Millisecond * 20)
}
This will render the below in the terminal
Using Custom Decorators
You can also add a custom decorator function in addition to default bar.AppendCompleted()
and bar.PrependElapsed()
decorators. The below example tracks the current step for an application deploy progress. Source code for the below example is available at example/full/full.go
var steps = []string{"downloading source", "installing deps", "compiling", "packaging", "seeding database", "deploying", "staring servers"}
bar := uiprogress.AddBar(len(steps))
bar.PrependFunc(func(b *uiprogress.Bar) string {
return "app: " + steps[b.Current()-1]
})
for bar.Incr() {
time.Sleep(time.Millisecond * 10)
}
Rendering Multiple bars
You can add multiple bars using uiprogress.AddBar(n)
. The below example demonstrates updating multiple bars concurrently and adding a new bar later in the pipeline. Source for this example is available at example/multi/multi.go
waitTime := time.Millisecond * 100
uiprogress.Start()
var wg sync.WaitGroup
bar1 := uiprogress.AddBar(20).AppendCompleted().PrependElapsed()
wg.Add(1)
go func() {
defer wg.Done()
for bar1.Incr() {
time.Sleep(waitTime)
}
}()
bar2 := uiprogress.AddBar(40).AppendCompleted().PrependElapsed()
wg.Add(1)
go func() {
defer wg.Done()
for bar2.Incr() {
time.Sleep(waitTime)
}
}()
time.Sleep(time.Second)
bar3 := uiprogress.AddBar(20).PrependElapsed().AppendCompleted()
wg.Add(1)
go func() {
defer wg.Done()
for i := 1; i <= bar3.Total; i++ {
bar3.Set(i)
time.Sleep(waitTime)
}
}()
wg.Wait()
This will produce
Incr
counter
Bar.Incr() is an atomic counter and can be used as a general tracker, making it ideal for tracking progress of work fanned out to a lots of go routines. The source code for the below example is available at example/incr/incr.go
runtime.GOMAXPROCS(runtime.NumCPU())
count := 1000
bar := uiprogress.AddBar(count).AppendCompleted().PrependElapsed()
bar.PrependFunc(func(b *uiprogress.Bar) string {
return fmt.Sprintf("Task (%d/%d)", b.Current(), count)
})
uiprogress.Start()
var wg sync.WaitGroup
for i := 0; i < count; i++ {
wg.Add(1)
go func() {
defer wg.Done()
time.Sleep(time.Millisecond * time.Duration(rand.Intn(500)))
bar.Incr()
}()
}
time.Sleep(time.Second)
wg.Wait()
uiprogress.Stop()
Installation
$ go get -v github.com/davidsnyder/uiprogress
Todos
License
uiprogress is released under the MIT License. See LICENSE.