pb

package module
v0.0.0-...-f57b110 Latest Latest
Warning

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

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

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)
	}

	// finish bar
	bar.Finish()
}

Result will be like this:

> go run test.go
37158 / 100000 [---------------->_______________________________] 37.16% 916 p/s

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.Bytes, 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 500 MiB 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 the 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/Bionic2113/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/Bionic2113/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/Bionic2113/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

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

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

Add progress bars.

func (*Pool) Start

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

func (*Pool) Stop

func (p *Pool) Stop() error

Stop 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
	HideCountersTotal                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

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

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

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

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

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

SetTotal atomically sets new total count

func (*ProgressBar) SetTotal64

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

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

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

It's proxy Writer, implement io.Writer

func (*Writer) Close

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

Close the reader when it implements io.Closer

func (*Writer) Write

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