Help us shape the future of Go! Take the 2026 Go Developer Survey

pb

package module
v1.0.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2016 License: BSD-3-Clause Imports: 15 Imported by: 0

README

Terminal progress bar for Go

Simple progress bar for console programs.

Installation

go get gopkg.in/cheggaaa/pb.v1

Usage

package main

import (
	"gopkg.in/cheggaaa/pb.v1"
	"time"
)

func main() {
	count := 100000
	bar := pb.StartNew(count)
	for i := 0; i < count; i++ {
		bar.Increment()
		time.Sleep(time.Millisecond)
	}
	bar.FinishPrint("The End!")
}

Result will be like this:

> go run test.go
37158 / 100000 [================>_______________________________] 37.16% 1m11s

Customization

// create bar
bar := pb.New(count)

// refresh info every second (default 200ms)
bar.SetRefreshRate(time.Second)

// show percents (by default already true)
bar.ShowPercent = true

// show bar (by default already true)
bar.ShowBar = true

// no counters
bar.ShowCounters = false

// show "time left"
bar.ShowTimeLeft = true

// show average speed
bar.ShowSpeed = true

// sets the width of the progress bar
bar.SetWidth(80)

// sets the width of the progress bar, but if terminal size smaller will be ignored
bar.SetMaxWidth(80)

// convert output to readable format (like KB, MB)
bar.SetUnits(pb.U_BYTES)

// and start
bar.Start()

Progress bar for IO Operations

// create and start bar
bar := pb.New(myDataLen).SetUnits(pb.U_BYTES)
bar.Start()

// my io.Reader
r := myReader

// my io.Writer
w := myWriter

// create proxy reader
reader := bar.NewProxyReader(r)

// and copy from pb reader
io.Copy(w, reader)

// create and start bar
bar := pb.New(myDataLen).SetUnits(pb.U_BYTES)
bar.Start()

// my io.Reader
r := myReader

// my io.Writer
w := myWriter

// create multi writer
writer := io.MultiWriter(w, bar)

// and copy
io.Copy(writer, r)

bar.Finish()

Custom Progress Bar Look-and-feel

bar.Format("<.- >")

Multiple Progress Bars (experimental and unstable)

Do not print to terminal while pool is active.

package main

import (
    "math/rand"
    "sync"
    "time"

    "gopkg.in/cheggaaa/pb.v1"
)

func main() {
    // create bars
    first := pb.New(200).Prefix("First ")
    second := pb.New(200).Prefix("Second ")
    third := pb.New(200).Prefix("Third ")
    // start pool
    pool, err := pb.StartPool(first, second, third)
    if err != nil {
        panic(err)
    }
    // update bars
    wg := new(sync.WaitGroup)
    for _, bar := range []*pb.ProgressBar{first, second, third} {
        wg.Add(1)
        go func(cb *pb.ProgressBar) {
            for n := 0; n < 200; n++ {
                cb.Increment()
                time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
            }
            cb.Finish()
            wg.Done()
        }(bar)
    }
    wg.Wait()
    // close pool
    pool.Stop()
}

The result will be as follows:

$ go run example/multiple.go 
First 141 / 1000 [===============>---------------------------------------] 14.10 % 44s
Second 139 / 1000 [==============>---------------------------------------] 13.90 % 44s
Third 152 / 1000 [================>--------------------------------------] 15.20 % 40s

Documentation

Overview

Simple console progress bars

Example
package main

import (
	"time"

	"gopkg.in/cheggaaa/pb.v1"
)

func main() {
	count := 5000
	bar := pb.New(count)

	// show percents (by default already true)
	bar.ShowPercent = true

	// show bar (by default already true)
	bar.ShowBar = true

	bar.ShowCounters = true

	bar.ShowTimeLeft = true

	// and start
	bar.Start()
	for i := 0; i < count; i++ {
		bar.Increment()
		time.Sleep(time.Millisecond)
	}
	bar.FinishPrint("The End!")
}
Example (Copy)
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"

	"gopkg.in/cheggaaa/pb.v1"
)

