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: Jul 2, 2019 License: BSD-3-Clause Imports: 19 Imported by: 0

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

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

func StripString(s string, w int) string

func StripStringToBuffer

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

func New(total int) *ProgressBar

New creates new ProgressBar object

func New64

func New64(total int64) *ProgressBar

New64 creates new ProgressBar object using int64 as total

func Start64

func Start64(total int64) *ProgressBar

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

func StartNew

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

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 added in v1.0.5

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

func (pb *ProgressBar) IsStarted() bool

IsStarted indicates progress bar state

func (*ProgressBar) NewProxyReader

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

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

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

SetTemplateString sets ProgressBar tempate string and parse it

func (*ProgressBar) SetTotal added in v1.0.24

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

func (pb *ProgressBar) Write() *ProgressBar

Write performs write to the output

type ProgressBarTemplate

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

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

New creates new bar from template

func (ProgressBarTemplate) Start

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

Start create and start new bar with given int total value

func (ProgressBarTemplate) Start64

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

Start64 create and start new bar with given int64 total value

type Reader

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 v1.0.4

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

Close the wrapped reader when it implements io.Closer

func (*Reader) Read

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

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

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