pb

package module
v2.0.7 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2019 License: BSD-3-Clause Imports: 19 Imported by: 55

README

Warning

Please use v3 version go get github.com/cheggaaa/v3 - it's a continuation of the v2, but in the master branch and with the support of go modules

Terminal progress bar for Go

Coverage Status

It's beta, some features may be changed

This is proposal for the second version of progress bar

  • based on text/template
  • can take custom elements
  • using colors is easy

Installation

go get gopkg.in/cheggaaa/pb.v2

Usage

package main

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

func main() {
	simple()
	fromPreset()
	customTemplate(`Custom template: {{counters . }}`)
	customTemplate(`{{ red "With colors:" }} {{bar . | green}} {{speed . | blue }}`)
	customTemplate(`{{ red "With funcs:" }} {{ bar . "<" "-" (cycle . "↖" "↗" "↘" "↙" ) "." ">"}} {{speed . | rndcolor }}`)
	customTemplate(`{{ bar . "[<" "·····•·····" (rnd "ᗧ" "◔" "◕" "◷" ) "•" ">]"}}`)
}

func simple() {
	count := 1000
	bar := pb.StartNew(count)
	for i := 0; i < count; i++ {
		bar.Increment()
		time.Sleep(time.Millisecond * 2)
	}
	bar.Finish()
}

func fromPreset() {
	count := 1000
	//bar := pb.Default.Start(total)
	//bar := pb.Simple.Start(total)
	bar := pb.Full.Start(count)
	defer bar.Finish()
	bar.Set("prefix", "fromPreset(): ")
	for i := 0; i < count/2; i++ {
		bar.Add(2)
		time.Sleep(time.Millisecond * 4)
	}
}

func customTemplate(tmpl string) {
	count := 1000
	bar := pb.ProgressBarTemplate(tmpl).Start(count)
	defer bar.Finish()
	for i := 0; i < count/2; i++ {
		bar.Add(2)
		time.Sleep(time.Millisecond * 4)
	}
}

Documentation

Index

Constants

View Source
const (
	// Bytes means we're working with byte sizes. Numbers will print as Kb, Mb, etc
	// bar.Set(pb.Bytes, true)
	Bytes key = 1 << iota

	// Terminal means we're will print to terminal and can use ascii sequences
	// Also we're will try to use terminal width
	Terminal

	// Static means progress bar will not update automaticly
	Static

	// ReturnSymbol - by default in terminal mode it's '\r'
	ReturnSymbol

	// Color by default is true when output is tty, but you can set to false for disabling colors
	Color
)
View Source
const Version = "2.0.6"

Version of ProgressBar library

Variables

This section is empty.

Functions

func CellCount added in v2.0.2

func CellCount(s string) int

func RegisterElement

func RegisterElement(name string, el Element, adaptive bool)

RegisterElement give you a chance to use custom elements

func StripString added in v2.0.2

func StripString(s string, w int) string

func StripStringToBuffer added in v2.0.2

func StripStringToBuffer(s string, w int, buf *bytes.Buffer)

Types

type Element

type Element interface {
	ProgressElement(state *State, args ...string) string
}

Element is an interface for bar elements

type ElementFunc

type ElementFunc func(state *State, args ...string) string

ElementFunc type implements Element interface and created for simplify elements

var ElementBar ElementFunc = func(state *State, args ...string) string {
	// init
	var p = getProgressObj(state, args...)

	total, value := state.Total(), state.Value()
	if total < 0 {
		total = -total
	}
	if value < 0 {
		value = -value
	}

	if total != 0 && value > total {
		total = value
	}

	p.buf.Reset()

	var widthLeft = state.AdaptiveElWidth()
	if widthLeft <= 0 || !state.IsAdaptiveWidth() {
		widthLeft = 30
	}

	if p.cc[0] < widthLeft {
		widthLeft -= p.write(state, 0, p.cc[0])
	} else {
		p.write(state, 0, widthLeft)
		return p.buf.String()
	}

	if p.cc[4] < widthLeft {

		widthLeft -= p.cc[4]
	} else {
		p.write(state, 4, widthLeft)
		return p.buf.String()
	}

	var curCount int

	if total > 0 {

		curCount = int(math.Ceil((float64(value) / float64(total)) * float64(widthLeft)))
	}

	if total == value && state.IsFinished() {
		widthLeft -= p.write(state, 1, curCount)
	} else if toWrite := curCount - p.cc[2]; toWrite > 0 {
		widthLeft -= p.write(state, 1, toWrite)
		widthLeft -= p.write(state, 2, p.cc[2])
	} else if curCount > 0 {
		widthLeft -= p.write(state, 2, curCount)
	}
	if widthLeft > 0 {
		widthLeft -= p.write(state, 3, widthLeft)
	}

	p.write(state, 4, p.cc[4])

	return p.buf.String()
}

