Update vendor of boltdb and containers/image

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2020-03-29 06:16:27 -04:00
parent 684b4bd2f1
commit 366001fb5f
130 changed files with 1634 additions and 760 deletions

View File

@ -29,11 +29,11 @@ func (f FillerFunc) Fill(w io.Writer, width int, stat *decor.Statistics) {
f(w, width, stat)
}
// Wrapper interface.
// WrapFiller interface.
// If you're implementing custom Filler by wrapping a built-in one,
// it is necessary to implement this interface to retain functionality
// of built-in Filler.
type Wrapper interface {
type WrapFiller interface {
Base() Filler
}

View File

@ -18,13 +18,14 @@ const (
rRefill
)
// DefaultBarStyle is applied when bar constructed with *Progress.AddBar method.
// DefaultBarStyle is a string containing 7 runes.
// Each rune is a building block of a progress bar.
//
// '1th rune' stands for left boundary rune
// '1st rune' stands for left boundary rune
//
// '2th rune' stands for fill rune
// '2nd rune' stands for fill rune
//
// '3th rune' stands for tip rune
// '3rd rune' stands for tip rune
//
// '4th rune' stands for empty rune
//
@ -44,16 +45,16 @@ type barFiller struct {
flush func(w io.Writer, bb [][]byte)
}
// NewBarFiller constucts mpb.Filler, to be used with *Progress.Add method.
// NewBarFiller constucts mpb.Filler, to be used with *Progress.Add(...) *Bar method.
func NewBarFiller(style string, reverse bool) Filler {
if style == "" {
style = DefaultBarStyle
}
bf := &barFiller{
format: make([][]byte, utf8.RuneCountInString(style)),
format: make([][]byte, utf8.RuneCountInString(style)),
reverse: reverse,
}
bf.SetStyle(style)
bf.SetReverse(reverse)
return bf
}
@ -66,28 +67,16 @@ func (s *barFiller) SetStyle(style string) {
src = append(src, []byte(string(r)))
}
copy(s.format, src)
if s.reverse {
s.tip = s.format[rRevTip]
} else {
s.tip = s.format[rTip]
}
s.SetReverse(s.reverse)
}
func (s *barFiller) SetReverse(reverse bool) {
if reverse {
s.tip = s.format[rRevTip]
s.flush = func(w io.Writer, bb [][]byte) {
for i := len(bb) - 1; i >= 0; i-- {
w.Write(bb[i])
}
}
s.flush = reverseFlush
} else {
s.tip = s.format[rTip]
s.flush = func(w io.Writer, bb [][]byte) {
for i := 0; i < len(bb); i++ {
w.Write(bb[i])
}
}
s.flush = normalFlush
}
s.reverse = reverse
}
@ -135,3 +124,15 @@ func (s *barFiller) Fill(w io.Writer, width int, stat *decor.Statistics) {
s.flush(w, bb)
}
func normalFlush(w io.Writer, bb [][]byte) {
for i := 0; i < len(bb); i++ {
w.Write(bb[i])
}
}
func reverseFlush(w io.Writer, bb [][]byte) {
for i := len(bb) - 1; i >= 0; i-- {
w.Write(bb[i])
}
}

View File

