Enable 'OptimizeDestinationImageAlreadyExists' feature

Signed-off-by: George Jenkins <gjenkins8@bloomberg.net>
This commit is contained in:
George Jenkins
2021-02-24 19:41:57 +13:00
committed by Valentin Rothberg
parent 2c8655e251
commit 61b62f9e93
107 changed files with 3195 additions and 394 deletions

View File

@@ -1,10 +0,0 @@
module github.com/vbauerster/mpb/v5
require (
github.com/VividCortex/ewma v1.1.1
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/mattn/go-runewidth v0.0.9
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742
)
go 1.14

View File

@@ -1,8 +0,0 @@
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
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=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 h1:+CBz4km/0KPU3RGTwARGh/noP3bEwtHcq+0YcBQM2JQ=
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@@ -1,8 +0,0 @@
package internal
func WidthForBarFiller(reqWidth, available int) int {
if reqWidth <= 0 || reqWidth >= available {
return available
}
return reqWidth
}

View File

@@ -1,6 +1,6 @@
# Multi Progress Bar
[![GoDoc](https://godoc.org/github.com/vbauerster/mpb?status.svg)](https://godoc.org/github.com/vbauerster/mpb)
[![GoDoc](https://pkg.go.dev/badge/github.com/vbauerster/mpb)](https://pkg.go.dev/github.com/vbauerster/mpb/v6)
[![Build Status](https://travis-ci.org/vbauerster/mpb.svg?branch=master)](https://travis-ci.org/vbauerster/mpb)
[![Go Report Card](https://goreportcard.com/badge/github.com/vbauerster/mpb)](https://goreportcard.com/report/github.com/vbauerster/mpb)
@@ -8,16 +8,17 @@
## Features
* __Multiple Bars__: Multiple progress bars are supported
* __Dynamic Total__: Set total while bar is running
* __Dynamic Add/Remove__: Dynamically add or remove bars
* __Cancellation__: Cancel whole rendering process
* __Predefined Decorators__: Elapsed time, [ewma](https://github.com/VividCortex/ewma) based ETA, Percentage, Bytes counter
* __Decorator's width sync__: Synchronized decorator's width among multiple bars
- **Multiple Bars**: Multiple progress bars are supported
- **Dynamic Total**: Set total while bar is running
- **Dynamic Add/Remove**: Dynamically add or remove bars
- **Cancellation**: Cancel whole rendering process
- **Predefined Decorators**: Elapsed time, [ewma](https://github.com/VividCortex/ewma) based ETA, Percentage, Bytes counter
- **Decorator's width sync**: Synchronized decorator's width among multiple bars
## Usage
#### [Rendering single bar](_examples/singleBar/main.go)
```go
package main
@@ -25,8 +26,8 @@ import (
"math/rand"
"time"
"github.com/vbauerster/mpb/v5"
"github.com/vbauerster/mpb/v5/decor"
"github.com/vbauerster/mpb/v6"
"github.com/vbauerster/mpb/v6/decor"
)
func main() {
@@ -36,9 +37,9 @@ func main() {
total := 100
name := "Single Bar:"
// adding a single bar, which will inherit container's width
bar := p.AddBar(int64(total),
// override DefaultBarStyle, which is "[=>-]<+"
mpb.BarStyle("╢▌▌░╟"),
bar := p.Add(int64(total),
// progress bar filler with customized style
mpb.NewBarFiller("╢▌▌░╟"),
mpb.PrependDecorators(
// display our name with one space on the right
decor.Name(name, decor.WC{W: len(name) + 1, C: decor.DidentRight}),
@@ -61,6 +62,7 @@ func main() {
```
#### [Rendering multiple bars](_examples/multiBars/main.go)
```go
var wg sync.WaitGroup
// pass &wg (optional), so p will wait for it eventually

View File

@@ -12,10 +12,10 @@ import (
"github.com/acarl005/stripansi"
"github.com/mattn/go-runewidth"
"github.com/vbauerster/mpb/v5/decor"
"github.com/vbauerster/mpb/v6/decor"
)
// Bar represents a progress Bar.
// Bar represents a progress bar.
type Bar struct {
priority int // used by heap
index int // used by heap
@@ -42,8 +42,10 @@ type Bar struct {
recoveredPanic interface{}
}
type extFunc func(in io.Reader, reqWidth int, st decor.Statistics) (out io.Reader, lines int)
type extenderFunc func(in io.Reader, reqWidth int, st decor.Statistics) (out io.Reader, lines int)
// bState is actual bar state. It gets passed to *Bar.serve(...) monitor
// goroutine.
type bState struct {
id int
priority int
@@ -54,9 +56,9 @@ type bState struct {
lastN int64
iterated bool
trimSpace bool
toComplete bool
completed bool
completeFlushed bool
ignoreComplete bool
triggerComplete bool
dropOnComplete bool
noPop bool
aDecorators []decor.Decorator
@@ -67,7 +69,7 @@ type bState struct {
bufP, bufB, bufA *bytes.Buffer
filler BarFiller
middleware func(BarFiller) BarFiller
extender extFunc
extender extenderFunc
// runningBar is a key for *pState.parkedBars
runningBar *Bar
@@ -128,9 +130,10 @@ func (b *Bar) Current() int64 {
}
}
// SetRefill fills bar with refill rune up to amount argument.
// Given default bar style is "[=>-]<+", refill rune is '+'.
// To set bar style use mpb.BarStyle(string) BarOption.
// SetRefill sets refill flag with specified amount.
// The underlying BarFiller will change its visual representation, to
// indicate refill event. Refill event may be referred to some retry
// operation for example.
func (b *Bar) SetRefill(amount int64) {
select {
case b.operateState <- func(s *bState) {
@@ -159,19 +162,18 @@ func (b *Bar) TraverseDecorators(cb func(decor.Decorator)) {
// SetTotal sets total dynamically.
// If total is less than or equal to zero it takes progress' current value.
// A complete flag enables or disables complete event on `current >= total`.
func (b *Bar) SetTotal(total int64, complete bool) {
func (b *Bar) SetTotal(total int64, triggerComplete bool) {
select {
case b.operateState <- func(s *bState) {
s.ignoreComplete = !complete
s.triggerComplete = triggerComplete
if total <= 0 {
s.total = s.current
} else {
s.total = total
}
if !s.ignoreComplete && !s.toComplete {
if s.triggerComplete && !s.completed {
s.current = s.total
s.toComplete = true
s.completed = true
go b.refreshTillShutdown()
}
}:
@@ -187,9 +189,9 @@ func (b *Bar) SetCurrent(current int64) {
s.iterated = true
s.lastN = current - s.current
s.current = current
if !s.ignoreComplete && s.current >= s.total {
if s.triggerComplete && s.current >= s.total {
s.current = s.total
s.toComplete = true
s.completed = true
go b.refreshTillShutdown()
}
}:
@@ -214,9 +216,9 @@ func (b *Bar) IncrInt64(n int64) {
s.iterated = true
s.lastN = n
s.current += n
if !s.ignoreComplete && s.current >= s.total {
if s.triggerComplete && s.current >= s.total {
s.current = s.total
s.toComplete = true
s.completed = true
go b.refreshTillShutdown()
}
}:
@@ -280,7 +282,7 @@ func (b *Bar) Abort(drop bool) {
// Completed reports whether the bar is in completed state.
func (b *Bar) Completed() bool {
select {
case b.operateState <- func(s *bState) { b.completed <- s.toComplete }:
case b.operateState <- func(s *bState) { b.completed <- s.completed }:
return <-b.completed
case <-b.done:
return true
@@ -322,11 +324,11 @@ func (b *Bar) render(tw int) {
b.frameCh <- frame
b.dlogger.Println(p)
}
s.completeFlushed = s.toComplete
s.completeFlushed = s.completed
}()
frame, lines := s.extender(s.draw(stat), s.reqWidth, stat)
b.extendedLines = lines
b.toShutdown = s.toComplete && !s.completeFlushed
b.toShutdown = s.completed && !s.completeFlushed
b.frameCh <- frame
}:
case <-b.done:
@@ -475,7 +477,7 @@ func ewmaIterationUpdate(done bool, s *bState, dur time.Duration) {
}
}
func makePanicExtender(p interface{}) extFunc {
func makePanicExtender(p interface{}) extenderFunc {
pstr := fmt.Sprint(p)
stack := debug.Stack()
stackLines := bytes.Count(stack, []byte("\n"))

View File

@@ -3,19 +3,20 @@ package mpb
import (
"io"
"github.com/vbauerster/mpb/v5/decor"
"github.com/vbauerster/mpb/v6/decor"
)
// BarFiller interface.
// Bar (without decorators) renders itself by calling BarFiller's Fill method.
//
// `reqWidth` is requested width, which is set via:
// func WithWidth(width int) ContainerOption
// func BarWidth(width int) BarOption
// reqWidth is requested width, set by `func WithWidth(int) ContainerOption`.
// If not set, it defaults to terminal width.
//
// Default implementations can be obtained via:
//
// func NewBarFiller(style string, reverse bool) BarFiller
// func NewBarFiller(style string) BarFiller
// func NewBarFillerRev(style string) BarFiller
// func NewBarFillerPick(style string, rev bool) BarFiller
// func NewSpinnerFiller(style []string, alignment SpinnerAlignment) BarFiller
//
type BarFiller interface {

View File

@@ -6,8 +6,9 @@ import (
"unicode/utf8"
"github.com/mattn/go-runewidth"
"github.com/vbauerster/mpb/v5/decor"
"github.com/vbauerster/mpb/v5/internal"
"github.com/rivo/uniseg"
"github.com/vbauerster/mpb/v6/decor"
"github.com/vbauerster/mpb/v6/internal"
)
const (
@@ -20,8 +21,8 @@ const (
rRefill
)
// DefaultBarStyle is a string containing 7 runes.
// Each rune is a building block of a progress bar.
// BarDefaultStyle is a style for rendering a progress bar.
// It consist of 7 ordered runes:
//
// '1st rune' stands for left boundary rune
//
@@ -37,7 +38,7 @@ const (
//
// '7th rune' stands for refill rune
//
const DefaultBarStyle string = "[=>-]<+"
const BarDefaultStyle string = "[=>-]<+"
type barFiller struct {
format [][]byte
@@ -54,55 +55,72 @@ type space struct {
count int
}
// NewBarFiller constucts mpb.BarFiller, to be used with *Progress.Add(...) *Bar method.
func NewBarFiller(style string, reverse bool) BarFiller {
// NewBarFiller returns a BarFiller implementation which renders a
// progress bar in regular direction. If style is empty string,
// BarDefaultStyle is applied. To be used with `*Progress.Add(...)
// *Bar` method.
func NewBarFiller(style string) BarFiller {
return newBarFiller(style, false)
}
// NewBarFillerRev returns a BarFiller implementation which renders a
// progress bar in reverse direction. If style is empty string,
// BarDefaultStyle is applied. To be used with `*Progress.Add(...)
// *Bar` method.
func NewBarFillerRev(style string) BarFiller {
return newBarFiller(style, true)
}
// NewBarFillerPick pick between regular and reverse BarFiller implementation
// based on rev param. To be used with `*Progress.Add(...) *Bar` method.
func NewBarFillerPick(style string, rev bool) BarFiller {
return newBarFiller(style, rev)
}
func newBarFiller(style string, rev bool) BarFiller {
bf := &barFiller{
format: make([][]byte, len(DefaultBarStyle)),
rwidth: make([]int, len(DefaultBarStyle)),
reverse: reverse,
format: make([][]byte, len(BarDefaultStyle)),
rwidth: make([]int, len(BarDefaultStyle)),
reverse: rev,
}
bf.parse(BarDefaultStyle)
if style != "" && style != BarDefaultStyle {
bf.parse(style)
}
bf.SetStyle(style)
return bf
}
func (s *barFiller) SetStyle(style string) {
func (s *barFiller) parse(style string) {
if !utf8.ValidString(style) {
panic("invalid bar style")
}
if style == "" {
style = DefaultBarStyle
srcFormat := make([][]byte, 0, len(BarDefaultStyle))
srcRwidth := make([]int, 0, len(BarDefaultStyle))
gr := uniseg.NewGraphemes(style)
for gr.Next() {
srcFormat = append(srcFormat, gr.Bytes())
srcRwidth = append(srcRwidth, runewidth.StringWidth(gr.Str()))
}
src := make([][]byte, utf8.RuneCountInString(style))
i := 0
for _, r := range style {
s.rwidth[i] = runewidth.RuneWidth(r)
src[i] = []byte(string(r))
i++
}
copy(s.format, src)
s.SetReverse(s.reverse)
}
func (s *barFiller) SetReverse(reverse bool) {
if reverse {
copy(s.format, srcFormat)
copy(s.rwidth, srcRwidth)
if s.reverse {
s.tip = s.format[rRevTip]
s.flush = reverseFlush
} else {
s.tip = s.format[rTip]
s.flush = regularFlush
}
s.reverse = reverse
}
func (s *barFiller) Fill(w io.Writer, reqWidth int, stat decor.Statistics) {
width := internal.WidthForBarFiller(reqWidth, stat.AvailableWidth)
if brackets := s.rwidth[rLeft] + s.rwidth[rRight]; width < brackets {
width := internal.CheckRequestedWidth(reqWidth, stat.AvailableWidth)
brackets := s.rwidth[rLeft] + s.rwidth[rRight]
if width < brackets {
return
} else {
// don't count brackets as progress
width -= brackets
}
// don't count brackets as progress
width -= brackets
w.Write(s.format[rLeft])
defer w.Write(s.format[rRight])

View File

@@ -3,10 +3,10 @@ package mpb
import (
"io"
"strings"
"unicode/utf8"
"github.com/vbauerster/mpb/v5/decor"
"github.com/vbauerster/mpb/v5/internal"
"github.com/mattn/go-runewidth"
"github.com/vbauerster/mpb/v6/decor"
"github.com/vbauerster/mpb/v6/internal"
)
// SpinnerAlignment enum.
@@ -19,8 +19,8 @@ const (
SpinnerOnRight
)
// DefaultSpinnerStyle is a slice of strings, which makes a spinner.
var DefaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
// SpinnerDefaultStyle is a style for rendering a spinner.
var SpinnerDefaultStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
type spinnerFiller struct {
frames []string
@@ -28,10 +28,12 @@ type spinnerFiller struct {
alignment SpinnerAlignment
}
// NewSpinnerFiller constucts mpb.BarFiller, to be used with *Progress.Add(...) *Bar method.
// NewSpinnerFiller returns a BarFiller implementation which renders
// a spinner. If style is nil or zero length, SpinnerDefaultStyle is
// applied. To be used with `*Progress.Add(...) *Bar` method.
func NewSpinnerFiller(style []string, alignment SpinnerAlignment) BarFiller {
if len(style) == 0 {
style = DefaultSpinnerStyle
style = SpinnerDefaultStyle
}
filler := &spinnerFiller{
frames: style,
@@ -41,10 +43,10 @@ func NewSpinnerFiller(style []string, alignment SpinnerAlignment) BarFiller {
}
func (s *spinnerFiller) Fill(w io.Writer, reqWidth int, stat decor.Statistics) {
width := internal.WidthForBarFiller(reqWidth, stat.AvailableWidth)
width := internal.CheckRequestedWidth(reqWidth, stat.AvailableWidth)
frame := s.frames[s.count%uint(len(s.frames))]
frameWidth := utf8.RuneCountInString(frame)
frameWidth := runewidth.StringWidth(frame)
if width < frameWidth {
return

View File

@@ -4,10 +4,11 @@ import (
"bytes"
"io"
"github.com/vbauerster/mpb/v5/decor"
"github.com/vbauerster/mpb/v6/decor"
"github.com/vbauerster/mpb/v6/internal"
)
// BarOption is a function option which changes the default behavior of a bar.
// BarOption is a func option to alter default behavior of a bar.
type BarOption func(*bState)
func (s *bState) addDecorators(dest *[]decor.Decorator, decorators ...decor.Decorator) {
@@ -88,7 +89,7 @@ func BarFillerOnComplete(message string) BarOption {
})
}
// BarFillerMiddleware provides a way to augment default BarFiller.
// BarFillerMiddleware provides a way to augment the underlying BarFiller.
func BarFillerMiddleware(middle func(BarFiller) BarFiller) BarOption {
return func(s *bState) {
s.middleware = middle
@@ -104,18 +105,17 @@ func BarPriority(priority int) BarOption {
}
}
// BarExtender is an option to extend bar to the next new line, with
// arbitrary output.
// BarExtender provides a way to extend bar to the next new line.
func BarExtender(filler BarFiller) BarOption {
if filler == nil {
return nil
}
return func(s *bState) {
s.extender = makeExtFunc(filler)
s.extender = makeExtenderFunc(filler)
}
}
func makeExtFunc(filler BarFiller) extFunc {
func makeExtenderFunc(filler BarFiller) extenderFunc {
buf := new(bytes.Buffer)
return func(r io.Reader, reqWidth int, st decor.Statistics) (io.Reader, int) {
filler.Fill(buf, reqWidth, st)
@@ -123,37 +123,13 @@ func makeExtFunc(filler BarFiller) extFunc {
}
}
// BarFillerTrim bar filler is rendered with leading and trailing space
// like ' [===] ' by default. With this option leading and trailing
// space will be removed.
// BarFillerTrim removes leading and trailing space around the underlying BarFiller.
func BarFillerTrim() BarOption {
return func(s *bState) {
s.trimSpace = true
}
}
// TrimSpace is an alias to BarFillerTrim.
func TrimSpace() BarOption {
return BarFillerTrim()
}
// BarStyle overrides mpb.DefaultBarStyle which is "[=>-]<+".
// It's ok to pass string containing just 5 runes, for example "╢▌▌░╟",
// if you don't need to override '<' (reverse tip) and '+' (refill rune).
func BarStyle(style string) BarOption {
if style == "" {
return nil
}
type styleSetter interface {
SetStyle(string)
}
return func(s *bState) {
if t, ok := s.filler.(styleSetter); ok {
t.SetStyle(style)
}
}
}
// BarNoPop disables bar pop out of container. Effective when
// PopCompletedMode of container is enabled.
func BarNoPop() BarOption {
@@ -162,51 +138,15 @@ func BarNoPop() BarOption {
}
}
// BarReverse reverse mode, bar will progress from right to left.
func BarReverse() BarOption {
type revSetter interface {
SetReverse(bool)
}
return func(s *bState) {
if t, ok := s.filler.(revSetter); ok {
t.SetReverse(true)
}
}
// BarOptional will invoke provided option only when pick is true.
func BarOptional(option BarOption, pick bool) BarOption {
return BarOptOn(option, internal.Predicate(pick))
}
// SpinnerStyle sets custom spinner style.
// Effective when Filler type is spinner.
func SpinnerStyle(frames []string) BarOption {
if len(frames) == 0 {
return nil
}
chk := func(filler BarFiller) (interface{}, bool) {
t, ok := filler.(*spinnerFiller)
return t, ok
}
cb := func(t interface{}) {
t.(*spinnerFiller).frames = frames
}
return MakeFillerTypeSpecificBarOption(chk, cb)
}
// MakeFillerTypeSpecificBarOption makes BarOption specific to Filler's
// actual type. If you implement your own Filler, so most probably
// you'll need this. See BarStyle or SpinnerStyle for example.
func MakeFillerTypeSpecificBarOption(
typeChecker func(BarFiller) (interface{}, bool),
cb func(interface{}),
) BarOption {
return func(s *bState) {
if t, ok := typeChecker(s.filler); ok {
cb(t)
}
}
}
// BarOptOn returns option when condition evaluates to true.
func BarOptOn(option BarOption, condition func() bool) BarOption {
if condition() {
// BarOptOn will invoke provided option only when higher order predicate
// evaluates to true.
func BarOptOn(option BarOption, predicate func() bool) BarOption {
if predicate() {
return option
}
return nil

View File

@@ -5,10 +5,13 @@ import (
"io/ioutil"
"sync"
"time"
"github.com/vbauerster/mpb/v6/internal"
)
// ContainerOption is a function option which changes the default
// behavior of progress container, if passed to mpb.New(...ContainerOption).
// ContainerOption is a func option to alter default behavior of a bar
// container. Container term refers to a Progress struct which can
// hold one or more Bars.
type ContainerOption func(*pState)
// WithWaitGroup provides means to have a single joint point. If
@@ -21,8 +24,9 @@ func WithWaitGroup(wg *sync.WaitGroup) ContainerOption {
}
}
// WithWidth sets container width. If not set underlying bars will
// occupy whole term width.
// WithWidth sets container width. If not set it defaults to terminal
// width. A bar added to the container will inherit its width, unless
// overridden by `func BarWidth(int) BarOption`.
func WithWidth(width int) ContainerOption {
return func(s *pState) {
s.reqWidth = width
@@ -38,9 +42,9 @@ func WithRefreshRate(d time.Duration) ContainerOption {
// WithManualRefresh disables internal auto refresh time.Ticker.
// Refresh will occur upon receive value from provided ch.
func WithManualRefresh(ch <-chan time.Time) ContainerOption {
func WithManualRefresh(ch <-chan interface{}) ContainerOption {
return func(s *pState) {
s.refreshSrc = ch
s.externalRefresh = ch
}
}
@@ -68,8 +72,8 @@ func WithShutdownNotifier(ch chan struct{}) ContainerOption {
func WithOutput(w io.Writer) ContainerOption {
return func(s *pState) {
if w == nil {
s.refreshSrc = make(chan time.Time)
s.output = ioutil.Discard
s.outputDiscarded = true
return
}
s.output = w
@@ -93,9 +97,15 @@ func PopCompletedMode() ContainerOption {
}
}
// ContainerOptOn returns option when condition evaluates to true.
func ContainerOptOn(option ContainerOption, condition func() bool) ContainerOption {
if condition() {
// ContainerOptional will invoke provided option only when pick is true.
func ContainerOptional(option ContainerOption, pick bool) ContainerOption {
return ContainerOptOn(option, internal.Predicate(pick))
}
// ContainerOptOn will invoke provided option only when higher order
// predicate evaluates to true.
func ContainerOptOn(option ContainerOption, predicate func() bool) ContainerOption {
if predicate() {
return option
}
return nil

2
vendor/github.com/vbauerster/mpb/v6/cwriter/doc.go generated vendored Normal file
View File

@@ -0,0 +1,2 @@
// Package cwriter is a console writer abstraction for the underlying OS.
package cwriter

View File

@@ -8,8 +8,8 @@ import (
"strconv"
)
// NotATTY not a TeleTYpewriter error.
var NotATTY = errors.New("not a terminal")
// ErrNotTTY not a TeleTYpewriter error.
var ErrNotTTY = errors.New("not a terminal")
// http://ascii-table.com/ansi-escape-sequences.php
const (
@@ -39,7 +39,7 @@ func New(out io.Writer) *Writer {
// Flush flushes the underlying buffer.
func (w *Writer) Flush(lineCount int) (err error) {
// some terminals interpret clear 0 lines as clear 1
// some terminals interpret 'cursor up 0' as 'cursor up 1'
if w.lineCount > 0 {
err = w.clearLines()
if err != nil {
@@ -70,7 +70,7 @@ func (w *Writer) ReadFrom(r io.Reader) (n int64, err error) {
// GetWidth returns width of underlying terminal.
func (w *Writer) GetWidth() (int, error) {
if !w.isTerminal {
return -1, NotATTY
return -1, ErrNotTTY
}
tw, _, err := GetSize(w.fd)
return tw, err

View File

@@ -1,6 +1,5 @@
// Package decor provides common decorators for "github.com/vbauerster/mpb/v6" module.
/*
Package decor provides common decorators for "github.com/vbauerster/mpb/v5" module.
Some decorators returned by this package might have a closure state. It is ok to use
decorators concurrently, unless you share the same decorator among multiple
*mpb.Bar instances. To avoid data races, create new decorator per *mpb.Bar instance.

View File

@@ -5,7 +5,7 @@ import (
"io"
"strconv"
"github.com/vbauerster/mpb/v5/internal"
"github.com/vbauerster/mpb/v6/internal"
)
type percentageType float64

11
vendor/github.com/vbauerster/mpb/v6/go.mod generated vendored Normal file
View File

@@ -0,0 +1,11 @@
module github.com/vbauerster/mpb/v6
require (
github.com/VividCortex/ewma v1.1.1
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/mattn/go-runewidth v0.0.10
github.com/rivo/uniseg v0.2.0
golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78
)
go 1.14

11
vendor/github.com/vbauerster/mpb/v6/go.sum generated vendored Normal file
View File

@@ -0,0 +1,11 @@
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
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=
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 h1:nVuTkr9L6Bq62qpUqKo/RnZCFfzDBL0bYo6w9OJUqZY=
golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@@ -13,6 +13,7 @@ func Percentage(total, current int64, width int) float64 {
return float64(int64(width)*current) / float64(total)
}
// PercentageRound same as Percentage but with math.Round.
func PercentageRound(total, current int64, width int) float64 {
return math.Round(Percentage(total, current, width))
}

View File

@@ -0,0 +1,6 @@
package internal
// Predicate helper for internal use.
func Predicate(pick bool) func() bool {
return func() bool { return pick }
}

10
vendor/github.com/vbauerster/mpb/v6/internal/width.go generated vendored Normal file
View File

@@ -0,0 +1,10 @@
package internal
// CheckRequestedWidth checks that requested width doesn't overflow
// available width
func CheckRequestedWidth(requested, available int) int {
if requested <= 0 || requested >= available {
return available
}
return requested
}

View File

@@ -13,8 +13,8 @@ import (
"sync"
"time"
"github.com/vbauerster/mpb/v5/cwriter"
"github.com/vbauerster/mpb/v5/decor"
"github.com/vbauerster/mpb/v6/cwriter"
"github.com/vbauerster/mpb/v6/decor"
)
const (
@@ -22,7 +22,8 @@ const (
prr = 120 * time.Millisecond
)
// Progress represents the container that renders Progress bars
// Progress represents a container that renders one or more progress
// bars.
type Progress struct {
ctx context.Context
uwg *sync.WaitGroup
@@ -35,6 +36,8 @@ type Progress struct {
dlogger *log.Logger
}
// pState holds bars in its priorityQueue. It gets passed to
// *Progress.serve(...) monitor goroutine.
type pState struct {
bHeap priorityQueue
heapUpdated bool
@@ -46,9 +49,10 @@ type pState struct {
idCount int
reqWidth int
popCompleted bool
outputDiscarded bool
rr time.Duration
uwg *sync.WaitGroup
refreshSrc <-chan time.Time
externalRefresh <-chan interface{}
renderDelay <-chan struct{}
shutdownNotifier chan struct{}
parkedBars map[*Bar]*Bar
@@ -95,18 +99,21 @@ func NewWithContext(ctx context.Context, options ...ContainerOption) *Progress {
return p
}
// AddBar creates a new progress bar and adds it to the rendering queue.
// AddBar creates a bar with default bar filler. Different filler can
// be choosen and applied via `*Progress.Add(...) *Bar` method.
func (p *Progress) AddBar(total int64, options ...BarOption) *Bar {
return p.Add(total, NewBarFiller(DefaultBarStyle, false), options...)
return p.Add(total, NewBarFiller(BarDefaultStyle), options...)
}
// AddSpinner creates a new spinner bar and adds it to the rendering queue.
// AddSpinner creates a bar with default spinner filler. Different
// filler can be choosen and applied via `*Progress.Add(...) *Bar`
// method.
func (p *Progress) AddSpinner(total int64, alignment SpinnerAlignment, options ...BarOption) *Bar {
return p.Add(total, NewSpinnerFiller(DefaultSpinnerStyle, alignment), options...)
return p.Add(total, NewSpinnerFiller(SpinnerDefaultStyle, alignment), options...)
}
// Add creates a bar which renders itself by provided filler.
// Set total to 0, if you plan to update it later.
// If `total <= 0` trigger complete event is disabled until reset with *bar.SetTotal(int64, bool).
// Panics if *Progress instance is done, i.e. called after *Progress.Wait().
func (p *Progress) Add(total int64, filler BarFiller, options ...BarOption) *Bar {
if filler == nil {
@@ -168,7 +175,7 @@ func (p *Progress) UpdateBarPriority(b *Bar, priority int) {
p.setBarPriority(b, priority)
}
// BarCount returns bars count
// BarCount returns bars count.
func (p *Progress) BarCount() int {
result := make(chan int, 1)
select {
@@ -234,15 +241,26 @@ func (s *pState) newTicker(done <-chan struct{}) chan time.Time {
if s.renderDelay != nil {
<-s.renderDelay
}
if s.refreshSrc == nil {
ticker := time.NewTicker(s.rr)
defer ticker.Stop()
s.refreshSrc = ticker.C
var internalRefresh <-chan time.Time
if !s.outputDiscarded {
if s.externalRefresh == nil {
ticker := time.NewTicker(s.rr)
defer ticker.Stop()
internalRefresh = ticker.C
}
} else {
s.externalRefresh = nil
}
for {
select {
case tick := <-s.refreshSrc:
ch <- tick
case t := <-internalRefresh:
ch <- t
case x := <-s.externalRefresh:
if t, ok := x.(time.Time); ok {
ch <- t
} else {
ch <- time.Now()
}
case <-done:
close(s.shutdownNotifier)
return
@@ -349,6 +367,10 @@ func (s *pState) makeBarState(total int64, filler BarFiller, options ...BarOptio
debugOut: s.debugOut,
}
if total > 0 {
bs.triggerComplete = true
}
for _, opt := range options {
if opt != nil {
opt(bs)