pb

package module
v2.0.7+incompatible Latest Latest
Warning

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

Go to latest
Published: Mar 1, 2019 License: BSD-3-Clause Imports: 15 Imported by: 0

README

Terminal progress bar for Go

Simple progress bar for console programs.

Please check the new version https://github.com/cheggaaa/pb/tree/v2 (currently, it's beta)

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  34 / 200 [=========>---------------------------------------------]  17.00% 00m08s
Second  42 / 200 [===========>------------------------------------------]  21.00% 00m06s
Third  36 / 200 [=========>---------------------------------------------]  18.00% 00m08s

Documentation

Overview

Simple console progress bars

Example
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!")
Output:

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]")
}
Output:

Example (Multiple)
// 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()
Output:

Index

Examples

Constants

View Source
const (
	KiB = 1024
	MiB = 1048576
	GiB = 1073741824
	TiB = 1099511627776

	KB = 1e3
	MB = 1e6
	GB = 1e9
	TB = 1e12
)
View Source
const (
	// Default refresh rate - 200ms
	DEFAULT_REFRESH_RATE = time.Millisecond * 200
	FORMAT               = "[=>-]"
)
View Source
const Version = "1.0.28"

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 {
	Output      io.Writer
	RefreshRate time.Duration
	// contains filtered or unexported fields
}

func NewPool added in v1.0.22

func NewPool(pbs ...*ProgressBar) (pool *Pool)

NewPool initialises a pool with progress bars, but doesn't start it. You need to call Start manually

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) Start added in v1.0.22

func (p *Pool) Start() (err error)

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, ShowElapsedTime   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) IsFinished added in v1.0.12

func (pb *ProgressBar) IsFinished() bool

IsFinished return boolean

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) Reset added in v1.0.24

func (pb *ProgressBar) Reset(total int) *ProgressBar

Reset bar and set new total count Does effect only on finished bar

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) SetTotal added in v1.0.24

func (pb *ProgressBar) SetTotal(total int) *ProgressBar

SetTotal atomically sets new total count

func (*ProgressBar) SetTotal64 added in v1.0.24

func (pb *ProgressBar) SetTotal64(total int64) *ProgressBar

SetTotal64 atomically sets new total count

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

String return the last bar print

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, KiB, MiB, ...)
	U_BYTES
	// U_BYTES_DEC units are like U_BYTES, but base 10 (B, KB, MB, ...)
	U_BYTES_DEC
	// 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