func main() {
	// check args
	if len(os.Args) < 3 {
		printUsage()
		return
	}
	sourceName, destName := os.Args[1], os.Args[2]

	// check source
	var source io.Reader
	var sourceSize int64
	if strings.HasPrefix(sourceName, "http://") {
		// open as url
		resp, err := http.Get(sourceName)
		if err != nil {
			fmt.Printf("Can't get %s: %v\n", sourceName, err)
			return
		}
		defer resp.Body.Close()
		if resp.StatusCode != http.StatusOK {
			fmt.Printf("Server return non-200 status: %v\n", resp.Status)
			return
		}
		i, _ := strconv.Atoi(resp.Header.Get("Content-Length"))
		sourceSize = int64(i)
		source = resp.Body
	} else {
		// open as file
		s, err := os.Open(sourceName)
		if err != nil {
			fmt.Printf("Can't open %s: %v\n", sourceName, err)
			return
		}
		defer s.Close()
		// get source size
		sourceStat, err := s.Stat()
		if err != nil {
			fmt.Printf("Can't stat %s: %v\n", sourceName, err)
			return
		}
		sourceSize = sourceStat.Size()
		source = s
	}

	// create dest
	dest, err := os.Create(destName)
	if err != nil {
		fmt.Printf("Can't create %s: %v\n", destName, err)
		return
	}
	defer dest.Close()

	// create bar
	bar := pb.New(int(sourceSize)).SetUnits(pb.U_BYTES).SetRefreshRate(time.Millisecond * 10)
	bar.ShowSpeed = true
	bar.Start()

	// create proxy reader
	reader := bar.NewProxyReader(source)

	// and copy from reader
	io.Copy(dest, reader)
	bar.Finish()
}

func printUsage() {
	fmt.Println("copy [source file or url] [dest file]")
}
Example (Multiple)
package main

import (
	"math/rand"
	"sync"
	"time"

	"gopkg.in/cheggaaa/pb.v1"
)

func main() {
	// create bars
	first := pb.New(200).Prefix("First ")
	second := pb.New(200).Prefix("Second ")
	third := pb.New(200).Prefix("Third ")
	// start pool
	pool, err := pb.StartPool(first, second, third)
	if err != nil {
		panic(err)
	}
	// update bars
	wg := new(sync.WaitGroup)
	for _, bar := range []*pb.ProgressBar{first, second, third} {
		wg.Add(1)
		go func(cb *pb.ProgressBar) {
			for n := 0; n < 200; n++ {
				cb.Increment()
				time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
			}
			cb.Finish()
			wg.Done()
		}(bar)
	}
	wg.Wait()
	// close pool
	pool.Stop()
}

Index

Examples

Constants

View Source
const (
	// Default refresh rate - 200ms
	DEFAULT_REFRESH_RATE = time.Millisecond * 200
	FORMAT               = "[=>-]"
)
View Source
const (
	TIOCGWINSZ     = 0x5413
	TIOCGWINSZ_OSX = 1074295912
)
View Source
const Version = "1.0.6"

Current version

Variables

View Source
var (
	DefaultRefreshRate                         = DEFAULT_REFRESH_RATE
	BarStart, BarEnd, Empty, Current, CurrentN string
)

DEPRECATED variables for backward compatibility, from now do not work use pb.Format and pb.SetRefreshRate

View Source
var ErrPoolWasStarted = errors.New("Bar pool was started")

Functions

func Format

func Format(i int64) *formatter

func GetTerminalWidth

func GetTerminalWidth() (int, error)

GetTerminalWidth - returns terminal width for all platforms.

Types

type Callback

type Callback func(out string)

Callback for custom output For example:

bar.Callback = func(s string) {
    mySuperPrint(s)
}

type Pool

type Pool struct {
	RefreshRate time.Duration
	// contains filtered or unexported fields
}

func StartPool

func StartPool(pbs ...*ProgressBar) (pool *Pool, err error)

Create and start new pool with given bars You need call pool.Stop() after work

func (*Pool) Add added in v1.0.6

func (p *Pool) Add(pbs ...*ProgressBar)

Add progress bars.

func (*Pool) Stop

func (p *Pool) Stop() error

Restore terminal state and close pool

type ProgressBar