@ -199,8 +199,8 @@ func MakeFillerTypeSpecificBarOption(
}
}
// BarOptOnCond returns option when condition evaluates to true.
func BarOptOnCond(option BarOption, condition func() bool) BarOption {
// BarOptOn returns option when condition evaluates to true.
func BarOptOn(option BarOption, condition func() bool) BarOption {
if condition() {
return option
}

21
vendor/github.com/vbauerster/mpb/v4/decor/any.go generated vendored Normal file
View File

@ -0,0 +1,21 @@
package decor
// Any decorator displays text, that can be changed during decorator's
// lifetime via provided func call back.
//
// `f` call back which provides string to display
//
// `wcc` optional WC config
//
func Any(f func(*Statistics) string, wcc ...WC) Decorator {
return &any{initWC(wcc...), f}
}
type any struct {
WC
f func(*Statistics) string
}
func (d *any) Decor(s *Statistics) string {
return d.FormatMsg(d.f(s))
}

View File

@ -43,24 +43,7 @@ func CountersKiloByte(pairFmt string, wcc ...WC) Decorator {
// pairFmt="% d / % d" output: "1 MB / 12 MB"
//
func Counters(unit int, pairFmt string, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
d := &countersDecorator{
WC: wc.Init(),
producer: chooseSizeProducer(unit, pairFmt),
}
return d
}
type countersDecorator struct {
WC
producer func(*Statistics) string
}
func (d *countersDecorator) Decor(st *Statistics) string {
return d.FormatMsg(d.producer(st))
return Any(chooseSizeProducer(unit, pairFmt), wcc...)
}
func chooseSizeProducer(unit int, format string) func(*Statistics) string {
@ -69,16 +52,16 @@ func chooseSizeProducer(unit int, format string) func(*Statistics) string {
}
switch unit {
case UnitKiB:
return func(st *Statistics) string {
return fmt.Sprintf(format, SizeB1024(st.Current), SizeB1024(st.Total))
return func(s *Statistics) string {
return fmt.Sprintf(format, SizeB1024(s.Current), SizeB1024(s.Total))
}
case UnitKB:
return func(st *Statistics) string {
return fmt.Sprintf(format, SizeB1000(st.Current), SizeB1000(st.Total))
return func(s *Statistics) string {
return fmt.Sprintf(format, SizeB1000(s.Current), SizeB1000(s.Total))
}
default:
return func(st *Statistics) string {
return fmt.Sprintf(format, st.Current, st.Total)
return func(s *Statistics) string {
return fmt.Sprintf(format, s.Current, s.Total)
}
}
}

View File

@ -176,3 +176,11 @@ func (wc *WC) GetConf() WC {
func (wc *WC) SetConf(conf WC) {
*wc = conf.Init()
}
func initWC(wcc ...WC) WC {
var wc WC
for _, nwc := range wcc {
wc = nwc
}
return wc.Init()
}

View File

@ -9,6 +9,7 @@ import (
// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
//
// `wcc` optional WC config
//
func Elapsed(style TimeStyle, wcc ...WC) Decorator {
return NewElapsed(style, time.Now(), wcc...)
}
@ -20,29 +21,15 @@ func Elapsed(style TimeStyle, wcc ...WC) Decorator {
// `startTime` start time
//
// `wcc` optional WC config
//
func NewElapsed(style TimeStyle, startTime time.Time, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
var msg string
producer := chooseTimeProducer(style)
f := func(s *Statistics) string {
if !s.Completed {
msg = producer(time.Since(startTime))
}
return msg
}
d := &elapsedDecorator{
WC: wc.Init(),
startTime: startTime,
producer: chooseTimeProducer(style),
}
return d
}
type elapsedDecorator struct {
WC
startTime time.Time
producer func(time.Duration) string
msg string
}
func (d *elapsedDecorator) Decor(st *Statistics) string {
if !st.Completed {
d.msg = d.producer(time.Since(d.startTime))
}
return d.FormatMsg(d.msg)
return Any(f, wcc...)
}

View File

@ -33,7 +33,7 @@ func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator {
} else {
average = ewma.NewMovingAverage(age)
}
return MovingAverageETA(style, average, nil, wcc...)
return MovingAverageETA(style, NewThreadSafeMovingAverage(average), nil, wcc...)
}
// MovingAverageETA decorator relies on MovingAverage implementation to calculate its average.
@ -45,13 +45,10 @@ func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator {
// `normalizer` available implementations are [FixedIntervalTimeNormalizer|MaxTolerateTimeNormalizer]
//
// `wcc` optional WC config
//
func MovingAverageETA(style TimeStyle, average MovingAverage, normalizer TimeNormalizer, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
d := &movingAverageETA{
WC: wc.Init(),
WC: initWC(wcc...),
average: average,
normalizer: normalizer,
producer: chooseTimeProducer(style),
@ -66,9 +63,9 @@ type movingAverageETA struct {
producer func(time.Duration) string
}
func (d *movingAverageETA) Decor(st *Statistics) string {
func (d *movingAverageETA) Decor(s *Statistics) string {
v := math.Round(d.average.Value())
remaining := time.Duration((st.Total - st.Current) * int64(v))
remaining := time.Duration((s.Total - s.Current) * int64(v))
if d.normalizer != nil {
remaining = d.normalizer.Normalize(remaining)
}
@ -92,6 +89,7 @@ func (d *movingAverageETA) NextAmount(n int64, wdd ...time.Duration) {
// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
//
// `wcc` optional WC config
//
func AverageETA(style TimeStyle, wcc ...WC) Decorator {
return NewAverageETA(style, time.Now(), nil, wcc...)
}
@ -105,13 +103,10 @@ func AverageETA(style TimeStyle, wcc ...WC) Decorator {
// `normalizer` available implementations are [FixedIntervalTimeNormalizer|MaxTolerateTimeNormalizer]
//
// `wcc` optional WC config
//
func NewAverageETA(style TimeStyle, startTime time.Time, normalizer TimeNormalizer, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
d := &averageETA{
WC: wc.Init(),
WC: initWC(wcc...),
startTime: startTime,
normalizer: normalizer,
producer: chooseTimeProducer(style),
@ -126,12 +121,12 @@ type averageETA struct {
producer func(time.Duration) string
}
func (d *averageETA) Decor(st *Statistics) string {
func (d *averageETA) Decor(s *Statistics) string {
var remaining time.Duration
if st.Current != 0 {
durPerItem := float64(time.Since(d.startTime)) / float64(st.Current)
if s.Current != 0 {
durPerItem := float64(time.Since(d.startTime)) / float64(s.Current)
durPerItem = math.Round(durPerItem)
remaining = time.Duration((st.Total - st.Current) * int64(durPerItem))
remaining = time.Duration((s.Total - s.Current) * int64(durPerItem))
if d.normalizer != nil {
remaining = d.normalizer.Normalize(remaining)
}

View File

@ -64,8 +64,8 @@ func (d *mergeDecorator) Base() Decorator {
return d.Decorator
}
func (d *mergeDecorator) Decor(st *Statistics) string {
msg := d.Decorator.Decor(st)
func (d *mergeDecorator) Decor(s *Statistics) string {
msg := d.Decorator.Decor(s)
msgLen := utf8.RuneCountInString(msg)
if (d.wc.C & DextraSpace) != 0 {
msgLen++
@ -101,6 +101,6 @@ type placeHolderDecorator struct {
WC
}
func (d *placeHolderDecorator) Decor(_ *Statistics) string {
func (d *placeHolderDecorator) Decor(*Statistics) string {
return ""
}

View File

@ -2,6 +2,7 @@ package decor
import (
"sort"
"sync"
"github.com/VividCortex/ewma"
)
@ -11,6 +12,38 @@ import (
// or exponentially decaying.
type MovingAverage = ewma.MovingAverage
type threadSafeMovingAverage struct {
ewma.MovingAverage
mu sync.Mutex
}
func (s *threadSafeMovingAverage) Add(value float64) {
s.mu.Lock()
s.MovingAverage.Add(value)
s.mu.Unlock()
}
func (s *threadSafeMovingAverage) Value() float64 {
s.mu.Lock()
defer s.mu.Unlock()
return s.MovingAverage.Value()
}
func (s *threadSafeMovingAverage) Set(value float64) {
s.mu.Lock()
s.MovingAverage.Set(value)
s.mu.Unlock()
}
// NewThreadSafeMovingAverage converts provided ewma.MovingAverage
// into thread safe ewma.MovingAverage.
func NewThreadSafeMovingAverage(average ewma.MovingAverage) ewma.MovingAverage {
if tsma, ok := average.(*threadSafeMovingAverage); ok {
return tsma
}
return &threadSafeMovingAverage{MovingAverage: average}
}
type medianWindow [3]float64
func (s *medianWindow) Len() int { return len(s) }
@ -36,5 +69,5 @@ func (s *medianWindow) Set(value float64) {
// NewMedian is fixed last 3 samples median MovingAverage.
func NewMedian() MovingAverage {
return new(medianWindow)
return NewThreadSafeMovingAverage(new(medianWindow))
}

View File

@ -1,27 +1,12 @@
package decor
// Name returns name decorator.
// Name decorator displays text that is set once and can't be changed
// during decorator's lifetime.
//
// `name` string to display
// `str` string to display
//
// `wcc` optional WC config
func Name(name string, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
d := &nameDecorator{
WC: wc.Init(),
msg: name,
}
return d
}
type nameDecorator struct {
WC
msg string
}
func (d *nameDecorator) Decor(st *Statistics) string {
return d.FormatMsg(d.msg)
//
func Name(str string, wcc ...WC) Decorator {
return Any(func(*Statistics) string { return str }, wcc...)
}

View File

@ -6,6 +6,7 @@ package decor
// `decorator` Decorator to wrap
//
// `message` message to display on complete event
//
func OnComplete(decorator Decorator, message string) Decorator {
d := &onCompleteWrapper{
Decorator: decorator,
@ -23,12 +24,12 @@ type onCompleteWrapper struct {
msg string
}
func (d *onCompleteWrapper) Decor(st *Statistics) string {
if st.Completed {
func (d *onCompleteWrapper) Decor(s *Statistics) string {
if s.Completed {
wc := d.GetConf()
return wc.FormatMsg(d.msg)
}
return d.Decorator.Decor(st)
return d.Decorator.Decor(s)
}
func (d *onCompleteWrapper) Base() Decorator {

View File

@ -37,36 +37,22 @@ func Percentage(wcc ...WC) Decorator {
return NewPercentage("% d", wcc...)
}
// NewPercentage percentage decorator with custom fmt string.
// NewPercentage percentage decorator with custom format string.
//
// fmt examples:
// format examples:
//
// fmt="%.1f" output: "1.0%"
// fmt="% .1f" output: "1.0 %"
// fmt="%d" output: "1%"
// fmt="% d" output: "1 %"
// format="%.1f" output: "1.0%"
// format="% .1f" output: "1.0 %"
// format="%d" output: "1%"
// format="% d" output: "1 %"
//
func NewPercentage(fmt string, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
func NewPercentage(format string, wcc ...WC) Decorator {
if format == "" {
format = "% d"
}
if fmt == "" {
fmt = "% d"
f := func(s *Statistics) string {
p := internal.Percentage(s.Total, s.Current, 100)
return fmt.Sprintf(format, percentageType(p))
}
d := &percentageDecorator{
WC: wc.Init(),
fmt: fmt,
}
return d
}
type percentageDecorator struct {
WC
fmt string
}
func (d *percentageDecorator) Decor(st *Statistics) string {
p := internal.Percentage(st.Total, st.Current, 100)
return d.FormatMsg(fmt.Sprintf(d.fmt, percentageType(p)))
return Any(f, wcc...)
}

View File

@ -9,12 +9,20 @@ import (
"github.com/VividCortex/ewma"
)
// SpeedFormatter is wrapper for SizeB1024 and SizeB1000 to format value as speed/s.
type SpeedFormatter struct {
// FmtAsSpeed adds "/s" to the end of the input formatter. To be
// used with SizeB1000 or SizeB1024 types, for example:
//
// fmt.Printf("%.1f", FmtAsSpeed(SizeB1024(2048)))
//
func FmtAsSpeed(input fmt.Formatter) fmt.Formatter {
return &speedFormatter{input}
}
type speedFormatter struct {
fmt.Formatter
}
func (self *SpeedFormatter) Format(st fmt.State, verb rune) {
func (self *speedFormatter) Format(st fmt.State, verb rune) {
self.Formatter.Format(st, verb)
io.WriteString(st, "/s")
}
@ -30,7 +38,7 @@ func EwmaSpeed(unit int, format string, age float64, wcc ...WC) Decorator {
} else {
average = ewma.NewMovingAverage(age)
}
return MovingAverageSpeed(unit, format, average, wcc...)
return MovingAverageSpeed(unit, format, NewThreadSafeMovingAverage(average), wcc...)
}
// MovingAverageSpeed decorator relies on MovingAverage implementation
@ -52,15 +60,11 @@ func EwmaSpeed(unit int, format string, age float64, wcc ...WC) Decorator {
// unit=UnitKB, format="% .1f" output: "1.0 MB/s"
//
func MovingAverageSpeed(unit int, format string, average MovingAverage, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
if format == "" {
format = "%.0f"
}
d := &movingAverageSpeed{
WC: wc.Init(),
WC: initWC(wcc...),
average: average,
producer: chooseSpeedProducer(unit, format),
}
@ -74,8 +78,8 @@ type movingAverageSpeed struct {
msg string
}
func (d *movingAverageSpeed) Decor(st *Statistics) string {
if !st.Completed {
func (d *movingAverageSpeed) Decor(s *Statistics) string {
if !s.Completed {
var speed float64
if v := d.average.Value(); v > 0 {
speed = 1 / v
@ -122,15 +126,11 @@ func AverageSpeed(unit int, format string, wcc ...WC) Decorator {
// unit=UnitKB, format="% .1f" output: "1.0 MB/s"
//
func NewAverageSpeed(unit int, format string, startTime time.Time, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
if format == "" {
format = "%.0f"
}
d := &averageSpeed{
WC: wc.Init(),
WC: initWC(wcc...),
startTime: startTime,
producer: chooseSpeedProducer(unit, format),
}
@ -144,9 +144,9 @@ type averageSpeed struct {
msg string
}
func (d *averageSpeed) Decor(st *Statistics) string {
if !st.Completed {
speed := float64(st.Current) / float64(time.Since(d.startTime))
func (d *averageSpeed) Decor(s *Statistics) string {
if !s.Completed {
speed := float64(s.Current) / float64(time.Since(d.startTime))
d.msg = d.producer(speed * 1e9)
}
@ -161,11 +161,11 @@ func chooseSpeedProducer(unit int, format string) func(float64) string {
switch unit {
case UnitKiB:
return func(speed float64) string {
return fmt.Sprintf(format, &SpeedFormatter{SizeB1024(math.Round(speed))})
return fmt.Sprintf(format, FmtAsSpeed(SizeB1024(math.Round(speed))))
}
case UnitKB:
return func(speed float64) string {
return fmt.Sprintf(format, &SpeedFormatter{SizeB1000(math.Round(speed))})
return fmt.Sprintf(format, FmtAsSpeed(SizeB1000(math.Round(speed))))
}
default:
return func(speed float64) string {

View File

@ -8,28 +8,14 @@ var defaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "
//
// `wcc` optional WC config
func Spinner(frames []string, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
if len(frames) == 0 {
frames = defaultSpinnerStyle
}
d := &spinnerDecorator{
WC: wc.Init(),
frames: frames,
var count uint
f := func(s *Statistics) string {
frame := frames[count%uint(len(frames))]
count++
return frame
}
return d
}
type spinnerDecorator struct {
WC
frames []string
count uint
}
func (d *spinnerDecorator) Decor(st *Statistics) string {
frame := d.frames[d.count%uint(len(d.frames))]
d.count++
return d.FormatMsg(frame)
return Any(f, wcc...)
}

View File

@ -3,8 +3,8 @@ module github.com/vbauerster/mpb/v4
require (
github.com/VividCortex/ewma v1.1.1
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 // indirect
golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6
golang.org/x/sys v0.0.0-20200217220822-9197077df867 // indirect
)
go 1.13

View File

@ -3,11 +3,11 @@ github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmx
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708 h1:pXVtWnwHkrWD9ru3sDxY/qFK/bfc0egRovX91EjWjf4=
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6 h1:Sy5bstxEqwwbYs6n0/pBuxKENqOeZUgD45Gp3Q3pqLg=
golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk=
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867 h1:JoRuNIf+rpHl+VhScRQQvzbHed86tKkqwPMV34T8myw=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@ -96,8 +96,8 @@ func PopCompletedMode() ContainerOption {
}
}
// ContainerOptOnCond returns option when condition evaluates to true.
func ContainerOptOnCond(option ContainerOption, condition func() bool) ContainerOption {
// ContainerOptOn returns option when condition evaluates to true.
func ContainerOptOn(option ContainerOption, condition func() bool) ContainerOption {
if condition() {
return option
}

View File

@ -4,6 +4,7 @@ import (
"bytes"
"container/heap"
"context"
"fmt"
"io"
"io/ioutil"
"log"
@ -97,18 +98,19 @@ func NewWithContext(ctx context.Context, options ...ContainerOption) *Progress {
return p
}
// AddBar creates a new progress bar and adds to the container.
// AddBar creates a new progress bar and adds it to the rendering queue.
func (p *Progress) AddBar(total int64, options ...BarOption) *Bar {
return p.Add(total, NewBarFiller(DefaultBarStyle, false), options...)
}
// AddSpinner creates a new spinner bar and adds to the container.
// AddSpinner creates a new spinner bar and adds it to the rendering queue.
func (p *Progress) AddSpinner(total int64, alignment SpinnerAlignment, options ...BarOption) *Bar {
return p.Add(total, NewSpinnerFiller(DefaultSpinnerStyle, alignment), options...)
}
// Add creates a bar which renders itself by provided filler.
// Set total to 0, if you plan to update it later.
// Panics if *Progress instance is done, i.e. called after *Progress.Wait().
func (p *Progress) Add(total int64, filler Filler, options ...BarOption) *Bar {
if filler == nil {
filler = NewBarFiller(DefaultBarStyle, false)
@ -134,7 +136,7 @@ func (p *Progress) Add(total int64, filler Filler, options ...BarOption) *Bar {
return bar
case <-p.done:
p.bwg.Done()
return nil
panic(fmt.Sprintf("%T instance can't be reused after it's done!", p))
}
}
@ -387,7 +389,7 @@ func syncWidth(matrix map[int][]chan int) {
}
func extractBaseFiller(f Filler) Filler {
if f, ok := f.(Wrapper); ok {
if f, ok := f.(WrapFiller); ok {
return extractBaseFiller(f.Base())
}
return f

View File

@ -18,7 +18,7 @@ const (
SpinnerOnRight
)
// DefaultSpinnerStyle is applied when bar constructed with *Progress.AddSpinner method.
// DefaultSpinnerStyle is a slice of strings, which makes a spinner.
var DefaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
type spinnerFiller struct {
@ -27,7 +27,7 @@ type spinnerFiller struct {
alignment SpinnerAlignment
}
// NewSpinnerFiller constucts mpb.Filler, to be used with *Progress.Add method.
// NewSpinnerFiller constucts mpb.Filler, to be used with *Progress.Add(...) *Bar method.
func NewSpinnerFiller(style []string, alignment SpinnerAlignment) Filler {
if len(style) == 0 {
style = DefaultSpinnerStyle