ElementBar make progress bar view [-->__] Optionally can take up to 5 string arguments. Defaults is "[", "-", ">", "_", "]" In template use as follows: {{bar . }} or {{bar . "<" "oOo" "|" "~" ">"}} Color args: {{bar . (red "[") (green "-") ...

var ElementCounters ElementFunc = func(state *State, args ...string) string {
	var f string
	if state.Total() > 0 {
		f = argsHelper(args).getNotEmptyOr(0, "%s / %s")
	} else {
		f = argsHelper(args).getNotEmptyOr(1, "%[1]s")
	}
	return fmt.Sprintf(f, state.Format(state.Value()), state.Format(state.Total()))
}

ElementCounters shows current and total values. Optionally can take one or two string arguments. First string will be used as format value when Total is present (>0). Default is "%s / %s" Second string will be used when total <= 0. Default is "%[1]s" In template use as follows: {{counters .}} or {{counters . "%s/%s"}} or {{counters . "%s/%s" "%s/?"}}

var ElementCycle ElementFunc = func(state *State, args ...string) string {
	if len(args) == 0 {
		return ""
	}
	n, _ := state.Get(cycleObj).(int)
	if n >= len(args) {
		n = 0
	}
	state.Set(cycleObj, n+1)
	return args[n]
}

ElementCycle return next argument for every call In template use as follows: {{cycle . "1" "2" "3"}} Or mix width other elements: {{ bar . "" "" (cycle . "↖" "↗" "↘" "↙" )}}

var ElementElapsedTime ElementFunc = func(state *State, args ...string) string {
	etm := state.Time().Truncate(time.Second).Sub(state.StartTime().Truncate(time.Second))
	return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), etm.String())
}

ElementElapsedTime shows elapsed time Optionally cat take one argument - it's format for time string. In template use as follows: {{etime .}} or {{etime . "%s elapsed"}}

var ElementPercent ElementFunc = func(state *State, args ...string) string {
	argsh := argsHelper(args)
	if state.Total() > 0 {
		return fmt.Sprintf(
			argsh.getNotEmptyOr(0, "%.02f%%"),
			float64(state.Value())/(float64(state.Total())/float64(100)),
		)
	}
	return argsh.getOr(1, "?%")
}

ElementPercent shows current percent of progress. Optionally can take one or two string arguments. First string will be used as value for format float64, default is "%.02f%%". Second string will be used when percent can't be calculated, default is "?%" In template use as follows: {{percent .}} or {{percent . "%.03f%%"}} or {{percent . "%.03f%%" "?"}}

var ElementRemainingTime ElementFunc = func(state *State, args ...string) string {
	var rts string
	sp := getSpeedObj(state).value(state)
	if !state.IsFinished() {
		if sp > 0 {
			remain := float64(state.Total() - state.Value())
			remainDur := time.Duration(remain/sp) * time.Second
			rts = remainDur.String()
		} else {
			return argsHelper(args).getOr(2, "?")
		}
	} else {
		rts = state.Time().Truncate(time.Second).Sub(state.StartTime().Truncate(time.Second)).String()
		return fmt.Sprintf(argsHelper(args).getOr(1, "%s"), rts)
	}
	return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), rts)
}

ElementRemainingTime calculates remaining time based on speed (EWMA) Optionally can take one or two string arguments. First string will be used as value for format time duration string, default is "%s". Second string will be used when bar finished and value indicates elapsed time, default is "%s" Third string will be used when value not available, default is "?" In template use as follows: {{rtime .}} or {{rtime . "%s remain"}} or {{rtime . "%s remain" "%s total" "???"}}