type ProgressBar struct {
	Total                            int64
	RefreshRate                      time.Duration
	ShowPercent, ShowCounters        bool
	ShowSpeed, ShowTimeLeft, ShowBar bool
	ShowFinalTime                    bool
	Output                           io.Writer
	Callback                         Callback
	NotPrint                         bool
	Units                            Units
	Width                            int
	ForceWidth                       bool
	ManualUpdate                     bool
	AutoStat                         bool

	// Default width for the time box.
	UnitsWidth   int
	TimeBoxWidth int

	BarStart string
	BarEnd   string
	Empty    string
	Current  string
	CurrentN string

	AlwaysUpdate bool
	// contains filtered or unexported fields
}

func New

func New(total int) *ProgressBar

Create new progress bar object

func New64

func New64(total int64) *ProgressBar

Create new progress bar object using int64 as total

func StartNew

func StartNew(total int) *ProgressBar

Create new object and start

func (*ProgressBar) Add

func (pb *ProgressBar) Add(add int) int

Add to current value

func (*ProgressBar) Add64

func (pb *ProgressBar) Add64(add int64) int64

func (*ProgressBar) Finish

func (pb *ProgressBar) Finish()

End print

func (*ProgressBar) FinishPrint

func (pb *ProgressBar) FinishPrint(str string)

End print and write string 'str'

func (*ProgressBar) Format

func (pb *ProgressBar) Format(format string) *ProgressBar

Set custom format for bar Example: bar.Format("[=>_]") Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter

func (*ProgressBar) Get added in v1.0.5

func (pb *ProgressBar) Get() int64

Get current value

func (*ProgressBar) GetWidth

func (pb *ProgressBar) GetWidth() int

func (*ProgressBar) Increment

func (pb *ProgressBar) Increment() int

Increment current value

func (*ProgressBar) NewProxyReader

func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader

Create new proxy reader over bar Takes io.Reader or io.ReadCloser

func (*ProgressBar) Postfix

func (pb *ProgressBar) Postfix(postfix string) *ProgressBar

Set postfix string

func (*ProgressBar) Prefix

func (pb *ProgressBar) Prefix(prefix string) *ProgressBar

Set prefix string

func (*ProgressBar) Read

func (pb *ProgressBar) Read(p []byte) (n int, err error)

implement io.Reader

func (*ProgressBar) Set

func (pb *ProgressBar) Set(current int) *ProgressBar

Set current value

func (*ProgressBar) Set64

func (pb *ProgressBar) Set64(current int64) *ProgressBar

Set64 sets the current value as int64

func (*ProgressBar) SetMaxWidth

func (pb *ProgressBar) SetMaxWidth(width int) *ProgressBar

Set max width, if width is bigger than terminal width, will be ignored

func (*ProgressBar) SetRefreshRate

func (pb *ProgressBar) SetRefreshRate(rate time.Duration) *ProgressBar

Set bar refresh rate

func (*ProgressBar) SetUnits

func (pb *ProgressBar) SetUnits(units Units) *ProgressBar

Set units bar.SetUnits(U_NO) - by default bar.SetUnits(U_BYTES) - for Mb, Kb, etc

func (*ProgressBar) SetWidth

func (pb *ProgressBar) SetWidth(width int) *ProgressBar

Set bar width

func (*ProgressBar) Start

func (pb *ProgressBar) Start() *ProgressBar

Start print

func (*ProgressBar) String

func (pb *ProgressBar) String() string

func (*ProgressBar) Update

func (pb *ProgressBar) Update()

Write the current state of the progressbar

func (*ProgressBar) Write

func (pb *ProgressBar) Write(p []byte) (n int, err error)

implement io.Writer

type Reader

type Reader struct {
	io.Reader
	// contains filtered or unexported fields
}

It's proxy reader, implement io.Reader

func (*Reader) Close added in v1.0.4

func (r *Reader) Close() (err error)

Close the reader when it implements io.Closer

func (*Reader) Read

func (r *Reader) Read(p []byte) (n int, err error)

type Units

type Units int
const (
	// U_NO are default units, they represent a simple value and are not formatted at all.
	U_NO Units = iota
	// U_BYTES units are formatted in a human readable way (b, Bb, Mb, ...)
	U_BYTES
	// U_DURATION units are formatted in a human readable way (3h14m15s)
	U_DURATION
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL