pb

package module
v1.0.29 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2020 License: BSD-3-Clause Imports: 15 Imported by: 1,161

README

Terminal progress bar for Go

Coverage Status

Installation

go get github.com/cheggaaa/pb/v3

Documentation for v1 bar available here

Quick start

package main

import (
	"time"
	
	"github.com/cheggaaa/pb/v3"
)

func main() {
	count := 100000
	// create and start new bar
	bar := pb.StartNew(count)
	
	// start bar from 'default' template
	// bar := pb.Default.Start(count)
	
	// start bar from 'simple' template
	// bar := pb.Simple.Start(count)
	
	// start bar from 'full' template
	// bar := pb.Full.Start(count)
	
	for i := 0; i < count; i++ {
		bar.Increment()
		time.Sleep(time.Millisecond)
	}
	bar.Finish()
}

Result will be like this:

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

Settings

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

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

// force set io.Writer, by default it's os.Stderr
bar.SetWriter(os.Stdout)

// bar will format numbers as bytes (B, KiB, MiB, etc)
bar.Set(pb.Byte, true)

// bar use SI bytes prefix names (B, kB) instead of IEC (B, KiB)
bar.Set(pb.SIBytesPrefix, true)

// set custom bar template
bar.SetTemplateString(myTemplate)

// check for error after template set
if err = bar.Err(); err != nil {
    return
}

// start bar
bar.Start()

Progress bar for IO Operations

package main

import (
	"crypto/rand"
	"io"
	"io/ioutil"

	"github.com/cheggaaa/pb/v3"
)

func main() {

	var limit int64 = 1024 * 1024 * 500
	// we will copy 200 Mb from /dev/rand to /dev/null
	reader := io.LimitReader(rand.Reader, limit)
	writer := ioutil.Discard

	// start new bar
	bar := pb.Full.Start64(limit)
	// create proxy reader
	barReader := bar.NewProxyReader(reader)
	// copy from proxy reader
	io.Copy(writer, barReader)
	// finish bar
	bar.Finish()
}

Custom Progress Bar templates

Rendering based on builtin text/template package. You can use existing pb's elements or create you own.

All available elements are described in element.go file.

All in one example:
tmpl := `{{ red "With funcs:" }} {{ bar . "<" "-" (cycle . "↖" "↗" "↘" "↙" ) "." ">"}} {{speed . | rndcolor }} {{percent .}} {{string . "my_green_string" | green}} {{string . "my_blue_string" | blue}}`
// start bar based on our template
bar := pb.ProgressBarTemplate(tmpl).Start64(limit)
// set values for string elements
bar.Set("my_green_string", "green").
	Set("my_blue_string", "blue")

Documentation

Overview

Simple console progress bars

Example
package main

import (
	"time"

	"github.com/cheggaaa/pb"
)

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

Example (Copy)
package main

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

	"github.com/cheggaaa/pb"
)

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)
package main

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

	"github.com/cheggaaa/pb"
)

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()
}
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.29"

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) NewProxyWriter added in v1.0.29

func (pb *ProgressBar) NewProxyWriter(r io.Writer) *Writer

Create new proxy writer over bar Takes io.Writer or io.WriteCloser

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
)

type Writer added in v1.0.29

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

It's proxy Writer, implement io.Writer

func (*Writer) Close added in v1.0.29

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

Close the reader when it implements io.Closer

func (*Writer) Write added in v1.0.29

func (r *Writer) Write(p []byte) (n int, err error)

Jump to

Keyboard shortcuts

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