var ElementSpeed ElementFunc = func(state *State, args ...string) string {
	sp := getSpeedObj(state).value(state)
	if sp == 0 {
		return argsHelper(args).getNotEmptyOr(1, "? p/s")
	}
	return fmt.Sprintf(argsHelper(args).getNotEmptyOr(0, "%s p/s"), state.Format(int64(round(sp))))
}

ElementSpeed calculates current speed by EWMA Optionally can take one or two string arguments. First string will be used as value for format speed, default is "%s p/s". Second string will be used when speed not available, default is "? p/s" In template use as follows: {{speed .}} or {{speed . "%s per second"}} or {{speed . "%s ps" "..."}

var ElementString ElementFunc = func(state *State, args ...string) string {
	if len(args) == 0 {
		return ""
	}
	v := state.Get(args[0])
	if v == nil {
		return ""
	}
	return fmt.Sprint(v)
}

ElementString get value from bar by given key and print them bar.Set("myKey", "string to print") In template use as follows: {{string . "myKey"}}

func (ElementFunc) ProgressElement

func (e ElementFunc) ProgressElement(state *State, args ...string) string

ProgressElement just call self func

type ProgressBar

type ProgressBar struct {
	// contains filtered or unexported fields
}

ProgressBar is the main object of bar

func New added in v2.0.3

func New(total int) *ProgressBar

New creates new ProgressBar object

func New64 added in v2.0.3

func New64(total int64) *ProgressBar

New64 creates new ProgressBar object using int64 as total

func Start64 added in v2.0.3

func Start64(total int64) *ProgressBar

Start64 starts new ProgressBar with Default template. Using int64 as total.

func StartNew added in v2.0.4

func StartNew(total int) *ProgressBar

StartNew starts new ProgressBar with Default template

func (*ProgressBar) Add

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

Add adding given int value to bar value

func (*ProgressBar) Add64

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

Add adding given int64 value to bar value

func (*ProgressBar) Current added in v2.0.2

func (pb *ProgressBar) Current() int64

Current return current bar value

func (*ProgressBar) Err

func (pb *ProgressBar) Err() error

Err return possible error When all ok - will be nil May contain template.Execute errors

func (*ProgressBar) Finish

func (pb *ProgressBar) Finish() *ProgressBar

Finish stops the bar

func (*ProgressBar) Format

func (pb *ProgressBar) Format(v int64) string

Format convert int64 to string according to the current settings

func (*ProgressBar) Get

func (pb *ProgressBar) Get(key interface{}) interface{}

Get return value by key

func (*ProgressBar) GetBool

func (pb *ProgressBar) GetBool(key interface{}) bool

GetBool return value by key and try to convert there to boolean If value doesn't set or not boolean - return false

func (*ProgressBar) Increment

func (pb *ProgressBar) Increment() *ProgressBar

Increment atomically increments the progress

func (*ProgressBar) IsStarted added in v2.0.2

func (pb *ProgressBar) IsStarted() bool

IsStarted indicates progress bar state

func (*ProgressBar) NewProxyReader added in v2.0.5

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

NewProxyReader creates a wrapper for given reader, but with progress handle Takes io.Reader or io.ReadCloser Also, it automatically switches progress bar to handle units as bytes

func (*ProgressBar) ProgressElement

func (pb *ProgressBar) ProgressElement(s *State, args ...string) string

ProgressElement implements Element interface

func (*ProgressBar) Set

func (pb *ProgressBar) Set(key, value interface{}) *ProgressBar

Set sets any value by any key

func (*ProgressBar) SetCurrent

func (pb *ProgressBar) SetCurrent(value int64) *ProgressBar

SetCurrent sets the current bar value

func (*ProgressBar) SetErr

func (pb *ProgressBar) SetErr(err error) *ProgressBar

SetErr sets error to the ProgressBar Error will be available over Err()

func (*ProgressBar) SetRefreshRate added in v2.0.2

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

func (*ProgressBar) SetTemplate

func (pb *ProgressBar) SetTemplate(tmpl ProgressBarTemplate) *ProgressBar

SetTemplateString sets ProgressBarTempate and parse it

func (*ProgressBar) SetTemplateString added in v2.0.2

func (pb *ProgressBar) SetTemplateString(tmpl string) *ProgressBar

SetTemplateString sets ProgressBar tempate string and parse it

func (*ProgressBar) SetTotal

func (pb *ProgressBar) SetTotal(value int64) *ProgressBar

SetTotal sets the total bar value

func (*ProgressBar) SetWidth

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

SetWidth sets the bar width When given value <= 0 would be using the terminal width (if possible) or default value.

func (*ProgressBar) SetWriter

func (pb *ProgressBar) SetWriter(w io.Writer) *ProgressBar

SetWriter sets the io.Writer. Bar will write in this writer By default this is os.Stderr

func (*ProgressBar) Start

func (pb *ProgressBar) Start() *ProgressBar

Start starts the bar

func (*ProgressBar) StartTime

func (pb *ProgressBar) StartTime() time.Time

StartTime return the time when bar started

func (*ProgressBar) String

func (pb *ProgressBar) String() string

String return currrent string representation of ProgressBar

func (*ProgressBar) Total

func (pb *ProgressBar) Total() int64

Total return current total bar value

func (*ProgressBar) Width

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

Width return the bar width It's current terminal width or settled over 'SetWidth' value.

func (*ProgressBar) Write added in v2.0.3

func (pb *ProgressBar) Write() *ProgressBar

Write performs write to the output

type ProgressBarTemplate added in v2.0.2

type ProgressBarTemplate string

ProgressBarTemplate that template string

var (
	// Full - preset with all default available elements
	// Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix'
	Full ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }} {{rtime . "ETA %s"}}{{string . "suffix"}}`

	// Default - preset like Full but without elapsed time
	// Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix'
	Default ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }}{{string . "suffix"}}`

	// Simple - preset without speed and any timers. Only counters, bar and percents
	// Example: 'Prefix 20/100 [-->______] 20% Suffix'
	Simple ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }}{{string . "suffix"}}`
)

func (ProgressBarTemplate) New added in v2.0.2

func (pbt ProgressBarTemplate) New(total int) *ProgressBar

New creates new bar from template

func (ProgressBarTemplate) Start added in v2.0.2

func (pbt ProgressBarTemplate) Start(total int) *ProgressBar

Start create and start new bar with given int total value

func (ProgressBarTemplate) Start64 added in v2.0.2

func (pbt ProgressBarTemplate) Start64(total int64) *ProgressBar

Start64 create and start new bar with given int64 total value

type Reader added in v2.0.5

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

Reader it's a wrapper for given reader, but with progress handle

func (*Reader) Close added in v2.0.5

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

Close the wrapped reader when it implements io.Closer

func (*Reader) Read added in v2.0.5

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

Read reads bytes from wrapped reader and add amount of bytes to progress bar

type State

type State struct {
	*ProgressBar
	// contains filtered or unexported fields
}

State represents the current state of bar Need for bar elements

func (*State) AdaptiveElWidth

func (s *State) AdaptiveElWidth() int

AdaptiveElWidth - adaptive elements must return string with given cell count (when AdaptiveElWidth > 0)

func (*State) Id added in v2.0.4

func (s *State) Id() uint64

Id it's the current state identifier - incremental - starts with 1 - resets after finish/start

func (*State) IsAdaptiveWidth

func (s *State) IsAdaptiveWidth() bool

IsAdaptiveWidth returns true when element must be shown as adaptive

func (*State) IsFinished

func (s *State) IsFinished() bool

IsFinished return true when bar is finished

func (*State) IsFirst

func (s *State) IsFirst() bool

IsFirst return true only in first render

func (*State) Time added in v2.0.4

func (s *State) Time() time.Time

Time when state was created

func (*State) Total

func (s *State) Total() int64

Total it's bar int64 total

func (*State) Value

func (s *State) Value() int64

Value it's current value

func (*State) Width

func (s *State) Width() int

Width of bar

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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