diff options
Diffstat (limited to 'vendor/github.com/vbauerster')
56 files changed, 2733 insertions, 2455 deletions
diff --git a/vendor/github.com/vbauerster/mpb/.travis.yml b/vendor/github.com/vbauerster/mpb/.travis.yml deleted file mode 100644 index c982d1f90..000000000 --- a/vendor/github.com/vbauerster/mpb/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: go -sudo: false -go: - - 1.10.x - - tip - -before_install: - - go get -t -v ./... - -script: - - go test -race -coverprofile=coverage.txt -covermode=atomic - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/vbauerster/mpb/LICENSE b/vendor/github.com/vbauerster/mpb/LICENSE deleted file mode 100644 index 5e68ed21e..000000000 --- a/vendor/github.com/vbauerster/mpb/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (C) 2016-2018 Vladimir Bauer -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/vbauerster/mpb/bar.go b/vendor/github.com/vbauerster/mpb/bar.go deleted file mode 100644 index a304a87cb..000000000 --- a/vendor/github.com/vbauerster/mpb/bar.go +++ /dev/null @@ -1,399 +0,0 @@ -package mpb - -import ( - "bytes" - "context" - "fmt" - "io" - "io/ioutil" - "strings" - "sync" - "time" - "unicode/utf8" - - "github.com/vbauerster/mpb/decor" -) - -// Bar represents a progress Bar -type Bar struct { - priority int - index int - - runningBar *Bar - cacheState *bState - operateState chan func(*bState) - int64Ch chan int64 - boolCh chan bool - frameReaderCh chan *frameReader - syncTableCh chan [][]chan int - - // done is closed by Bar's goroutine, after cacheState is written - done chan struct{} - // shutdown is closed from master Progress goroutine only - shutdown chan struct{} -} - -// Filler interface. -// Bar renders by calling Filler's Fill method. You can literally have -// any bar kind, by implementing this interface and passing it to the -// Add method. -type Filler interface { - Fill(w io.Writer, width int, s *decor.Statistics) -} - -// FillerFunc is function type adapter to convert function into Filler. -type FillerFunc func(w io.Writer, width int, stat *decor.Statistics) - -func (f FillerFunc) Fill(w io.Writer, width int, stat *decor.Statistics) { - f(w, width, stat) -} - -type ( - bState struct { - filler Filler - id int - width int - alignment int - total int64 - current int64 - trimSpace bool - toComplete bool - removeOnComplete bool - barClearOnComplete bool - completeFlushed bool - aDecorators []decor.Decorator - pDecorators []decor.Decorator - amountReceivers []decor.AmountReceiver - shutdownListeners []decor.ShutdownListener - refill *refill - bufP, bufB, bufA *bytes.Buffer - bufNL *bytes.Buffer - panicMsg string - newLineExtendFn func(io.Writer, *decor.Statistics) - - // following options are assigned to the *Bar - priority int - runningBar *Bar - } - refill struct { - r rune - limit int64 - } - frameReader struct { - io.Reader - extendedLines int - toShutdown bool - removeOnComplete bool - } -) - -func newBar( - ctx context.Context, - wg *sync.WaitGroup, - filler Filler, - id, width int, - total int64, - options ...BarOption, -) *Bar { - - s := &bState{ - filler: filler, - id: id, - priority: id, - width: width, - total: total, - } - - for _, opt := range options { - if opt != nil { - opt(s) - } - } - - s.bufP = bytes.NewBuffer(make([]byte, 0, s.width)) - s.bufB = bytes.NewBuffer(make([]byte, 0, s.width)) - s.bufA = bytes.NewBuffer(make([]byte, 0, s.width)) - if s.newLineExtendFn != nil { - s.bufNL = bytes.NewBuffer(make([]byte, 0, s.width)) - } - - b := &Bar{ - priority: s.priority, - runningBar: s.runningBar, - operateState: make(chan func(*bState)), - int64Ch: make(chan int64), - boolCh: make(chan bool), - frameReaderCh: make(chan *frameReader, 1), - syncTableCh: make(chan [][]chan int), - done: make(chan struct{}), - shutdown: make(chan struct{}), - } - - if b.runningBar != nil { - b.priority = b.runningBar.priority - } - - go b.serve(ctx, wg, s) - return b -} - -// RemoveAllPrependers removes all prepend functions. -func (b *Bar) RemoveAllPrependers() { - select { - case b.operateState <- func(s *bState) { s.pDecorators = nil }: - case <-b.done: - } -} - -// RemoveAllAppenders removes all append functions. -func (b *Bar) RemoveAllAppenders() { - select { - case b.operateState <- func(s *bState) { s.aDecorators = nil }: - case <-b.done: - } -} - -// ProxyReader wraps r with metrics required for progress tracking. -func (b *Bar) ProxyReader(r io.Reader) io.ReadCloser { - if r == nil { - panic("expect io.Reader, got nil") - } - rc, ok := r.(io.ReadCloser) - if !ok { - rc = ioutil.NopCloser(r) - } - return &proxyReader{rc, b, time.Now()} -} - -// ID returs id of the bar. -func (b *Bar) ID() int { - select { - case b.operateState <- func(s *bState) { b.int64Ch <- int64(s.id) }: - return int(<-b.int64Ch) - case <-b.done: - return b.cacheState.id - } -} - -// Current returns bar's current number, in other words sum of all increments. -func (b *Bar) Current() int64 { - select { - case b.operateState <- func(s *bState) { b.int64Ch <- s.current }: - return <-b.int64Ch - case <-b.done: - return b.cacheState.current - } -} - -// SetTotal sets total dynamically. -// Set complete to true, to trigger bar complete event now. -func (b *Bar) SetTotal(total int64, complete bool) { - select { - case b.operateState <- func(s *bState) { - s.total = total - if complete && !s.toComplete { - s.current = s.total - s.toComplete = true - } - }: - case <-b.done: - } -} - -// SetRefill sets refill, if supported by underlying Filler. -func (b *Bar) SetRefill(amount int64) { - b.operateState <- func(s *bState) { - if f, ok := s.filler.(interface{ SetRefill(int64) }); ok { - f.SetRefill(amount) - } - } -} - -// Increment is a shorthand for b.IncrBy(1). -func (b *Bar) Increment() { - b.IncrBy(1) -} - -// IncrBy increments progress bar by amount of n. -// wdd is optional work duration i.e. time.Since(start), which expected -// to be provided, if any ewma based decorator is used. -func (b *Bar) IncrBy(n int, wdd ...time.Duration) { - select { - case b.operateState <- func(s *bState) { - s.current += int64(n) - if s.total > 0 && s.current >= s.total { - s.current = s.total - s.toComplete = true - } - for _, ar := range s.amountReceivers { - ar.NextAmount(n, wdd...) - } - }: - case <-b.done: - } -} - -// Completed reports whether the bar is in completed state. -func (b *Bar) Completed() bool { - // omit select here, because primary usage of the method is for loop - // condition, like for !bar.Completed() {...} so when toComplete=true - // it is called once (at which time, the bar is still alive), then - // quits the loop and never suppose to be called afterwards. - return <-b.boolCh -} - -func (b *Bar) wSyncTable() [][]chan int { - select { - case b.operateState <- func(s *bState) { b.syncTableCh <- s.wSyncTable() }: - return <-b.syncTableCh - case <-b.done: - return b.cacheState.wSyncTable() - } -} - -func (b *Bar) serve(ctx context.Context, wg *sync.WaitGroup, s *bState) { - defer wg.Done() - cancel := ctx.Done() - for { - select { - case op := <-b.operateState: - op(s) - case b.boolCh <- s.toComplete: - case <-cancel: - s.toComplete = true - cancel = nil - case <-b.shutdown: - b.cacheState = s - close(b.done) - for _, sl := range s.shutdownListeners { - sl.Shutdown() - } - return - } - } -} - -func (b *Bar) render(debugOut io.Writer, tw int) { - select { - case b.operateState <- func(s *bState) { - defer func() { - // recovering if user defined decorator panics for example - if p := recover(); p != nil { - s.panicMsg = fmt.Sprintf("panic: %v", p) - fmt.Fprintf(debugOut, "%s %s bar id %02d %v\n", "[mpb]", time.Now(), s.id, s.panicMsg) - b.frameReaderCh <- &frameReader{ - Reader: strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%ds\n", tw), s.panicMsg)), - toShutdown: true, - } - } - }() - r := s.draw(tw) - var extendedLines int - if s.newLineExtendFn != nil { - s.bufNL.Reset() - s.newLineExtendFn(s.bufNL, newStatistics(s)) - extendedLines = countLines(s.bufNL.Bytes()) - r = io.MultiReader(r, s.bufNL) - } - b.frameReaderCh <- &frameReader{ - Reader: r, - extendedLines: extendedLines, - toShutdown: s.toComplete && !s.completeFlushed, - removeOnComplete: s.removeOnComplete, - } - s.completeFlushed = s.toComplete - }: - case <-b.done: - s := b.cacheState - r := s.draw(tw) - var extendedLines int - if s.newLineExtendFn != nil { - s.bufNL.Reset() - s.newLineExtendFn(s.bufNL, newStatistics(s)) - extendedLines = countLines(s.bufNL.Bytes()) - r = io.MultiReader(r, s.bufNL) - } - b.frameReaderCh <- &frameReader{ - Reader: r, - extendedLines: extendedLines, - } - } -} - -func (s *bState) draw(termWidth int) io.Reader { - if s.panicMsg != "" { - return strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%ds\n", termWidth), s.panicMsg)) - } - - stat := newStatistics(s) - - for _, d := range s.pDecorators { - s.bufP.WriteString(d.Decor(stat)) - } - - for _, d := range s.aDecorators { - s.bufA.WriteString(d.Decor(stat)) - } - - if s.barClearOnComplete && s.completeFlushed { - s.bufA.WriteByte('\n') - return io.MultiReader(s.bufP, s.bufA) - } - - prependCount := utf8.RuneCount(s.bufP.Bytes()) - appendCount := utf8.RuneCount(s.bufA.Bytes()) - - if !s.trimSpace { - // reserve space for edge spaces - termWidth -= 2 - s.bufB.WriteByte(' ') - } - - if prependCount+s.width+appendCount > termWidth { - s.filler.Fill(s.bufB, termWidth-prependCount-appendCount, stat) - } else { - s.filler.Fill(s.bufB, s.width, stat) - } - - if !s.trimSpace { - s.bufB.WriteByte(' ') - } - - s.bufA.WriteByte('\n') - return io.MultiReader(s.bufP, s.bufB, s.bufA) -} - -func (s *bState) wSyncTable() [][]chan int { - columns := make([]chan int, 0, len(s.pDecorators)+len(s.aDecorators)) - var pCount int - for _, d := range s.pDecorators { - if ok, ch := d.Syncable(); ok { - columns = append(columns, ch) - pCount++ - } - } - var aCount int - for _, d := range s.aDecorators { - if ok, ch := d.Syncable(); ok { - columns = append(columns, ch) - aCount++ - } - } - table := make([][]chan int, 2) - table[0] = columns[0:pCount] - table[1] = columns[pCount : pCount+aCount : pCount+aCount] - return table -} - -func newStatistics(s *bState) *decor.Statistics { - return &decor.Statistics{ - ID: s.id, - Completed: s.completeFlushed, - Total: s.total, - Current: s.current, - } -} - -func countLines(b []byte) int { - return bytes.Count(b, []byte("\n")) -} diff --git a/vendor/github.com/vbauerster/mpb/bar_filler.go b/vendor/github.com/vbauerster/mpb/bar_filler.go deleted file mode 100644 index 4e9285ca5..000000000 --- a/vendor/github.com/vbauerster/mpb/bar_filler.go +++ /dev/null @@ -1,111 +0,0 @@ -package mpb - -import ( - "io" - "unicode/utf8" - - "github.com/vbauerster/mpb/decor" - "github.com/vbauerster/mpb/internal" -) - -const ( - rLeft = iota - rFill - rTip - rEmpty - rRight - rRevTip - rRefill -) - -var defaultBarStyle = "[=>-]<+" - -type barFiller struct { - format [][]byte - refillAmount int64 - reverse bool -} - -func newDefaultBarFiller() Filler { - bf := &barFiller{ - format: make([][]byte, utf8.RuneCountInString(defaultBarStyle)), - } - bf.setStyle(defaultBarStyle) - return bf -} - -func (s *barFiller) setStyle(style string) { - if !utf8.ValidString(style) { - return - } - src := make([][]byte, 0, utf8.RuneCountInString(style)) - for _, r := range style { - src = append(src, []byte(string(r))) - } - copy(s.format, src) -} - -func (s *barFiller) setReverse() { - s.reverse = true -} - -func (s *barFiller) SetRefill(amount int64) { - s.refillAmount = amount -} - -func (s *barFiller) Fill(w io.Writer, width int, stat *decor.Statistics) { - - // don't count rLeft and rRight [brackets] - width -= 2 - if width < 2 { - return - } - - w.Write(s.format[rLeft]) - if width == 2 { - w.Write(s.format[rRight]) - return - } - - bb := make([][]byte, width) - - cwidth := int(internal.Percentage(stat.Total, stat.Current, int64(width))) - - for i := 0; i < cwidth; i++ { - bb[i] = s.format[rFill] - } - - if s.refillAmount > 0 { - var rwidth int - if s.refillAmount > stat.Current { - rwidth = cwidth - } else { - rwidth = int(internal.Percentage(stat.Total, int64(s.refillAmount), int64(width))) - } - for i := 0; i < rwidth; i++ { - bb[i] = s.format[rRefill] - } - } - - if cwidth > 0 && cwidth < width { - bb[cwidth-1] = s.format[rTip] - } - - for i := cwidth; i < width; i++ { - bb[i] = s.format[rEmpty] - } - - if s.reverse { - if cwidth > 0 && cwidth < width { - bb[cwidth-1] = s.format[rRevTip] - } - for i := len(bb) - 1; i >= 0; i-- { - w.Write(bb[i]) - } - } else { - for i := 0; i < len(bb); i++ { - w.Write(bb[i]) - } - } - w.Write(s.format[rRight]) -} diff --git a/vendor/github.com/vbauerster/mpb/bar_option.go b/vendor/github.com/vbauerster/mpb/bar_option.go deleted file mode 100644 index e9a4bd2a7..000000000 --- a/vendor/github.com/vbauerster/mpb/bar_option.go +++ /dev/null @@ -1,193 +0,0 @@ -package mpb - -import ( - "io" - - "github.com/vbauerster/mpb/decor" -) - -// BarOption is a function option which changes the default behavior of a bar. -type BarOption func(*bState) - -// AppendDecorators let you inject decorators to the bar's right side. -func AppendDecorators(appenders ...decor.Decorator) BarOption { - return func(s *bState) { - for _, decorator := range appenders { - if ar, ok := decorator.(decor.AmountReceiver); ok { - s.amountReceivers = append(s.amountReceivers, ar) - } - if sl, ok := decorator.(decor.ShutdownListener); ok { - s.shutdownListeners = append(s.shutdownListeners, sl) - } - s.aDecorators = append(s.aDecorators, decorator) - } - } -} - -// PrependDecorators let you inject decorators to the bar's left side. -func PrependDecorators(prependers ...decor.Decorator) BarOption { - return func(s *bState) { - for _, decorator := range prependers { - if ar, ok := decorator.(decor.AmountReceiver); ok { - s.amountReceivers = append(s.amountReceivers, ar) - } - if sl, ok := decorator.(decor.ShutdownListener); ok { - s.shutdownListeners = append(s.shutdownListeners, sl) - } - s.pDecorators = append(s.pDecorators, decorator) - } - } -} - -// BarID sets bar id. -func BarID(id int) BarOption { - return func(s *bState) { - s.id = id - } -} - -// BarWidth sets bar width independent of the container. -func BarWidth(width int) BarOption { - return func(s *bState) { - s.width = width - } -} - -// BarRemoveOnComplete is a flag, if set whole bar line will be removed -// on complete event. If both BarRemoveOnComplete and BarClearOnComplete -// are set, first bar section gets cleared and then whole bar line -// gets removed completely. -func BarRemoveOnComplete() BarOption { - return func(s *bState) { - s.removeOnComplete = true - } -} - -// BarReplaceOnComplete is indicator for delayed bar start, after the -// `runningBar` is complete. To achieve bar replacement effect, -// `runningBar` should has its `BarRemoveOnComplete` option set. -func BarReplaceOnComplete(runningBar *Bar) BarOption { - return BarParkTo(runningBar) -} - -// BarParkTo same as BarReplaceOnComplete -func BarParkTo(runningBar *Bar) BarOption { - return func(s *bState) { - s.runningBar = runningBar - } -} - -// BarClearOnComplete is a flag, if set will clear bar section on -// complete event. If you need to remove a whole bar line, refer to -// BarRemoveOnComplete. -func BarClearOnComplete() BarOption { - return func(s *bState) { - s.barClearOnComplete = true - } -} - -// BarPriority sets bar's priority. Zero is highest priority, i.e. bar -// will be on top. If `BarReplaceOnComplete` option is supplied, this -// option is ignored. -func BarPriority(priority int) BarOption { - return func(s *bState) { - s.priority = priority - } -} - -// BarNewLineExtend takes user defined efn, which gets called each -// render cycle. Any write to provided writer of efn, will appear on -// new line of respective bar. -func BarNewLineExtend(efn func(io.Writer, *decor.Statistics)) BarOption { - return func(s *bState) { - s.newLineExtendFn = efn - } -} - -// TrimSpace trims bar's edge spaces. -func TrimSpace() BarOption { - return func(s *bState) { - s.trimSpace = true - } -} - -// BarStyle sets custom bar style, default one is "[=>-]<+". -// -// '[' left bracket rune -// -// '=' fill rune -// -// '>' tip rune -// -// '-' empty rune -// -// ']' right bracket rune -// -// '<' reverse tip rune, used when BarReverse option is set -// -// '+' refill rune, used when *Bar.SetRefill(int64) is called -// -// It's ok to provide first five runes only, for example mpb.BarStyle("╢▌▌░╟") -func BarStyle(style string) BarOption { - chk := func(filler Filler) (interface{}, bool) { - if style == "" { - return nil, false - } - t, ok := filler.(*barFiller) - return t, ok - } - cb := func(t interface{}) { - t.(*barFiller).setStyle(style) - } - return MakeFillerTypeSpecificBarOption(chk, cb) -} - -// BarReverse reverse mode, bar will progress from right to left. -func BarReverse() BarOption { - chk := func(filler Filler) (interface{}, bool) { - t, ok := filler.(*barFiller) - return t, ok - } - cb := func(t interface{}) { - t.(*barFiller).setReverse() - } - return MakeFillerTypeSpecificBarOption(chk, cb) -} - -// SpinnerStyle sets custom spinner style. -// Effective when Filler type is spinner. -func SpinnerStyle(frames []string) BarOption { - chk := func(filler Filler) (interface{}, bool) { - if len(frames) == 0 { - return nil, false - } - 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(Filler) (interface{}, bool), - cb func(interface{}), -) BarOption { - return func(s *bState) { - if t, ok := typeChecker(s.filler); ok { - cb(t) - } - } -} - -// OptionOnCondition returns option when condition evaluates to true. -func OptionOnCondition(option BarOption, condition func() bool) BarOption { - if condition() { - return option - } - return nil -} diff --git a/vendor/github.com/vbauerster/mpb/cwriter/writer_posix.go b/vendor/github.com/vbauerster/mpb/cwriter/writer_posix.go deleted file mode 100644 index 05e31c480..000000000 --- a/vendor/github.com/vbauerster/mpb/cwriter/writer_posix.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build !windows - -package cwriter - -import ( - "io" - "strings" -) - -func (w *Writer) clearLines() error { - _, err := io.WriteString(w.out, strings.Repeat(clearCursorAndLine, w.lineCount)) - return err -} diff --git a/vendor/github.com/vbauerster/mpb/cwriter/writer_windows.go b/vendor/github.com/vbauerster/mpb/cwriter/writer_windows.go deleted file mode 100644 index 747a63484..000000000 --- a/vendor/github.com/vbauerster/mpb/cwriter/writer_windows.go +++ /dev/null @@ -1,77 +0,0 @@ -// +build windows - -package cwriter - -import ( - "io" - "strings" - "syscall" - "unsafe" - - isatty "github.com/mattn/go-isatty" -) - -var kernel32 = syscall.NewLazyDLL("kernel32.dll") - -var ( - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") - procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") - procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") -) - -type ( - short int16 - word uint16 - dword uint32 - - coord struct { - x short - y short - } - smallRect struct { - left short - top short - right short - bottom short - } - consoleScreenBufferInfo struct { - size coord - cursorPosition coord - attributes word - window smallRect - maximumWindowSize coord - } -) - -// FdWriter is a writer with a file descriptor. -type FdWriter interface { - io.Writer - Fd() uintptr -} - -func (w *Writer) clearLines() error { - f, ok := w.out.(FdWriter) - if ok && !isatty.IsTerminal(f.Fd()) { - _, err := io.WriteString(w.out, strings.Repeat(clearCursorAndLine, w.lineCount)) - return err - } - fd := f.Fd() - var info consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(fd, uintptr(unsafe.Pointer(&info))) - - for i := 0; i < w.lineCount; i++ { - // move the cursor up - info.cursorPosition.y-- - procSetConsoleCursorPosition.Call(fd, uintptr(*(*int32)(unsafe.Pointer(&info.cursorPosition)))) - // clear the line - cursor := coord{ - x: info.window.left, - y: info.window.top + info.cursorPosition.y, - } - var count, w dword - count = dword(info.size.x) - procFillConsoleOutputCharacter.Call(fd, uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&w))) - } - return nil -} diff --git a/vendor/github.com/vbauerster/mpb/decor/counters.go b/vendor/github.com/vbauerster/mpb/decor/counters.go deleted file mode 100644 index 7d581eefb..000000000 --- a/vendor/github.com/vbauerster/mpb/decor/counters.go +++ /dev/null @@ -1,208 +0,0 @@ -package decor - -import ( - "fmt" - "io" - "strconv" - "strings" -) - -const ( - _ = iota - KiB = 1 << (iota * 10) - MiB - GiB - TiB -) - -const ( - KB = 1000 - MB = KB * 1000 - GB = MB * 1000 - TB = GB * 1000 -) - -const ( - _ = iota - UnitKiB - UnitKB -) - -type CounterKiB int64 - -func (c CounterKiB) Format(st fmt.State, verb rune) { - prec, ok := st.Precision() - - if verb == 'd' || !ok { - prec = 0 - } - if verb == 'f' && !ok { - prec = 6 - } - // retain old beahavior if s verb used - if verb == 's' { - prec = 1 - } - - var res, unit string - switch { - case c >= TiB: - unit = "TiB" - res = strconv.FormatFloat(float64(c)/TiB, 'f', prec, 64) - case c >= GiB: - unit = "GiB" - res = strconv.FormatFloat(float64(c)/GiB, 'f', prec, 64) - case c >= MiB: - unit = "MiB" - res = strconv.FormatFloat(float64(c)/MiB, 'f', prec, 64) - case c >= KiB: - unit = "KiB" - res = strconv.FormatFloat(float64(c)/KiB, 'f', prec, 64) - default: - unit = "b" - res = strconv.FormatInt(int64(c), 10) - } - - if st.Flag(' ') { - res += " " - } - res += unit - - if w, ok := st.Width(); ok { - if len(res) < w { - pad := strings.Repeat(" ", w-len(res)) - if st.Flag(int('-')) { - res += pad - } else { - res = pad + res - } - } - } - - io.WriteString(st, res) -} - -type CounterKB int64 - -func (c CounterKB) Format(st fmt.State, verb rune) { - prec, ok := st.Precision() - - if verb == 'd' || !ok { - prec = 0 - } - if verb == 'f' && !ok { - prec = 6 - } - // retain old beahavior if s verb used - if verb == 's' { - prec = 1 - } - - var res, unit string - switch { - case c >= TB: - unit = "TB" - res = strconv.FormatFloat(float64(c)/TB, 'f', prec, 64) - case c >= GB: - unit = "GB" - res = strconv.FormatFloat(float64(c)/GB, 'f', prec, 64) - case c >= MB: - unit = "MB" - res = strconv.FormatFloat(float64(c)/MB, 'f', prec, 64) - case c >= KB: - unit = "kB" - res = strconv.FormatFloat(float64(c)/KB, 'f', prec, 64) - default: - unit = "b" - res = strconv.FormatInt(int64(c), 10) - } - - if st.Flag(' ') { - res += " " - } - res += unit - - if w, ok := st.Width(); ok { - if len(res) < w { - pad := strings.Repeat(" ", w-len(res)) - if st.Flag(int('-')) { - res += pad - } else { - res = pad + res - } - } - } - - io.WriteString(st, res) -} - -// CountersNoUnit is a wrapper around Counters with no unit param. -func CountersNoUnit(pairFormat string, wcc ...WC) Decorator { - return Counters(0, pairFormat, wcc...) -} - -// CountersKibiByte is a wrapper around Counters with predefined unit -// UnitKiB (bytes/1024). -func CountersKibiByte(pairFormat string, wcc ...WC) Decorator { - return Counters(UnitKiB, pairFormat, wcc...) -} - -// CountersKiloByte is a wrapper around Counters with predefined unit -// UnitKB (bytes/1000). -func CountersKiloByte(pairFormat string, wcc ...WC) Decorator { - return Counters(UnitKB, pairFormat, wcc...) -} - -// Counters decorator with dynamic unit measure adjustment. -// -// `unit` one of [0|UnitKiB|UnitKB] zero for no unit -// -// `pairFormat` printf compatible verbs for current and total, like "%f" or "%d" -// -// `wcc` optional WC config -// -// pairFormat example if UnitKB is chosen: -// -// "%.1f / %.1f" = "1.0MB / 12.0MB" or "% .1f / % .1f" = "1.0 MB / 12.0 MB" -func Counters(unit int, pairFormat string, wcc ...WC) Decorator { - var wc WC - for _, widthConf := range wcc { - wc = widthConf - } - wc.Init() - d := &countersDecorator{ - WC: wc, - unit: unit, - pairFormat: pairFormat, - } - return d -} - -type countersDecorator struct { - WC - unit int - pairFormat string - completeMsg *string -} - -func (d *countersDecorator) Decor(st *Statistics) string { - if st.Completed && d.completeMsg != nil { - return d.FormatMsg(*d.completeMsg) - } - - var str string - switch d.unit { - case UnitKiB: - str = fmt.Sprintf(d.pairFormat, CounterKiB(st.Current), CounterKiB(st.Total)) - case UnitKB: - str = fmt.Sprintf(d.pairFormat, CounterKB(st.Current), CounterKB(st.Total)) - default: - str = fmt.Sprintf(d.pairFormat, st.Current, st.Total) - } - - return d.FormatMsg(str) -} - -func (d *countersDecorator) OnCompleteMessage(msg string) { - d.completeMsg = &msg -} diff --git a/vendor/github.com/vbauerster/mpb/decor/decorator.go b/vendor/github.com/vbauerster/mpb/decor/decorator.go deleted file mode 100644 index 2fe40aea6..000000000 --- a/vendor/github.com/vbauerster/mpb/decor/decorator.go +++ /dev/null @@ -1,152 +0,0 @@ -package decor - -import ( - "fmt" - "time" - "unicode/utf8" -) - -const ( - // DidentRight bit specifies identation direction. - // |foo |b | With DidentRight - // | foo| b| Without DidentRight - DidentRight = 1 << iota - - // DextraSpace bit adds extra space, makes sense with DSyncWidth only. - // When DidentRight bit set, the space will be added to the right, - // otherwise to the left. - DextraSpace - - // DSyncWidth bit enables same column width synchronization. - // Effective with multiple bars only. - DSyncWidth - - // DSyncWidthR is shortcut for DSyncWidth|DidentRight - DSyncWidthR = DSyncWidth | DidentRight - - // DSyncSpace is shortcut for DSyncWidth|DextraSpace - DSyncSpace = DSyncWidth | DextraSpace - - // DSyncSpaceR is shortcut for DSyncWidth|DextraSpace|DidentRight - DSyncSpaceR = DSyncWidth | DextraSpace | DidentRight -) - -// TimeStyle enum. -type TimeStyle int - -// TimeStyle kinds. -const ( - ET_STYLE_GO TimeStyle = iota - ET_STYLE_HHMMSS - ET_STYLE_HHMM - ET_STYLE_MMSS -) - -// Statistics is a struct, which gets passed to a Decorator. -type Statistics struct { - ID int - Completed bool - Total int64 - Current int64 -} - -// Decorator interface. -// A decorator must implement this interface, in order to be used with -// mpb library. -type Decorator interface { - Decor(*Statistics) string - Syncable -} - -// Syncable interface. -// All decorators implement this interface implicitly. Its Syncable -// method exposes width sync channel, if sync is enabled. -type Syncable interface { - Syncable() (bool, chan int) -} - -// OnCompleteMessenger interface. -// Decorators implementing this interface suppose to return provided -// string on complete event. -type OnCompleteMessenger interface { - OnCompleteMessage(string) -} - -// AmountReceiver interface. -// If decorator needs to receive increment amount, so this is the right -// interface to implement. -type AmountReceiver interface { - NextAmount(int, ...time.Duration) -} - -// ShutdownListener interface. -// If decorator needs to be notified once upon bar shutdown event, so -// this is the right interface to implement. -type ShutdownListener interface { - Shutdown() -} - -// Global convenience shortcuts -var ( - WCSyncWidth = WC{C: DSyncWidth} - WCSyncWidthR = WC{C: DSyncWidthR} - WCSyncSpace = WC{C: DSyncSpace} - WCSyncSpaceR = WC{C: DSyncSpaceR} -) - -// WC is a struct with two public fields W and C, both of int type. -// W represents width and C represents bit set of width related config. -// A decorator should embed WC, in order to become Syncable. -type WC struct { - W int - C int - format string - wsync chan int -} - -// FormatMsg formats final message according to WC.W and WC.C. -// Should be called by any Decorator implementation. -func (wc WC) FormatMsg(msg string) string { - if (wc.C & DSyncWidth) != 0 { - wc.wsync <- utf8.RuneCountInString(msg) - max := <-wc.wsync - if max == 0 { - max = wc.W - } - if (wc.C & DextraSpace) != 0 { - max++ - } - return fmt.Sprintf(fmt.Sprintf(wc.format, max), msg) - } - return fmt.Sprintf(fmt.Sprintf(wc.format, wc.W), msg) -} - -// Init initializes width related config. -func (wc *WC) Init() { - wc.format = "%%" - if (wc.C & DidentRight) != 0 { - wc.format += "-" - } - wc.format += "%ds" - if (wc.C & DSyncWidth) != 0 { - wc.wsync = make(chan int) - } -} - -// Syncable is implementation of Syncable interface. -func (wc *WC) Syncable() (bool, chan int) { - return (wc.C & DSyncWidth) != 0, wc.wsync -} - -// OnComplete returns decorator, which wraps provided decorator, with -// sole purpose to display provided message on complete event. -// -// `decorator` Decorator to wrap -// -// `message` message to display on complete event -func OnComplete(decorator Decorator, message string) Decorator { - if d, ok := decorator.(OnCompleteMessenger); ok { - d.OnCompleteMessage(message) - } - return decorator -} diff --git a/vendor/github.com/vbauerster/mpb/decor/elapsed.go b/vendor/github.com/vbauerster/mpb/decor/elapsed.go deleted file mode 100644 index b2e75852c..000000000 --- a/vendor/github.com/vbauerster/mpb/decor/elapsed.go +++ /dev/null @@ -1,68 +0,0 @@ -package decor - -import ( - "fmt" - "time" -) - -// Elapsed returns elapsed time decorator. -// -// `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 { - var wc WC - for _, widthConf := range wcc { - wc = widthConf - } - wc.Init() - d := &elapsedDecorator{ - WC: wc, - style: style, - startTime: time.Now(), - } - return d -} - -type elapsedDecorator struct { - WC - style TimeStyle - startTime time.Time - msg string - completeMsg *string -} - -func (d *elapsedDecorator) Decor(st *Statistics) string { - if st.Completed { - if d.completeMsg != nil { - return d.FormatMsg(*d.completeMsg) - } - return d.FormatMsg(d.msg) - } - - timeElapsed := time.Since(d.startTime) - hours := int64((timeElapsed / time.Hour) % 60) - minutes := int64((timeElapsed / time.Minute) % 60) - seconds := int64((timeElapsed / time.Second) % 60) - - switch d.style { - case ET_STYLE_GO: - d.msg = fmt.Sprint(time.Duration(timeElapsed.Seconds()) * time.Second) - case ET_STYLE_HHMMSS: - d.msg = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) - case ET_STYLE_HHMM: - d.msg = fmt.Sprintf("%02d:%02d", hours, minutes) - case ET_STYLE_MMSS: - if hours > 0 { - d.msg = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) - } else { - d.msg = fmt.Sprintf("%02d:%02d", minutes, seconds) - } - } - - return d.FormatMsg(d.msg) -} - -func (d *elapsedDecorator) OnCompleteMessage(msg string) { - d.completeMsg = &msg -} diff --git a/vendor/github.com/vbauerster/mpb/decor/eta.go b/vendor/github.com/vbauerster/mpb/decor/eta.go deleted file mode 100644 index e8dc979b4..000000000 --- a/vendor/github.com/vbauerster/mpb/decor/eta.go +++ /dev/null @@ -1,206 +0,0 @@ -package decor - -import ( - "fmt" - "math" - "time" - - "github.com/VividCortex/ewma" -) - -type TimeNormalizer func(time.Duration) time.Duration - -// EwmaETA exponential-weighted-moving-average based ETA decorator. -// -// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS] -// -// `age` is the previous N samples to average over. -// -// `wcc` optional WC config -func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator { - return MovingAverageETA(style, ewma.NewMovingAverage(age), NopNormalizer(), wcc...) -} - -// MovingAverageETA decorator relies on MovingAverage implementation to calculate its average. -// -// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS] -// -// `average` available implementations of MovingAverage [ewma.MovingAverage|NewMedian|NewMedianEwma] -// -// `normalizer` available implementations are [NopNormalizer|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 - } - wc.Init() - d := &movingAverageETA{ - WC: wc, - style: style, - average: average, - normalizer: normalizer, - } - return d -} - -type movingAverageETA struct { - WC - style TimeStyle - average ewma.MovingAverage - completeMsg *string - normalizer TimeNormalizer -} - -func (d *movingAverageETA) Decor(st *Statistics) string { - if st.Completed && d.completeMsg != nil { - return d.FormatMsg(*d.completeMsg) - } - - v := math.Round(d.average.Value()) - remaining := d.normalizer(time.Duration((st.Total - st.Current) * int64(v))) - hours := int64((remaining / time.Hour) % 60) - minutes := int64((remaining / time.Minute) % 60) - seconds := int64((remaining / time.Second) % 60) - - var str string - switch d.style { - case ET_STYLE_GO: - str = fmt.Sprint(time.Duration(remaining.Seconds()) * time.Second) - case ET_STYLE_HHMMSS: - str = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) - case ET_STYLE_HHMM: - str = fmt.Sprintf("%02d:%02d", hours, minutes) - case ET_STYLE_MMSS: - if hours > 0 { - str = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) - } else { - str = fmt.Sprintf("%02d:%02d", minutes, seconds) - } - } - - return d.FormatMsg(str) -} - -func (d *movingAverageETA) NextAmount(n int, wdd ...time.Duration) { - var workDuration time.Duration - for _, wd := range wdd { - workDuration = wd - } - lastItemEstimate := float64(workDuration) / float64(n) - if math.IsInf(lastItemEstimate, 0) || math.IsNaN(lastItemEstimate) { - return - } - d.average.Add(lastItemEstimate) -} - -func (d *movingAverageETA) OnCompleteMessage(msg string) { - d.completeMsg = &msg -} - -// AverageETA decorator. -// -// `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 { - var wc WC - for _, widthConf := range wcc { - wc = widthConf - } - wc.Init() - d := &averageETA{ - WC: wc, - style: style, - startTime: time.Now(), - } - return d -} - -type averageETA struct { - WC - style TimeStyle - startTime time.Time - completeMsg *string -} - -func (d *averageETA) Decor(st *Statistics) string { - if st.Completed && d.completeMsg != nil { - return d.FormatMsg(*d.completeMsg) - } - - var str string - timeElapsed := time.Since(d.startTime) - v := math.Round(float64(timeElapsed) / float64(st.Current)) - if math.IsInf(v, 0) || math.IsNaN(v) { - v = 0 - } - remaining := time.Duration((st.Total - st.Current) * int64(v)) - hours := int64((remaining / time.Hour) % 60) - minutes := int64((remaining / time.Minute) % 60) - seconds := int64((remaining / time.Second) % 60) - - switch d.style { - case ET_STYLE_GO: - str = fmt.Sprint(time.Duration(remaining.Seconds()) * time.Second) - case ET_STYLE_HHMMSS: - str = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) - case ET_STYLE_HHMM: - str = fmt.Sprintf("%02d:%02d", hours, minutes) - case ET_STYLE_MMSS: - if hours > 0 { - str = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) - } else { - str = fmt.Sprintf("%02d:%02d", minutes, seconds) - } - } - - return d.FormatMsg(str) -} - -func (d *averageETA) OnCompleteMessage(msg string) { - d.completeMsg = &msg -} - -func MaxTolerateTimeNormalizer(maxTolerate time.Duration) TimeNormalizer { - var normalized time.Duration - var lastCall time.Time - return func(remaining time.Duration) time.Duration { - if diff := normalized - remaining; diff <= 0 || diff > maxTolerate || remaining < maxTolerate/2 { - normalized = remaining - lastCall = time.Now() - return remaining - } - normalized -= time.Since(lastCall) - lastCall = time.Now() - return normalized - } -} - -func FixedIntervalTimeNormalizer(updInterval int) TimeNormalizer { - var normalized time.Duration - var lastCall time.Time - var count int - return func(remaining time.Duration) time.Duration { - if count == 0 || remaining <= time.Duration(15*time.Second) { - count = updInterval - normalized = remaining - lastCall = time.Now() - return remaining - } - count-- - normalized -= time.Since(lastCall) - lastCall = time.Now() - if normalized > 0 { - return normalized - } - return remaining - } -} - -func NopNormalizer() TimeNormalizer { - return func(remaining time.Duration) time.Duration { - return remaining - } -} diff --git a/vendor/github.com/vbauerster/mpb/decor/name.go b/vendor/github.com/vbauerster/mpb/decor/name.go deleted file mode 100644 index a5a5d1469..000000000 --- a/vendor/github.com/vbauerster/mpb/decor/name.go +++ /dev/null @@ -1,45 +0,0 @@ -package decor - -// StaticName returns name decorator. -// -// `name` string to display -// -// `wcc` optional WC config -func StaticName(name string, wcc ...WC) Decorator { - return Name(name, wcc...) -} - -// Name returns name decorator. -// -// `name` string to display -// -// `wcc` optional WC config -func Name(name string, wcc ...WC) Decorator { - var wc WC - for _, widthConf := range wcc { - wc = widthConf - } - wc.Init() - d := &nameDecorator{ - WC: wc, - msg: name, - } - return d -} - -type nameDecorator struct { - WC - msg string - complete *string -} - -func (d *nameDecorator) Decor(st *Statistics) string { - if st.Completed && d.complete != nil { - return d.FormatMsg(*d.complete) - } - return d.FormatMsg(d.msg) -} - -func (d *nameDecorator) OnCompleteMessage(msg string) { - d.complete = &msg -} diff --git a/vendor/github.com/vbauerster/mpb/decor/percentage.go b/vendor/github.com/vbauerster/mpb/decor/percentage.go deleted file mode 100644 index 078fbcf89..000000000 --- a/vendor/github.com/vbauerster/mpb/decor/percentage.go +++ /dev/null @@ -1,39 +0,0 @@ -package decor - -import ( - "fmt" - - "github.com/vbauerster/mpb/internal" -) - -// Percentage returns percentage decorator. -// -// `wcc` optional WC config -func Percentage(wcc ...WC) Decorator { - var wc WC - for _, widthConf := range wcc { - wc = widthConf - } - wc.Init() - d := &percentageDecorator{ - WC: wc, - } - return d -} - -type percentageDecorator struct { - WC - completeMsg *string -} - -func (d *percentageDecorator) Decor(st *Statistics) string { - if st.Completed && d.completeMsg != nil { - return d.FormatMsg(*d.completeMsg) - } - str := fmt.Sprintf("%d %%", internal.Percentage(st.Total, st.Current, 100)) - return d.FormatMsg(str) -} - -func (d *percentageDecorator) OnCompleteMessage(msg string) { - d.completeMsg = &msg -} diff --git a/vendor/github.com/vbauerster/mpb/decor/speed.go b/vendor/github.com/vbauerster/mpb/decor/speed.go deleted file mode 100644 index 74658ce41..000000000 --- a/vendor/github.com/vbauerster/mpb/decor/speed.go +++ /dev/null @@ -1,271 +0,0 @@ -package decor - -import ( - "fmt" - "io" - "math" - "strconv" - "strings" - "time" - - "github.com/VividCortex/ewma" -) - -type SpeedKiB float64 - -func (s SpeedKiB) Format(st fmt.State, verb rune) { - prec, ok := st.Precision() - - if verb == 'd' || !ok { - prec = 0 - } - if verb == 'f' && !ok { - prec = 6 - } - // retain old beahavior if s verb used - if verb == 's' { - prec = 1 - } - - var res, unit string - switch { - case s >= TiB: - unit = "TiB/s" - res = strconv.FormatFloat(float64(s)/TiB, 'f', prec, 64) - case s >= GiB: - unit = "GiB/s" - res = strconv.FormatFloat(float64(s)/GiB, 'f', prec, 64) - case s >= MiB: - unit = "MiB/s" - res = strconv.FormatFloat(float64(s)/MiB, 'f', prec, 64) - case s >= KiB: - unit = "KiB/s" - res = strconv.FormatFloat(float64(s)/KiB, 'f', prec, 64) - default: - unit = "b/s" - res = strconv.FormatInt(int64(s), 10) - } - - if st.Flag(' ') { - res += " " - } - res += unit - - if w, ok := st.Width(); ok { - if len(res) < w { - pad := strings.Repeat(" ", w-len(res)) - if st.Flag(int('-')) { - res += pad - } else { - res = pad + res - } - } - } - - io.WriteString(st, res) -} - -type SpeedKB float64 - -func (s SpeedKB) Format(st fmt.State, verb rune) { - prec, ok := st.Precision() - - if verb == 'd' || !ok { - prec = 0 - } - if verb == 'f' && !ok { - prec = 6 - } - // retain old beahavior if s verb used - if verb == 's' { - prec = 1 - } - - var res, unit string - switch { - case s >= TB: - unit = "TB/s" - res = strconv.FormatFloat(float64(s)/TB, 'f', prec, 64) - case s >= GB: - unit = "GB/s" - res = strconv.FormatFloat(float64(s)/GB, 'f', prec, 64) - case s >= MB: - unit = "MB/s" - res = strconv.FormatFloat(float64(s)/MB, 'f', prec, 64) - case s >= KB: - unit = "kB/s" - res = strconv.FormatFloat(float64(s)/KB, 'f', prec, 64) - default: - unit = "b/s" - res = strconv.FormatInt(int64(s), 10) - } - - if st.Flag(' ') { - res += " " - } - res += unit - - if w, ok := st.Width(); ok { - if len(res) < w { - pad := strings.Repeat(" ", w-len(res)) - if st.Flag(int('-')) { - res += pad - } else { - res = pad + res - } - } - } - - io.WriteString(st, res) -} - -// EwmaSpeed exponential-weighted-moving-average based speed decorator, -// with dynamic unit measure adjustment. -// -// `unit` one of [0|UnitKiB|UnitKB] zero for no unit -// -// `unitFormat` printf compatible verb for value, like "%f" or "%d" -// -// `average` MovingAverage implementation -// -// `wcc` optional WC config -// -// unitFormat example if UnitKiB is chosen: -// -// "%.1f" = "1.0MiB/s" or "% .1f" = "1.0 MiB/s" -func EwmaSpeed(unit int, unitFormat string, age float64, wcc ...WC) Decorator { - return MovingAverageSpeed(unit, unitFormat, ewma.NewMovingAverage(age), wcc...) -} - -// MovingAverageSpeed decorator relies on MovingAverage implementation -// to calculate its average. -// -// `unit` one of [0|UnitKiB|UnitKB] zero for no unit -// -// `unitFormat` printf compatible verb for value, like "%f" or "%d" -// -// `average` MovingAverage implementation -// -// `wcc` optional WC config -func MovingAverageSpeed(unit int, unitFormat string, average MovingAverage, wcc ...WC) Decorator { - var wc WC - for _, widthConf := range wcc { - wc = widthConf - } - wc.Init() - d := &movingAverageSpeed{ - WC: wc, - unit: unit, - unitFormat: unitFormat, - average: average, - } - return d -} - -type movingAverageSpeed struct { - WC - unit int - unitFormat string - average ewma.MovingAverage - msg string - completeMsg *string -} - -func (d *movingAverageSpeed) Decor(st *Statistics) string { - if st.Completed { - if d.completeMsg != nil { - return d.FormatMsg(*d.completeMsg) - } - return d.FormatMsg(d.msg) - } - - speed := d.average.Value() - switch d.unit { - case UnitKiB: - d.msg = fmt.Sprintf(d.unitFormat, SpeedKiB(speed)) - case UnitKB: - d.msg = fmt.Sprintf(d.unitFormat, SpeedKB(speed)) - default: - d.msg = fmt.Sprintf(d.unitFormat, speed) - } - - return d.FormatMsg(d.msg) -} - -func (s *movingAverageSpeed) NextAmount(n int, wdd ...time.Duration) { - var workDuration time.Duration - for _, wd := range wdd { - workDuration = wd - } - speed := float64(n) / workDuration.Seconds() / 1000 - if math.IsInf(speed, 0) || math.IsNaN(speed) { - return - } - s.average.Add(speed) -} - -func (d *movingAverageSpeed) OnCompleteMessage(msg string) { - d.completeMsg = &msg -} - -// AverageSpeed decorator with dynamic unit measure adjustment. -// -// `unit` one of [0|UnitKiB|UnitKB] zero for no unit -// -// `unitFormat` printf compatible verb for value, like "%f" or "%d" -// -// `wcc` optional WC config -// -// unitFormat example if UnitKiB is chosen: -// -// "%.1f" = "1.0MiB/s" or "% .1f" = "1.0 MiB/s" -func AverageSpeed(unit int, unitFormat string, wcc ...WC) Decorator { - var wc WC - for _, widthConf := range wcc { - wc = widthConf - } - wc.Init() - d := &averageSpeed{ - WC: wc, - unit: unit, - unitFormat: unitFormat, - startTime: time.Now(), - } - return d -} - -type averageSpeed struct { - WC - unit int - unitFormat string - startTime time.Time - msg string - completeMsg *string -} - -func (d *averageSpeed) Decor(st *Statistics) string { - if st.Completed { - if d.completeMsg != nil { - return d.FormatMsg(*d.completeMsg) - } - return d.FormatMsg(d.msg) - } - - timeElapsed := time.Since(d.startTime) - speed := float64(st.Current) / timeElapsed.Seconds() - - switch d.unit { - case UnitKiB: - d.msg = fmt.Sprintf(d.unitFormat, SpeedKiB(speed)) - case UnitKB: - d.msg = fmt.Sprintf(d.unitFormat, SpeedKB(speed)) - default: - d.msg = fmt.Sprintf(d.unitFormat, speed) - } - - return d.FormatMsg(d.msg) -} - -func (d *averageSpeed) OnCompleteMessage(msg string) { - d.completeMsg = &msg -} diff --git a/vendor/github.com/vbauerster/mpb/doc.go b/vendor/github.com/vbauerster/mpb/doc.go deleted file mode 100644 index 16245956a..000000000 --- a/vendor/github.com/vbauerster/mpb/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (C) 2016-2018 Vladimir Bauer -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package mpb is a library for rendering progress bars in terminal applications. -package mpb diff --git a/vendor/github.com/vbauerster/mpb/go.test.sh b/vendor/github.com/vbauerster/mpb/go.test.sh deleted file mode 100644 index 34dbbfb31..000000000 --- a/vendor/github.com/vbauerster/mpb/go.test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e -echo "" > coverage.txt - -for d in $(go list ./... | grep -v vendor); do - go test -race -coverprofile=profile.out -covermode=atomic $d - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - rm profile.out - fi -done diff --git a/vendor/github.com/vbauerster/mpb/internal/percentage.go b/vendor/github.com/vbauerster/mpb/internal/percentage.go deleted file mode 100644 index 0483d2598..000000000 --- a/vendor/github.com/vbauerster/mpb/internal/percentage.go +++ /dev/null @@ -1,12 +0,0 @@ -package internal - -import "math" - -// Percentage is a helper function, to calculate percentage. -func Percentage(total, current, width int64) int64 { - if total <= 0 { - return 0 - } - p := float64(width*current) / float64(total) - return int64(math.Round(p)) -} diff --git a/vendor/github.com/vbauerster/mpb/options.go b/vendor/github.com/vbauerster/mpb/options.go deleted file mode 100644 index 44a6ee3f3..000000000 --- a/vendor/github.com/vbauerster/mpb/options.go +++ /dev/null @@ -1,90 +0,0 @@ -package mpb - -import ( - "context" - "io" - "sync" - "time" - - "github.com/vbauerster/mpb/cwriter" -) - -// ProgressOption is a function option which changes the default -// behavior of progress pool, if passed to mpb.New(...ProgressOption). -type ProgressOption func(*pState) - -// WithWaitGroup provides means to have a single joint point. If -// *sync.WaitGroup is provided, you can safely call just p.Wait() -// without calling Wait() on provided *sync.WaitGroup. Makes sense -// when there are more than one bar to render. -func WithWaitGroup(wg *sync.WaitGroup) ProgressOption { - return func(s *pState) { - s.uwg = wg - } -} - -// WithWidth sets container width. Default is 80. Bars inherit this -// width, as long as no BarWidth is applied. -func WithWidth(w int) ProgressOption { - return func(s *pState) { - if w >= 0 { - s.width = w - } - } -} - -// WithRefreshRate overrides default 120ms refresh rate. -func WithRefreshRate(d time.Duration) ProgressOption { - return func(s *pState) { - if d < 10*time.Millisecond { - return - } - s.rr = d - } -} - -// WithManualRefresh disables internal auto refresh time.Ticker. -// Refresh will occur upon receive value from provided ch. -func WithManualRefresh(ch <-chan time.Time) ProgressOption { - return func(s *pState) { - s.manualRefreshCh = ch - } -} - -// WithContext provided context will be used for cancellation purposes. -func WithContext(ctx context.Context) ProgressOption { - return func(s *pState) { - if ctx == nil { - return - } - s.ctx = ctx - } -} - -// WithShutdownNotifier provided chanel will be closed, after all bars -// have been rendered. -func WithShutdownNotifier(ch chan struct{}) ProgressOption { - return func(s *pState) { - s.shutdownNotifier = ch - } -} - -// WithOutput overrides default output os.Stdout. -func WithOutput(w io.Writer) ProgressOption { - return func(s *pState) { - if w == nil { - return - } - s.cw = cwriter.New(w) - } -} - -// WithDebugOutput sets debug output. -func WithDebugOutput(w io.Writer) ProgressOption { - return func(s *pState) { - if w == nil { - return - } - s.debugOut = w - } -} diff --git a/vendor/github.com/vbauerster/mpb/progress.go b/vendor/github.com/vbauerster/mpb/progress.go deleted file mode 100644 index f9e25af79..000000000 --- a/vendor/github.com/vbauerster/mpb/progress.go +++ /dev/null @@ -1,267 +0,0 @@ -package mpb - -import ( - "container/heap" - "context" - "fmt" - "io" - "io/ioutil" - "os" - "sync" - "time" - - "github.com/vbauerster/mpb/cwriter" -) - -const ( - // default RefreshRate - prr = 120 * time.Millisecond - // default width - pwidth = 80 -) - -// Progress represents the container that renders Progress bars -type Progress struct { - wg *sync.WaitGroup - uwg *sync.WaitGroup - operateState chan func(*pState) - done chan struct{} -} - -type pState struct { - bHeap *priorityQueue - shutdownPending []*Bar - heapUpdated bool - zeroWait bool - idCounter int - width int - format string - rr time.Duration - cw *cwriter.Writer - pMatrix map[int][]chan int - aMatrix map[int][]chan int - - // following are provided/overrided by user - ctx context.Context - uwg *sync.WaitGroup - manualRefreshCh <-chan time.Time - shutdownNotifier chan struct{} - waitBars map[*Bar]*Bar - debugOut io.Writer -} - -// New creates new Progress instance, which orchestrates bars rendering -// process. Accepts mpb.ProgressOption funcs for customization. -func New(options ...ProgressOption) *Progress { - pq := make(priorityQueue, 0) - heap.Init(&pq) - s := &pState{ - ctx: context.Background(), - bHeap: &pq, - width: pwidth, - cw: cwriter.New(os.Stdout), - rr: prr, - waitBars: make(map[*Bar]*Bar), - debugOut: ioutil.Discard, - } - - for _, opt := range options { - if opt != nil { - opt(s) - } - } - - p := &Progress{ - uwg: s.uwg, - wg: new(sync.WaitGroup), - operateState: make(chan func(*pState)), - done: make(chan struct{}), - } - go p.serve(s) - return p -} - -// AddBar creates a new progress bar and adds to the container. -func (p *Progress) AddBar(total int64, options ...BarOption) *Bar { - return p.Add(total, newDefaultBarFiller(), options...) -} - -// AddSpinner creates a new spinner bar and adds to the container. -func (p *Progress) AddSpinner(total int64, alignment SpinnerAlignment, options ...BarOption) *Bar { - filler := &spinnerFiller{ - frames: defaultSpinnerStyle, - alignment: alignment, - } - return p.Add(total, filler, options...) -} - -// Add creates a bar which renders itself by provided filler. -func (p *Progress) Add(total int64, filler Filler, options ...BarOption) *Bar { - if filler == nil { - filler = newDefaultBarFiller() - } - p.wg.Add(1) - result := make(chan *Bar) - select { - case p.operateState <- func(s *pState) { - b := newBar(s.ctx, p.wg, filler, s.idCounter, s.width, total, options...) - if b.runningBar != nil { - s.waitBars[b.runningBar] = b - } else { - heap.Push(s.bHeap, b) - s.heapUpdated = true - } - s.idCounter++ - result <- b - }: - return <-result - case <-p.done: - p.wg.Done() - return nil - } -} - -// Abort is only effective while bar progress is running, it means -// remove bar now without waiting for its completion. If bar is already -// completed, there is nothing to abort. If you need to remove bar -// after completion, use BarRemoveOnComplete BarOption. -func (p *Progress) Abort(b *Bar, remove bool) { - select { - case p.operateState <- func(s *pState) { - if b.index < 0 { - return - } - if remove { - s.heapUpdated = heap.Remove(s.bHeap, b.index) != nil - } - s.shutdownPending = append(s.shutdownPending, b) - }: - case <-p.done: - } -} - -// UpdateBarPriority provides a way to change bar's order position. -// Zero is highest priority, i.e. bar will be on top. -func (p *Progress) UpdateBarPriority(b *Bar, priority int) { - select { - case p.operateState <- func(s *pState) { s.bHeap.update(b, priority) }: - case <-p.done: - } -} - -// BarCount returns bars count -func (p *Progress) BarCount() int { - result := make(chan int, 1) - select { - case p.operateState <- func(s *pState) { result <- s.bHeap.Len() }: - return <-result - case <-p.done: - return 0 - } -} - -// Wait first waits for user provided *sync.WaitGroup, if any, then -// waits far all bars to complete and finally shutdowns master goroutine. -// After this method has been called, there is no way to reuse *Progress -// instance. -func (p *Progress) Wait() { - if p.uwg != nil { - p.uwg.Wait() - } - - p.wg.Wait() - - select { - case p.operateState <- func(s *pState) { s.zeroWait = true }: - <-p.done - case <-p.done: - } -} - -func (s *pState) updateSyncMatrix() { - s.pMatrix = make(map[int][]chan int) - s.aMatrix = make(map[int][]chan int) - for i := 0; i < s.bHeap.Len(); i++ { - bar := (*s.bHeap)[i] - table := bar.wSyncTable() - pRow, aRow := table[0], table[1] - - for i, ch := range pRow { - s.pMatrix[i] = append(s.pMatrix[i], ch) - } - - for i, ch := range aRow { - s.aMatrix[i] = append(s.aMatrix[i], ch) - } - } -} - -func (s *pState) render(tw int) { - if s.heapUpdated { - s.updateSyncMatrix() - s.heapUpdated = false - } - syncWidth(s.pMatrix) - syncWidth(s.aMatrix) - - for i := 0; i < s.bHeap.Len(); i++ { - bar := (*s.bHeap)[i] - go bar.render(s.debugOut, tw) - } - - if err := s.flush(s.bHeap.Len()); err != nil { - fmt.Fprintf(s.debugOut, "%s %s %v\n", "[mpb]", time.Now(), err) - } -} - -func (s *pState) flush(lineCount int) error { - for s.bHeap.Len() > 0 { - bar := heap.Pop(s.bHeap).(*Bar) - frameReader := <-bar.frameReaderCh - defer func() { - if frameReader.toShutdown { - // shutdown at next flush, in other words decrement underlying WaitGroup - // only after the bar with completed state has been flushed. this - // ensures no bar ends up with less than 100% rendered. - s.shutdownPending = append(s.shutdownPending, bar) - if replacementBar, ok := s.waitBars[bar]; ok { - heap.Push(s.bHeap, replacementBar) - s.heapUpdated = true - delete(s.waitBars, bar) - } - if frameReader.removeOnComplete { - s.heapUpdated = true - return - } - } - heap.Push(s.bHeap, bar) - }() - s.cw.ReadFrom(frameReader) - lineCount += frameReader.extendedLines - } - - for i := len(s.shutdownPending) - 1; i >= 0; i-- { - close(s.shutdownPending[i].shutdown) - s.shutdownPending = s.shutdownPending[:i] - } - - return s.cw.Flush(lineCount) -} - -func syncWidth(matrix map[int][]chan int) { - for _, column := range matrix { - column := column - go func() { - var maxWidth int - for _, ch := range column { - w := <-ch - if w > maxWidth { - maxWidth = w - } - } - for _, ch := range column { - ch <- maxWidth - } - }() - } -} diff --git a/vendor/github.com/vbauerster/mpb/progress_posix.go b/vendor/github.com/vbauerster/mpb/progress_posix.go deleted file mode 100644 index 545245a42..000000000 --- a/vendor/github.com/vbauerster/mpb/progress_posix.go +++ /dev/null @@ -1,70 +0,0 @@ -// +build !windows - -package mpb - -import ( - "os" - "os/signal" - "syscall" - "time" -) - -func (p *Progress) serve(s *pState) { - - var ticker *time.Ticker - var refreshCh <-chan time.Time - var winch chan os.Signal - var resumeTimer *time.Timer - var resumeEvent <-chan time.Time - winchIdleDur := s.rr * 2 - - if s.manualRefreshCh == nil { - ticker = time.NewTicker(s.rr) - refreshCh = ticker.C - winch = make(chan os.Signal, 2) - signal.Notify(winch, syscall.SIGWINCH) - } else { - refreshCh = s.manualRefreshCh - } - - for { - select { - case op := <-p.operateState: - op(s) - case <-refreshCh: - if s.zeroWait { - if s.manualRefreshCh == nil { - signal.Stop(winch) - ticker.Stop() - } - if s.shutdownNotifier != nil { - close(s.shutdownNotifier) - } - close(p.done) - return - } - tw, err := s.cw.GetWidth() - if err != nil { - tw = s.width - } - s.render(tw) - case <-winch: - tw, err := s.cw.GetWidth() - if err != nil { - tw = s.width - } - s.render(tw - tw/8) - if resumeTimer != nil && resumeTimer.Reset(winchIdleDur) { - break - } - ticker.Stop() - resumeTimer = time.NewTimer(winchIdleDur) - resumeEvent = resumeTimer.C - case <-resumeEvent: - ticker = time.NewTicker(s.rr) - refreshCh = ticker.C - resumeEvent = nil - resumeTimer = nil - } - } -} diff --git a/vendor/github.com/vbauerster/mpb/progress_windows.go b/vendor/github.com/vbauerster/mpb/progress_windows.go deleted file mode 100644 index cab03d36c..000000000 --- a/vendor/github.com/vbauerster/mpb/progress_windows.go +++ /dev/null @@ -1,43 +0,0 @@ -// +build windows - -package mpb - -import ( - "time" -) - -func (p *Progress) serve(s *pState) { - - var ticker *time.Ticker - var refreshCh <-chan time.Time - - if s.manualRefreshCh == nil { - ticker = time.NewTicker(s.rr) - refreshCh = ticker.C - } else { - refreshCh = s.manualRefreshCh - } - - for { - select { - case op := <-p.operateState: - op(s) - case <-refreshCh: - if s.zeroWait { - if s.manualRefreshCh == nil { - ticker.Stop() - } - if s.shutdownNotifier != nil { - close(s.shutdownNotifier) - } - close(p.done) - return - } - tw, err := s.cw.GetWidth() - if err != nil { - tw = s.width - } - s.render(tw) - } - } -} diff --git a/vendor/github.com/vbauerster/mpb/proxyreader.go b/vendor/github.com/vbauerster/mpb/proxyreader.go deleted file mode 100644 index d2692ccf4..000000000 --- a/vendor/github.com/vbauerster/mpb/proxyreader.go +++ /dev/null @@ -1,22 +0,0 @@ -package mpb - -import ( - "io" - "time" -) - -// proxyReader is io.Reader wrapper, for proxy read bytes -type proxyReader struct { - io.ReadCloser - bar *Bar - iT time.Time -} - -func (pr *proxyReader) Read(p []byte) (n int, err error) { - n, err = pr.ReadCloser.Read(p) - if n > 0 { - pr.bar.IncrBy(n, time.Since(pr.iT)) - pr.iT = time.Now() - } - return -} diff --git a/vendor/github.com/vbauerster/mpb/.gitignore b/vendor/github.com/vbauerster/mpb/v4/.gitignore index 63bd91672..63bd91672 100644 --- a/vendor/github.com/vbauerster/mpb/.gitignore +++ b/vendor/github.com/vbauerster/mpb/v4/.gitignore diff --git a/vendor/github.com/vbauerster/mpb/v4/.travis.yml b/vendor/github.com/vbauerster/mpb/v4/.travis.yml new file mode 100644 index 000000000..997ae32d6 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/.travis.yml @@ -0,0 +1,12 @@ +language: go + +go: + - 1.12.x + - 1.13.x + +env: + - GO111MODULE=on + +script: + - go test -race ./... + - for i in _examples/*/; do go build $i/*.go || exit 1; done diff --git a/vendor/github.com/vbauerster/mpb/README.md b/vendor/github.com/vbauerster/mpb/v4/README.md index f96857c47..003fb5987 100644 --- a/vendor/github.com/vbauerster/mpb/README.md +++ b/vendor/github.com/vbauerster/mpb/v4/README.md @@ -3,43 +3,41 @@ [![GoDoc](https://godoc.org/github.com/vbauerster/mpb?status.svg)](https://godoc.org/github.com/vbauerster/mpb) [![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) -[![codecov](https://codecov.io/gh/vbauerster/mpb/branch/master/graph/badge.svg)](https://codecov.io/gh/vbauerster/mpb) **mpb** is a Go lib for rendering progress bars in terminal applications. ## Features * __Multiple Bars__: Multiple progress bars are supported -* __Dynamic Total__: [Set total](https://github.com/vbauerster/mpb/issues/9#issuecomment-344448984) while bar is running +* __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 -## Installation +## Usage -```sh -go get github.com/vbauerster/mpb -``` +#### [Rendering single bar](_examples/singleBar/main.go) +```go +package main -_Note:_ it is preferable to go get from github.com, rather than gopkg.in. See issue [#11](https://github.com/vbauerster/mpb/issues/11). +import ( + "math/rand" + "time" -## Usage + "github.com/vbauerster/mpb/v4" + "github.com/vbauerster/mpb/v4/decor" +) -#### [Rendering single bar](examples/singleBar/main.go) -```go - p := mpb.New( - // override default (80) width - mpb.WithWidth(64), - // override default 120ms refresh rate - mpb.WithRefreshRate(180*time.Millisecond), - ) +func main() { + // initialize progress container, with custom width + p := mpb.New(mpb.WithWidth(64)) total := 100 name := "Single Bar:" - // adding a single bar + // adding a single bar, which will inherit container's width bar := p.AddBar(int64(total), - // override default "[=>-]" style + // override DefaultBarStyle, which is "[=>-]<+" mpb.BarStyle("╢▌▌░╟"), mpb.PrependDecorators( // display our name with one space on the right @@ -57,16 +55,18 @@ _Note:_ it is preferable to go get from github.com, rather than gopkg.in. See is for i := 0; i < total; i++ { start := time.Now() time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) - // ewma based decorators require work duration measurement - bar.IncrBy(1, time.Since(start)) + // since ewma decorator is used, we need to pass time.Since(start) + bar.Increment(time.Since(start)) } // wait for our bar to complete and flush p.Wait() +} ``` -#### [Rendering multiple bars](examples/simple/main.go) +#### [Rendering multiple bars](_examples/multiBars//main.go) ```go var wg sync.WaitGroup + // pass &wg (optional), so p will wait for it eventually p := mpb.New(mpb.WithWaitGroup(&wg)) total, numBars := 100, 3 wg.Add(numBars) @@ -91,27 +91,28 @@ _Note:_ it is preferable to go get from github.com, rather than gopkg.in. See is // simulating some work go func() { defer wg.Done() + rng := rand.New(rand.NewSource(time.Now().UnixNano())) max := 100 * time.Millisecond for i := 0; i < total; i++ { start := time.Now() - time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) - // ewma based decorators require work duration measurement - bar.IncrBy(1, time.Since(start)) + time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) + // since ewma decorator is used, we need to pass time.Since(start) + bar.Increment(time.Since(start)) } }() } - // wait for all bars to complete and flush + // Waiting for passed &wg and for all bars to complete and flush p.Wait() ``` -#### [Dynamic total](examples/dynTotal/main.go) +#### [Dynamic total](_examples/dynTotal/main.go) -![dynamic total](examples/gifs/godEMrCZmJkHYH1X9dN4Nm0U7.svg) +![dynamic total](_svg/godEMrCZmJkHYH1X9dN4Nm0U7.svg) -#### [Complex example](examples/complex/main.go) +#### [Complex example](_examples/complex/main.go) -![complex](examples/gifs/wHzf1M7sd7B3zVa2scBMnjqRf.svg) +![complex](_svg/wHzf1M7sd7B3zVa2scBMnjqRf.svg) -#### [Bytes counters](examples/io/single/main.go) +#### [Bytes counters](_examples/io/main.go) -![byte counters](examples/gifs/hIpTa3A5rQz65ssiVuRJu87X6.svg) +![byte counters](_svg/hIpTa3A5rQz65ssiVuRJu87X6.svg) diff --git a/vendor/github.com/vbauerster/mpb/v4/UNLICENSE b/vendor/github.com/vbauerster/mpb/v4/UNLICENSE new file mode 100644 index 000000000..68a49daad --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/UNLICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to <http://unlicense.org/> diff --git a/vendor/github.com/vbauerster/mpb/v4/bar.go b/vendor/github.com/vbauerster/mpb/v4/bar.go new file mode 100644 index 000000000..c362da739 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/bar.go @@ -0,0 +1,477 @@ +package mpb + +import ( + "bytes" + "context" + "fmt" + "io" + "io/ioutil" + "log" + "strings" + "time" + "unicode/utf8" + + "github.com/vbauerster/mpb/v4/decor" +) + +// Filler interface. +// Bar renders by calling Filler's Fill method. You can literally have +// any bar kind, by implementing this interface and passing it to the +// *Progress.Add method. +type Filler interface { + Fill(w io.Writer, width int, stat *decor.Statistics) +} + +// FillerFunc is function type adapter to convert function into Filler. +type FillerFunc func(w io.Writer, width int, stat *decor.Statistics) + +func (f FillerFunc) Fill(w io.Writer, width int, stat *decor.Statistics) { + f(w, width, stat) +} + +// Wrapper 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 { + Base() Filler +} + +// Bar represents a progress Bar. +type Bar struct { + priority int // used by heap + index int // used by heap + + extendedLines int + toShutdown bool + toDrop bool + noPop bool + operateState chan func(*bState) + frameCh chan io.Reader + syncTableCh chan [][]chan int + completed chan bool + + // cancel is called either by user or on complete event + cancel func() + // done is closed after cacheState is assigned + done chan struct{} + // cacheState is populated, right after close(shutdown) + cacheState *bState + + container *Progress + dlogger *log.Logger + recoveredPanic interface{} +} + +type extFunc func(in io.Reader, tw int, st *decor.Statistics) (out io.Reader, lines int) + +type bState struct { + baseF Filler + filler Filler + id int + width int + total int64 + current int64 + trimSpace bool + toComplete bool + completeFlushed bool + noPop bool + aDecorators []decor.Decorator + pDecorators []decor.Decorator + amountReceivers []decor.AmountReceiver + shutdownListeners []decor.ShutdownListener + averageAdjusters []decor.AverageAdjuster + bufP, bufB, bufA *bytes.Buffer + extender extFunc + + // priority overrides *Bar's priority, if set + priority int + // dropOnComplete propagates to *Bar + dropOnComplete bool + // runningBar is a key for *pState.parkedBars + runningBar *Bar + + debugOut io.Writer +} + +func newBar(container *Progress, bs *bState) *Bar { + logPrefix := fmt.Sprintf("%sbar#%02d ", container.dlogger.Prefix(), bs.id) + ctx, cancel := context.WithCancel(container.ctx) + + bar := &Bar{ + container: container, + priority: bs.priority, + toDrop: bs.dropOnComplete, + noPop: bs.noPop, + operateState: make(chan func(*bState)), + frameCh: make(chan io.Reader, 1), + syncTableCh: make(chan [][]chan int), + completed: make(chan bool, 1), + done: make(chan struct{}), + cancel: cancel, + dlogger: log.New(bs.debugOut, logPrefix, log.Lshortfile), + } + + go bar.serve(ctx, bs) + return bar +} + +// RemoveAllPrependers removes all prepend functions. +func (b *Bar) RemoveAllPrependers() { + select { + case b.operateState <- func(s *bState) { s.pDecorators = nil }: + case <-b.done: + } +} + +// RemoveAllAppenders removes all append functions. +func (b *Bar) RemoveAllAppenders() { + select { + case b.operateState <- func(s *bState) { s.aDecorators = nil }: + case <-b.done: + } +} + +// ProxyReader wraps r with metrics required for progress tracking. +func (b *Bar) ProxyReader(r io.Reader) io.ReadCloser { + if r == nil { + return nil + } + rc, ok := r.(io.ReadCloser) + if !ok { + rc = ioutil.NopCloser(r) + } + prox := &proxyReader{rc, b, time.Now()} + if wt, ok := r.(io.WriterTo); ok { + return &proxyWriterTo{prox, wt} + } + return prox +} + +// ID returs id of the bar. +func (b *Bar) ID() int { + result := make(chan int) + select { + case b.operateState <- func(s *bState) { result <- s.id }: + return <-result + case <-b.done: + return b.cacheState.id + } +} + +// Current returns bar's current number, in other words sum of all increments. +func (b *Bar) Current() int64 { + result := make(chan int64) + select { + case b.operateState <- func(s *bState) { result <- s.current }: + return <-result + case <-b.done: + return b.cacheState.current + } +} + +// SetRefill sets refill, if supported by underlying Filler. +// Useful for resume-able tasks. +func (b *Bar) SetRefill(amount int64) { + type refiller interface { + SetRefill(int64) + } + b.operateState <- func(s *bState) { + if f, ok := s.baseF.(refiller); ok { + f.SetRefill(amount) + } + } +} + +// AdjustAverageDecorators updates start time of all average decorators. +// Useful for resume-able tasks. +func (b *Bar) AdjustAverageDecorators(startTime time.Time) { + b.operateState <- func(s *bState) { + for _, adjuster := range s.averageAdjusters { + adjuster.AverageAdjust(startTime) + } + } +} + +// TraverseDecorators traverses all available decorators and calls cb func on each. +func (b *Bar) TraverseDecorators(cb decor.CBFunc) { + b.operateState <- func(s *bState) { + for _, decorators := range [...][]decor.Decorator{ + s.pDecorators, + s.aDecorators, + } { + for _, d := range decorators { + cb(extractBaseDecorator(d)) + } + } + } +} + +// SetTotal sets total dynamically. +// Set complete to true, to trigger bar complete event now. +func (b *Bar) SetTotal(total int64, complete bool) { + select { + case b.operateState <- func(s *bState) { + if total <= 0 { + s.total = s.current + } else { + s.total = total + } + if complete && !s.toComplete { + s.current = s.total + s.toComplete = true + go b.refreshTillShutdown() + } + }: + case <-b.done: + } +} + +// SetCurrent sets progress' current to arbitrary amount. +func (b *Bar) SetCurrent(current int64, wdd ...time.Duration) { + select { + case b.operateState <- func(s *bState) { + for _, ar := range s.amountReceivers { + ar.NextAmount(current-s.current, wdd...) + } + s.current = current + if s.total > 0 && s.current >= s.total { + s.current = s.total + s.toComplete = true + go b.refreshTillShutdown() + } + }: + case <-b.done: + } +} + +// Increment is a shorthand for b.IncrInt64(1, wdd...). +func (b *Bar) Increment(wdd ...time.Duration) { + b.IncrInt64(1, wdd...) +} + +// IncrBy is a shorthand for b.IncrInt64(int64(n), wdd...). +func (b *Bar) IncrBy(n int, wdd ...time.Duration) { + b.IncrInt64(int64(n), wdd...) +} + +// IncrInt64 increments progress bar by amount of n. wdd is an optional +// work duration i.e. time.Since(start), which expected to be passed, +// if any ewma based decorator is used. +func (b *Bar) IncrInt64(n int64, wdd ...time.Duration) { + select { + case b.operateState <- func(s *bState) { + for _, ar := range s.amountReceivers { + ar.NextAmount(n, wdd...) + } + s.current += n + if s.total > 0 && s.current >= s.total { + s.current = s.total + s.toComplete = true + go b.refreshTillShutdown() + } + }: + case <-b.done: + } +} + +// SetPriority changes bar's order among multiple bars. Zero is highest +// priority, i.e. bar will be on top. If you don't need to set priority +// dynamically, better use BarPriority option. +func (b *Bar) SetPriority(priority int) { + select { + case <-b.done: + default: + b.container.setBarPriority(b, priority) + } +} + +// Abort interrupts bar's running goroutine. Call this, if you'd like +// to stop/remove bar before completion event. It has no effect after +// completion event. If drop is true bar will be removed as well. +func (b *Bar) Abort(drop bool) { + select { + case <-b.done: + default: + if drop { + b.container.dropBar(b) + } + b.cancel() + } +} + +// 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 }: + return <-b.completed + case <-b.done: + return true + } +} + +func (b *Bar) serve(ctx context.Context, s *bState) { + defer b.container.bwg.Done() + for { + select { + case op := <-b.operateState: + op(s) + case <-ctx.Done(): + b.cacheState = s + close(b.done) + // Notifying decorators about shutdown event + for _, sl := range s.shutdownListeners { + sl.Shutdown() + } + return + } + } +} + +func (b *Bar) render(tw int) { + if b.recoveredPanic != nil { + b.toShutdown = false + b.frameCh <- b.panicToFrame(tw) + return + } + select { + case b.operateState <- func(s *bState) { + defer func() { + // recovering if user defined decorator panics for example + if p := recover(); p != nil { + b.dlogger.Println(p) + b.recoveredPanic = p + b.toShutdown = !s.completeFlushed + b.frameCh <- b.panicToFrame(tw) + } + }() + + st := newStatistics(s) + frame := s.draw(tw, st) + frame, b.extendedLines = s.extender(frame, tw, st) + + b.toShutdown = s.toComplete && !s.completeFlushed + s.completeFlushed = s.toComplete + b.frameCh <- frame + }: + case <-b.done: + s := b.cacheState + st := newStatistics(s) + frame := s.draw(tw, st) + frame, b.extendedLines = s.extender(frame, tw, st) + b.frameCh <- frame + } +} + +func (b *Bar) panicToFrame(termWidth int) io.Reader { + return strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%dv\n", termWidth), b.recoveredPanic)) +} + +func (b *Bar) subscribeDecorators() { + var amountReceivers []decor.AmountReceiver + var shutdownListeners []decor.ShutdownListener + var averageAdjusters []decor.AverageAdjuster + b.TraverseDecorators(func(d decor.Decorator) { + if d, ok := d.(decor.AmountReceiver); ok { + amountReceivers = append(amountReceivers, d) + } + if d, ok := d.(decor.ShutdownListener); ok { + shutdownListeners = append(shutdownListeners, d) + } + if d, ok := d.(decor.AverageAdjuster); ok { + averageAdjusters = append(averageAdjusters, d) + } + }) + b.operateState <- func(s *bState) { + s.amountReceivers = amountReceivers + s.shutdownListeners = shutdownListeners + s.averageAdjusters = averageAdjusters + } +} + +func (b *Bar) refreshTillShutdown() { + for { + select { + case b.container.refreshCh <- time.Now(): + case <-b.done: + return + } + } +} + +func (b *Bar) wSyncTable() [][]chan int { + select { + case b.operateState <- func(s *bState) { b.syncTableCh <- s.wSyncTable() }: + return <-b.syncTableCh + case <-b.done: + return b.cacheState.wSyncTable() + } +} + +func (s *bState) draw(termWidth int, stat *decor.Statistics) io.Reader { + for _, d := range s.pDecorators { + s.bufP.WriteString(d.Decor(stat)) + } + + for _, d := range s.aDecorators { + s.bufA.WriteString(d.Decor(stat)) + } + + s.bufA.WriteByte('\n') + + prependCount := utf8.RuneCount(s.bufP.Bytes()) + appendCount := utf8.RuneCount(s.bufA.Bytes()) - 1 + + if fitWidth := s.width; termWidth > 1 { + if !s.trimSpace { + // reserve space for edge spaces + termWidth -= 2 + s.bufB.WriteByte(' ') + defer s.bufB.WriteByte(' ') + } + if prependCount+s.width+appendCount > termWidth { + fitWidth = termWidth - prependCount - appendCount + } + s.filler.Fill(s.bufB, fitWidth, stat) + } + + return io.MultiReader(s.bufP, s.bufB, s.bufA) +} + +func (s *bState) wSyncTable() [][]chan int { + columns := make([]chan int, 0, len(s.pDecorators)+len(s.aDecorators)) + var pCount int + for _, d := range s.pDecorators { + if ch, ok := d.Sync(); ok { + columns = append(columns, ch) + pCount++ + } + } + var aCount int + for _, d := range s.aDecorators { + if ch, ok := d.Sync(); ok { + columns = append(columns, ch) + aCount++ + } + } + table := make([][]chan int, 2) + table[0] = columns[0:pCount] + table[1] = columns[pCount : pCount+aCount : pCount+aCount] + return table +} + +func newStatistics(s *bState) *decor.Statistics { + return &decor.Statistics{ + ID: s.id, + Completed: s.completeFlushed, + Total: s.total, + Current: s.current, + } +} + +func extractBaseDecorator(d decor.Decorator) decor.Decorator { + if d, ok := d.(decor.Wrapper); ok { + return extractBaseDecorator(d.Base()) + } + return d +} diff --git a/vendor/github.com/vbauerster/mpb/v4/bar_filler.go b/vendor/github.com/vbauerster/mpb/v4/bar_filler.go new file mode 100644 index 000000000..0d751a68d --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/bar_filler.go @@ -0,0 +1,137 @@ +package mpb + +import ( + "io" + "unicode/utf8" + + "github.com/vbauerster/mpb/v4/decor" + "github.com/vbauerster/mpb/v4/internal" +) + +const ( + rLeft = iota + rFill + rTip + rEmpty + rRight + rRevTip + rRefill +) + +// DefaultBarStyle is applied when bar constructed with *Progress.AddBar method. +// +// '1th rune' stands for left boundary rune +// +// '2th rune' stands for fill rune +// +// '3th rune' stands for tip rune +// +// '4th rune' stands for empty rune +// +// '5th rune' stands for right boundary rune +// +// '6th rune' stands for reverse tip rune +// +// '7th rune' stands for refill rune +// +const DefaultBarStyle string = "[=>-]<+" + +type barFiller struct { + format [][]byte + tip []byte + refill int64 + reverse bool + flush func(w io.Writer, bb [][]byte) +} + +// NewBarFiller constucts mpb.Filler, to be used with *Progress.Add method. +func NewBarFiller(style string, reverse bool) Filler { + if style == "" { + style = DefaultBarStyle + } + bf := &barFiller{ + format: make([][]byte, utf8.RuneCountInString(style)), + } + bf.SetStyle(style) + bf.SetReverse(reverse) + return bf +} + +func (s *barFiller) SetStyle(style string) { + if !utf8.ValidString(style) { + return + } + src := make([][]byte, 0, utf8.RuneCountInString(style)) + for _, r := range style { + src = append(src, []byte(string(r))) + } + copy(s.format, src) + if s.reverse { + s.tip = s.format[rRevTip] + } else { + s.tip = s.format[rTip] + } +} + +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]) + } + } + } 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.reverse = reverse +} + +func (s *barFiller) SetRefill(amount int64) { + s.refill = amount +} + +func (s *barFiller) Fill(w io.Writer, width int, stat *decor.Statistics) { + // don't count rLeft and rRight as progress + width -= 2 + if width < 2 { + return + } + w.Write(s.format[rLeft]) + defer w.Write(s.format[rRight]) + + bb := make([][]byte, width) + + cwidth := int(internal.PercentageRound(stat.Total, stat.Current, width)) + + for i := 0; i < cwidth; i++ { + bb[i] = s.format[rFill] + } + + if s.refill > 0 { + var rwidth int + if s.refill > stat.Current { + rwidth = cwidth + } else { + rwidth = int(internal.PercentageRound(stat.Total, int64(s.refill), width)) + } + for i := 0; i < rwidth; i++ { + bb[i] = s.format[rRefill] + } + } + + if cwidth > 0 && cwidth < width { + bb[cwidth-1] = s.tip + } + + for i := cwidth; i < width; i++ { + bb[i] = s.format[rEmpty] + } + + s.flush(w, bb) +} diff --git a/vendor/github.com/vbauerster/mpb/v4/bar_option.go b/vendor/github.com/vbauerster/mpb/v4/bar_option.go new file mode 100644 index 000000000..bb79ac6a4 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/bar_option.go @@ -0,0 +1,209 @@ +package mpb + +import ( + "bytes" + "io" + + "github.com/vbauerster/mpb/v4/decor" +) + +// BarOption is a function option which changes the default behavior of a bar. +type BarOption func(*bState) + +type mergeWrapper interface { + MergeUnwrap() []decor.Decorator +} + +func (s *bState) addDecorators(dest *[]decor.Decorator, decorators ...decor.Decorator) { + for _, decorator := range decorators { + if mw, ok := decorator.(mergeWrapper); ok { + *dest = append(*dest, mw.MergeUnwrap()...) + } + *dest = append(*dest, decorator) + } +} + +// AppendDecorators let you inject decorators to the bar's right side. +func AppendDecorators(decorators ...decor.Decorator) BarOption { + return func(s *bState) { + s.addDecorators(&s.aDecorators, decorators...) + } +} + +// PrependDecorators let you inject decorators to the bar's left side. +func PrependDecorators(decorators ...decor.Decorator) BarOption { + return func(s *bState) { + s.addDecorators(&s.pDecorators, decorators...) + } +} + +// BarID sets bar id. +func BarID(id int) BarOption { + return func(s *bState) { + s.id = id + } +} + +// BarWidth sets bar width independent of the container. +func BarWidth(width int) BarOption { + return func(s *bState) { + s.width = width + } +} + +// BarReplaceOnComplete is deprecated. Use BarParkTo instead. +func BarReplaceOnComplete(runningBar *Bar) BarOption { + return BarParkTo(runningBar) +} + +// BarParkTo parks constructed bar into the runningBar. In other words, +// constructed bar will replace runningBar after it has been completed. +func BarParkTo(runningBar *Bar) BarOption { + if runningBar == nil { + return nil + } + return func(s *bState) { + s.runningBar = runningBar + } +} + +// BarRemoveOnComplete removes bar filler and decorators if any, on +// complete event. +func BarRemoveOnComplete() BarOption { + return func(s *bState) { + s.dropOnComplete = true + } +} + +// BarClearOnComplete clears bar filler only, on complete event. +func BarClearOnComplete() BarOption { + return BarOnComplete("") +} + +// BarOnComplete replaces bar filler with message, on complete event. +func BarOnComplete(message string) BarOption { + return func(s *bState) { + s.filler = makeBarOnCompleteFiller(s.baseF, message) + } +} + +func makeBarOnCompleteFiller(filler Filler, message string) Filler { + return FillerFunc(func(w io.Writer, width int, st *decor.Statistics) { + if st.Completed { + io.WriteString(w, message) + } else { + filler.Fill(w, width, st) + } + }) +} + +// BarPriority sets bar's priority. Zero is highest priority, i.e. bar +// will be on top. If `BarReplaceOnComplete` option is supplied, this +// option is ignored. +func BarPriority(priority int) BarOption { + return func(s *bState) { + s.priority = priority + } +} + +// BarExtender is an option to extend bar to the next new line, with +// arbitrary output. +func BarExtender(extender Filler) BarOption { + if extender == nil { + return nil + } + return func(s *bState) { + s.extender = makeExtFunc(extender) + } +} + +func makeExtFunc(extender Filler) extFunc { + buf := new(bytes.Buffer) + nl := []byte("\n") + return func(r io.Reader, tw int, st *decor.Statistics) (io.Reader, int) { + extender.Fill(buf, tw, st) + return io.MultiReader(r, buf), bytes.Count(buf.Bytes(), nl) + } +} + +// TrimSpace trims bar's edge spaces. +func TrimSpace() BarOption { + return func(s *bState) { + s.trimSpace = true + } +} + +// BarStyle overrides mpb.DefaultBarStyle, for example BarStyle("╢▌▌░╟"). +// If you need to override `reverse tip` and `refill rune` set 6th and +// 7th rune respectively, for example BarStyle("[=>-]<+"). +func BarStyle(style string) BarOption { + if style == "" { + return nil + } + type styleSetter interface { + SetStyle(string) + } + return func(s *bState) { + if t, ok := s.baseF.(styleSetter); ok { + t.SetStyle(style) + } + } +} + +// BarNoPop disables bar pop out of container. Effective when +// PopCompletedMode of container is enabled. +func BarNoPop() BarOption { + return func(s *bState) { + s.noPop = true + } +} + +// 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.baseF.(revSetter); ok { + t.SetReverse(true) + } + } +} + +// 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 Filler) (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(Filler) (interface{}, bool), + cb func(interface{}), +) BarOption { + return func(s *bState) { + if t, ok := typeChecker(s.baseF); ok { + cb(t) + } + } +} + +// BarOptOnCond returns option when condition evaluates to true. +func BarOptOnCond(option BarOption, condition func() bool) BarOption { + if condition() { + return option + } + return nil +} diff --git a/vendor/github.com/vbauerster/mpb/cwriter/writer.go b/vendor/github.com/vbauerster/mpb/v4/cwriter/writer.go index 638237c18..9ec1ec66b 100644 --- a/vendor/github.com/vbauerster/mpb/cwriter/writer.go +++ b/vendor/github.com/vbauerster/mpb/v4/cwriter/writer.go @@ -7,59 +7,50 @@ import ( "io" "os" - isatty "github.com/mattn/go-isatty" "golang.org/x/crypto/ssh/terminal" ) -// ESC is the ASCII code for escape character -const ESC = 27 - +// NotATTY not a TeleTYpewriter error. var NotATTY = errors.New("not a terminal") -var ( - cursorUp = fmt.Sprintf("%c[%dA", ESC, 1) - clearLine = fmt.Sprintf("%c[2K\r", ESC) - clearCursorAndLine = cursorUp + clearLine -) +var cuuAndEd = fmt.Sprintf("%c[%%dA%[1]c[J", 27) -// Writer is a buffered the writer that updates the terminal. The +// Writer is a buffered the writer that updates the terminal. The // contents of writer will be flushed when Flush is called. type Writer struct { out io.Writer buf bytes.Buffer - isTerminal bool - fd int lineCount int + fd uintptr + isTerminal bool } -// New returns a new Writer with defaults +// New returns a new Writer with defaults. func New(out io.Writer) *Writer { w := &Writer{out: out} if f, ok := out.(*os.File); ok { - fd := f.Fd() - w.isTerminal = isatty.IsTerminal(fd) - w.fd = int(fd) + w.fd = f.Fd() + w.isTerminal = terminal.IsTerminal(int(w.fd)) } return w } -// Flush flushes the underlying buffer -func (w *Writer) Flush(lineCount int) error { - err := w.clearLines() - w.lineCount = lineCount - // WriteTo takes care of w.buf.Reset - if _, e := w.buf.WriteTo(w.out); err == nil { - err = e +// Flush flushes the underlying buffer. +func (w *Writer) Flush(lineCount int) (err error) { + if w.lineCount > 0 { + w.clearLines() } - return err + w.lineCount = lineCount + _, err = w.buf.WriteTo(w.out) + return } -// Write appends the contents of p to the underlying buffer +// Write appends the contents of p to the underlying buffer. func (w *Writer) Write(p []byte) (n int, err error) { return w.buf.Write(p) } -// WriteString writes string to the underlying buffer +// WriteString writes string to the underlying buffer. func (w *Writer) WriteString(s string) (n int, err error) { return w.buf.WriteString(s) } @@ -73,7 +64,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 { - tw, _, err := terminal.GetSize(w.fd) + tw, _, err := terminal.GetSize(int(w.fd)) return tw, err } return -1, NotATTY diff --git a/vendor/github.com/vbauerster/mpb/v4/cwriter/writer_posix.go b/vendor/github.com/vbauerster/mpb/v4/cwriter/writer_posix.go new file mode 100644 index 000000000..3fb8b7d75 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/cwriter/writer_posix.go @@ -0,0 +1,9 @@ +// +build !windows + +package cwriter + +import "fmt" + +func (w *Writer) clearLines() { + fmt.Fprintf(w.out, cuuAndEd, w.lineCount) +} diff --git a/vendor/github.com/vbauerster/mpb/v4/cwriter/writer_windows.go b/vendor/github.com/vbauerster/mpb/v4/cwriter/writer_windows.go new file mode 100644 index 000000000..712528900 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/cwriter/writer_windows.go @@ -0,0 +1,60 @@ +// +build windows + +package cwriter + +import ( + "fmt" + "syscall" + "unsafe" +) + +var kernel32 = syscall.NewLazyDLL("kernel32.dll") + +var ( + procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") + procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") + procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") + procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") +) + +type coord struct { + x int16 + y int16 +} + +type smallRect struct { + left int16 + top int16 + right int16 + bottom int16 +} + +type consoleScreenBufferInfo struct { + size coord + cursorPosition coord + attributes uint16 + window smallRect + maximumWindowSize coord +} + +func (w *Writer) clearLines() { + if !w.isTerminal { + fmt.Fprintf(w.out, cuuAndEd, w.lineCount) + } + var info consoleScreenBufferInfo + procGetConsoleScreenBufferInfo.Call(w.fd, uintptr(unsafe.Pointer(&info))) + + info.cursorPosition.y -= int16(w.lineCount) + if info.cursorPosition.y < 0 { + info.cursorPosition.y = 0 + } + procSetConsoleCursorPosition.Call(w.fd, uintptr(uint32(uint16(info.cursorPosition.y))<<16|uint32(uint16(info.cursorPosition.x)))) + + // clear the lines + cursor := coord{ + x: info.window.left, + y: info.cursorPosition.y, + } + count := uint32(info.size.x) * uint32(w.lineCount) + procFillConsoleOutputCharacter.Call(w.fd, uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(new(uint32)))) +} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/counters.go b/vendor/github.com/vbauerster/mpb/v4/decor/counters.go new file mode 100644 index 000000000..32bcdf76a --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/decor/counters.go @@ -0,0 +1,84 @@ +package decor + +import ( + "fmt" +) + +const ( + _ = iota + UnitKiB + UnitKB +) + +// CountersNoUnit is a wrapper around Counters with no unit param. +func CountersNoUnit(pairFmt string, wcc ...WC) Decorator { + return Counters(0, pairFmt, wcc...) +} + +// CountersKibiByte is a wrapper around Counters with predefined unit +// UnitKiB (bytes/1024). +func CountersKibiByte(pairFmt string, wcc ...WC) Decorator { + return Counters(UnitKiB, pairFmt, wcc...) +} + +// CountersKiloByte is a wrapper around Counters with predefined unit +// UnitKB (bytes/1000). +func CountersKiloByte(pairFmt string, wcc ...WC) Decorator { + return Counters(UnitKB, pairFmt, wcc...) +} + +// Counters decorator with dynamic unit measure adjustment. +// +// `unit` one of [0|UnitKiB|UnitKB] zero for no unit +// +// `pairFmt` printf compatible verbs for current and total, like "%f" or "%d" +// +// `wcc` optional WC config +// +// pairFmt example if unit=UnitKB: +// +// pairFmt="%.1f / %.1f" output: "1.0MB / 12.0MB" +// pairFmt="% .1f / % .1f" output: "1.0 MB / 12.0 MB" +// pairFmt="%d / %d" output: "1MB / 12MB" +// 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)) +} + +func chooseSizeProducer(unit int, format string) func(*Statistics) string { + if format == "" { + format = "%d / %d" + } + switch unit { + case UnitKiB: + return func(st *Statistics) string { + return fmt.Sprintf(format, SizeB1024(st.Current), SizeB1024(st.Total)) + } + case UnitKB: + return func(st *Statistics) string { + return fmt.Sprintf(format, SizeB1000(st.Current), SizeB1000(st.Total)) + } + default: + return func(st *Statistics) string { + return fmt.Sprintf(format, st.Current, st.Total) + } + } +} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/decorator.go b/vendor/github.com/vbauerster/mpb/v4/decor/decorator.go new file mode 100644 index 000000000..5c0d16880 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/decor/decorator.go @@ -0,0 +1,173 @@ +package decor + +import ( + "fmt" + "time" + "unicode/utf8" +) + +const ( + // DidentRight bit specifies identation direction. + // |foo |b | With DidentRight + // | foo| b| Without DidentRight + DidentRight = 1 << iota + + // DextraSpace bit adds extra space, makes sense with DSyncWidth only. + // When DidentRight bit set, the space will be added to the right, + // otherwise to the left. + DextraSpace + + // DSyncWidth bit enables same column width synchronization. + // Effective with multiple bars only. + DSyncWidth + + // DSyncWidthR is shortcut for DSyncWidth|DidentRight + DSyncWidthR = DSyncWidth | DidentRight + + // DSyncSpace is shortcut for DSyncWidth|DextraSpace + DSyncSpace = DSyncWidth | DextraSpace + + // DSyncSpaceR is shortcut for DSyncWidth|DextraSpace|DidentRight + DSyncSpaceR = DSyncWidth | DextraSpace | DidentRight +) + +// TimeStyle enum. +type TimeStyle int + +// TimeStyle kinds. +const ( + ET_STYLE_GO TimeStyle = iota + ET_STYLE_HHMMSS + ET_STYLE_HHMM + ET_STYLE_MMSS +) + +// Statistics consists of progress related statistics, that Decorator +// may need. +type Statistics struct { + ID int + Completed bool + Total int64 + Current int64 +} + +// Decorator interface. +// Implementors should embed WC type, that way only single method +// Decor(*Statistics) needs to be implemented, the rest will be handled +// by WC type. +type Decorator interface { + Configurator + Synchronizer + Decor(*Statistics) string +} + +// Synchronizer interface. +// All decorators implement this interface implicitly. Its Sync +// method exposes width sync channel, if DSyncWidth bit is set. +type Synchronizer interface { + Sync() (chan int, bool) +} + +// Configurator interface. +type Configurator interface { + GetConf() WC + SetConf(WC) +} + +// Wrapper interface. +// If you're implementing custom Decorator by wrapping a built-in one, +// it is necessary to implement this interface to retain functionality +// of built-in Decorator. +type Wrapper interface { + Base() Decorator +} + +// AmountReceiver interface. +// EWMA based decorators need to implement this one. +type AmountReceiver interface { + NextAmount(int64, ...time.Duration) +} + +// ShutdownListener interface. +// If decorator needs to be notified once upon bar shutdown event, so +// this is the right interface to implement. +type ShutdownListener interface { + Shutdown() +} + +// AverageAdjuster interface. +// Average decorators should implement this interface to provide start +// time adjustment facility, for resume-able tasks. +type AverageAdjuster interface { + AverageAdjust(time.Time) +} + +// CBFunc convenience call back func type. +type CBFunc func(Decorator) + +// Global convenience instances of WC with sync width bit set. +var ( + WCSyncWidth = WC{C: DSyncWidth} + WCSyncWidthR = WC{C: DSyncWidthR} + WCSyncSpace = WC{C: DSyncSpace} + WCSyncSpaceR = WC{C: DSyncSpaceR} +) + +// WC is a struct with two public fields W and C, both of int type. +// W represents width and C represents bit set of width related config. +// A decorator should embed WC, to enable width synchronization. +type WC struct { + W int + C int + dynFormat string + staticFormat string + wsync chan int +} + +// FormatMsg formats final message according to WC.W and WC.C. +// Should be called by any Decorator implementation. +func (wc *WC) FormatMsg(msg string) string { + if (wc.C & DSyncWidth) != 0 { + wc.wsync <- utf8.RuneCountInString(msg) + max := <-wc.wsync + if (wc.C & DextraSpace) != 0 { + max++ + } + return fmt.Sprintf(fmt.Sprintf(wc.dynFormat, max), msg) + } + return fmt.Sprintf(wc.staticFormat, msg) +} + +// Init initializes width related config. +func (wc *WC) Init() WC { + wc.dynFormat = "%%" + if (wc.C & DidentRight) != 0 { + wc.dynFormat += "-" + } + wc.dynFormat += "%ds" + wc.staticFormat = fmt.Sprintf(wc.dynFormat, wc.W) + if (wc.C & DSyncWidth) != 0 { + // it's deliberate choice to override wsync on each Init() call, + // this way globals like WCSyncSpace can be reused + wc.wsync = make(chan int) + } + return *wc +} + +// Sync is implementation of Synchronizer interface. +func (wc *WC) Sync() (chan int, bool) { + if (wc.C&DSyncWidth) != 0 && wc.wsync == nil { + panic(fmt.Sprintf("%T is not initialized", wc)) + } + return wc.wsync, (wc.C & DSyncWidth) != 0 +} + +// GetConf is implementation of Configurator interface. +func (wc *WC) GetConf() WC { + return *wc +} + +// SetConf is implementation of Configurator interface. +func (wc *WC) SetConf(conf WC) { + *wc = conf.Init() +} diff --git a/vendor/github.com/vbauerster/mpb/decor/doc.go b/vendor/github.com/vbauerster/mpb/v4/decor/doc.go index 561a8677c..b595e8015 100644 --- a/vendor/github.com/vbauerster/mpb/decor/doc.go +++ b/vendor/github.com/vbauerster/mpb/v4/decor/doc.go @@ -1,9 +1,5 @@ -// Copyright (C) 2016-2018 Vladimir Bauer -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - /* - Package decor contains common decorators used by "github.com/vbauerster/mpb" package. + Package decor provides common decorators for "github.com/vbauerster/mpb/v4" 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 diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/elapsed.go b/vendor/github.com/vbauerster/mpb/v4/decor/elapsed.go new file mode 100644 index 000000000..ac2873143 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/decor/elapsed.go @@ -0,0 +1,48 @@ +package decor + +import ( + "time" +) + +// Elapsed decorator. It's wrapper of NewElapsed. +// +// `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...) +} + +// NewElapsed returns elapsed time decorator. +// +// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS] +// +// `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 + } + 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) +} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/eta.go b/vendor/github.com/vbauerster/mpb/v4/decor/eta.go new file mode 100644 index 000000000..818cded17 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/decor/eta.go @@ -0,0 +1,212 @@ +package decor + +import ( + "fmt" + "math" + "time" + + "github.com/VividCortex/ewma" +) + +// TimeNormalizer interface. Implementors could be passed into +// MovingAverageETA, in order to affect i.e. normalize its output. +type TimeNormalizer interface { + Normalize(time.Duration) time.Duration +} + +// TimeNormalizerFunc is function type adapter to convert function +// into TimeNormalizer. +type TimeNormalizerFunc func(time.Duration) time.Duration + +func (f TimeNormalizerFunc) Normalize(src time.Duration) time.Duration { + return f(src) +} + +// EwmaETA exponential-weighted-moving-average based ETA decorator. +// Note that it's necessary to supply bar.Incr* methods with incremental +// work duration as second argument, in order for this decorator to +// work correctly. This decorator is a wrapper of MovingAverageETA. +func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator { + var average MovingAverage + if age == 0 { + average = ewma.NewMovingAverage() + } else { + average = ewma.NewMovingAverage(age) + } + return MovingAverageETA(style, average, nil, wcc...) +} + +// MovingAverageETA decorator relies on MovingAverage implementation to calculate its average. +// +// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS] +// +// `average` implementation of MovingAverage interface +// +// `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(), + average: average, + normalizer: normalizer, + producer: chooseTimeProducer(style), + } + return d +} + +type movingAverageETA struct { + WC + average ewma.MovingAverage + normalizer TimeNormalizer + producer func(time.Duration) string +} + +func (d *movingAverageETA) Decor(st *Statistics) string { + v := math.Round(d.average.Value()) + remaining := time.Duration((st.Total - st.Current) * int64(v)) + if d.normalizer != nil { + remaining = d.normalizer.Normalize(remaining) + } + return d.FormatMsg(d.producer(remaining)) +} + +func (d *movingAverageETA) NextAmount(n int64, wdd ...time.Duration) { + var workDuration time.Duration + for _, wd := range wdd { + workDuration = wd + } + durPerItem := float64(workDuration) / float64(n) + if math.IsInf(durPerItem, 0) || math.IsNaN(durPerItem) { + return + } + d.average.Add(durPerItem) +} + +// AverageETA decorator. It's wrapper of NewAverageETA. +// +// `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...) +} + +// NewAverageETA decorator with user provided start time. +// +// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS] +// +// `startTime` start time +// +// `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(), + startTime: startTime, + normalizer: normalizer, + producer: chooseTimeProducer(style), + } + return d +} + +type averageETA struct { + WC + startTime time.Time + normalizer TimeNormalizer + producer func(time.Duration) string +} + +func (d *averageETA) Decor(st *Statistics) string { + var remaining time.Duration + if st.Current != 0 { + durPerItem := float64(time.Since(d.startTime)) / float64(st.Current) + durPerItem = math.Round(durPerItem) + remaining = time.Duration((st.Total - st.Current) * int64(durPerItem)) + if d.normalizer != nil { + remaining = d.normalizer.Normalize(remaining) + } + } + return d.FormatMsg(d.producer(remaining)) +} + +func (d *averageETA) AverageAdjust(startTime time.Time) { + d.startTime = startTime +} + +// MaxTolerateTimeNormalizer returns implementation of TimeNormalizer. +func MaxTolerateTimeNormalizer(maxTolerate time.Duration) TimeNormalizer { + var normalized time.Duration + var lastCall time.Time + return TimeNormalizerFunc(func(remaining time.Duration) time.Duration { + if diff := normalized - remaining; diff <= 0 || diff > maxTolerate || remaining < time.Minute { + normalized = remaining + lastCall = time.Now() + return remaining + } + normalized -= time.Since(lastCall) + lastCall = time.Now() + return normalized + }) +} + +// FixedIntervalTimeNormalizer returns implementation of TimeNormalizer. +func FixedIntervalTimeNormalizer(updInterval int) TimeNormalizer { + var normalized time.Duration + var lastCall time.Time + var count int + return TimeNormalizerFunc(func(remaining time.Duration) time.Duration { + if count == 0 || remaining < time.Minute { + count = updInterval + normalized = remaining + lastCall = time.Now() + return remaining + } + count-- + normalized -= time.Since(lastCall) + lastCall = time.Now() + return normalized + }) +} + +func chooseTimeProducer(style TimeStyle) func(time.Duration) string { + switch style { + case ET_STYLE_HHMMSS: + return func(remaining time.Duration) string { + hours := int64(remaining/time.Hour) % 60 + minutes := int64(remaining/time.Minute) % 60 + seconds := int64(remaining/time.Second) % 60 + return fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) + } + case ET_STYLE_HHMM: + return func(remaining time.Duration) string { + hours := int64(remaining/time.Hour) % 60 + minutes := int64(remaining/time.Minute) % 60 + return fmt.Sprintf("%02d:%02d", hours, minutes) + } + case ET_STYLE_MMSS: + return func(remaining time.Duration) string { + hours := int64(remaining/time.Hour) % 60 + minutes := int64(remaining/time.Minute) % 60 + seconds := int64(remaining/time.Second) % 60 + if hours > 0 { + return fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) + } + return fmt.Sprintf("%02d:%02d", minutes, seconds) + } + default: + return func(remaining time.Duration) string { + // strip off nanoseconds + return ((remaining / time.Second) * time.Second).String() + } + } +} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/merge.go b/vendor/github.com/vbauerster/mpb/v4/decor/merge.go new file mode 100644 index 000000000..fdf9e107b --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/decor/merge.go @@ -0,0 +1,97 @@ +package decor + +import ( + "fmt" + "unicode/utf8" +) + +// Merge wraps its decorator argument with intention to sync width +// with several decorators of another bar. Visual example: +// +// +----+--------+---------+--------+ +// | B1 | MERGE(D, P1, Pn) | +// +----+--------+---------+--------+ +// | B2 | D0 | D1 | Dn | +// +----+--------+---------+--------+ +// +func Merge(decorator Decorator, placeholders ...WC) Decorator { + if _, ok := decorator.Sync(); !ok || len(placeholders) == 0 { + return decorator + } + md := &mergeDecorator{ + Decorator: decorator, + wc: decorator.GetConf(), + placeHolders: make([]*placeHolderDecorator, len(placeholders)), + } + decorator.SetConf(WC{}) + for i, wc := range placeholders { + if (wc.C & DSyncWidth) == 0 { + return decorator + } + md.placeHolders[i] = &placeHolderDecorator{ + WC: wc.Init(), + wch: make(chan int), + } + } + return md +} + +type mergeDecorator struct { + Decorator + wc WC + placeHolders []*placeHolderDecorator +} + +func (d *mergeDecorator) GetConf() WC { + return d.wc +} + +func (d *mergeDecorator) SetConf(conf WC) { + d.wc = conf.Init() +} + +func (d *mergeDecorator) MergeUnwrap() []Decorator { + decorators := make([]Decorator, len(d.placeHolders)) + for i, ph := range d.placeHolders { + decorators[i] = ph + } + return decorators +} + +func (d *mergeDecorator) Sync() (chan int, bool) { + return d.wc.Sync() +} + +func (d *mergeDecorator) Base() Decorator { + return d.Decorator +} + +func (d *mergeDecorator) Decor(st *Statistics) string { + msg := d.Decorator.Decor(st) + msgLen := utf8.RuneCountInString(msg) + + var space int + for _, ph := range d.placeHolders { + space += <-ph.wch + } + + d.wc.wsync <- msgLen - space + + max := <-d.wc.wsync + if (d.wc.C & DextraSpace) != 0 { + max++ + } + return fmt.Sprintf(fmt.Sprintf(d.wc.dynFormat, max+space), msg) +} + +type placeHolderDecorator struct { + WC + wch chan int +} + +func (d *placeHolderDecorator) Decor(st *Statistics) string { + go func() { + d.wch <- utf8.RuneCountInString(d.FormatMsg("")) + }() + return "" +} diff --git a/vendor/github.com/vbauerster/mpb/decor/moving-average.go b/vendor/github.com/vbauerster/mpb/v4/decor/moving_average.go index fcd268923..933b1f2cd 100644 --- a/vendor/github.com/vbauerster/mpb/decor/moving-average.go +++ b/vendor/github.com/vbauerster/mpb/v4/decor/moving_average.go @@ -9,11 +9,7 @@ import ( // MovingAverage is the interface that computes a moving average over // a time-series stream of numbers. The average may be over a window // or exponentially decaying. -type MovingAverage interface { - Add(float64) - Value() float64 - Set(float64) -} +type MovingAverage = ewma.MovingAverage type medianWindow [3]float64 @@ -42,26 +38,3 @@ func (s *medianWindow) Set(value float64) { func NewMedian() MovingAverage { return new(medianWindow) } - -type medianEwma struct { - count uint - median MovingAverage - MovingAverage -} - -func (s *medianEwma) Add(v float64) { - s.median.Add(v) - if s.count >= 2 { - s.MovingAverage.Add(s.median.Value()) - } - s.count++ -} - -// NewMedianEwma is ewma based MovingAverage, which gets its values -// from median MovingAverage. -func NewMedianEwma(age ...float64) MovingAverage { - return &medianEwma{ - MovingAverage: ewma.NewMovingAverage(age...), - median: NewMedian(), - } -} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/name.go b/vendor/github.com/vbauerster/mpb/v4/decor/name.go new file mode 100644 index 000000000..2d5865f6c --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/decor/name.go @@ -0,0 +1,27 @@ +package decor + +// Name returns name decorator. +// +// `name` 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) +} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/on_complete.go b/vendor/github.com/vbauerster/mpb/v4/decor/on_complete.go new file mode 100644 index 000000000..714a0ded3 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/decor/on_complete.go @@ -0,0 +1,36 @@ +package decor + +// OnComplete returns decorator, which wraps provided decorator, with +// sole purpose to display provided message on complete event. +// +// `decorator` Decorator to wrap +// +// `message` message to display on complete event +func OnComplete(decorator Decorator, message string) Decorator { + d := &onCompleteWrapper{ + Decorator: decorator, + msg: message, + } + if md, ok := decorator.(*mergeDecorator); ok { + d.Decorator, md.Decorator = md.Decorator, d + return md + } + return d +} + +type onCompleteWrapper struct { + Decorator + msg string +} + +func (d *onCompleteWrapper) Decor(st *Statistics) string { + if st.Completed { + wc := d.GetConf() + return wc.FormatMsg(d.msg) + } + return d.Decorator.Decor(st) +} + +func (d *onCompleteWrapper) Base() Decorator { + return d.Decorator +} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/percentage.go b/vendor/github.com/vbauerster/mpb/v4/decor/percentage.go new file mode 100644 index 000000000..abf343a35 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/decor/percentage.go @@ -0,0 +1,72 @@ +package decor + +import ( + "fmt" + "io" + "strconv" + + "github.com/vbauerster/mpb/v4/internal" +) + +type percentageType float64 + +func (s percentageType) Format(st fmt.State, verb rune) { + var prec int + switch verb { + case 'd': + case 's': + prec = -1 + default: + if p, ok := st.Precision(); ok { + prec = p + } else { + prec = 6 + } + } + + io.WriteString(st, strconv.FormatFloat(float64(s), 'f', prec, 64)) + + if st.Flag(' ') { + io.WriteString(st, " ") + } + io.WriteString(st, "%") +} + +// Percentage returns percentage decorator. It's a wrapper of NewPercentage. +func Percentage(wcc ...WC) Decorator { + return NewPercentage("% d", wcc...) +} + +// NewPercentage percentage decorator with custom fmt string. +// +// fmt examples: +// +// fmt="%.1f" output: "1.0%" +// fmt="% .1f" output: "1.0 %" +// fmt="%d" output: "1%" +// fmt="% d" output: "1 %" +// +func NewPercentage(fmt string, wcc ...WC) Decorator { + var wc WC + for _, widthConf := range wcc { + wc = widthConf + } + if fmt == "" { + fmt = "% d" + } + 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))) +} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/size_type.go b/vendor/github.com/vbauerster/mpb/v4/decor/size_type.go new file mode 100644 index 000000000..e4b974058 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/decor/size_type.go @@ -0,0 +1,109 @@ +package decor + +import ( + "fmt" + "io" + "math" + "strconv" +) + +//go:generate stringer -type=SizeB1024 -trimprefix=_i +//go:generate stringer -type=SizeB1000 -trimprefix=_ + +const ( + _ib SizeB1024 = iota + 1 + _iKiB SizeB1024 = 1 << (iota * 10) + _iMiB + _iGiB + _iTiB +) + +// SizeB1024 named type, which implements fmt.Formatter interface. It +// adjusts its value according to byte size multiple by 1024 and appends +// appropriate size marker (KiB, MiB, GiB, TiB). +type SizeB1024 int64 + +func (self SizeB1024) Format(st fmt.State, verb rune) { + var prec int + switch verb { + case 'd': + case 's': + prec = -1 + default: + if p, ok := st.Precision(); ok { + prec = p + } else { + prec = 6 + } + } + + var unit SizeB1024 + switch { + case self < _iKiB: + unit = _ib + case self < _iMiB: + unit = _iKiB + case self < _iGiB: + unit = _iMiB + case self < _iTiB: + unit = _iGiB + case self <= math.MaxInt64: + unit = _iTiB + } + + io.WriteString(st, strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64)) + + if st.Flag(' ') { + io.WriteString(st, " ") + } + io.WriteString(st, unit.String()) +} + +const ( + _b SizeB1000 = 1 + _KB SizeB1000 = _b * 1000 + _MB SizeB1000 = _KB * 1000 + _GB SizeB1000 = _MB * 1000 + _TB SizeB1000 = _GB * 1000 +) + +// SizeB1000 named type, which implements fmt.Formatter interface. It +// adjusts its value according to byte size multiple by 1000 and appends +// appropriate size marker (KB, MB, GB, TB). +type SizeB1000 int64 + +func (self SizeB1000) Format(st fmt.State, verb rune) { + var prec int + switch verb { + case 'd': + case 's': + prec = -1 + default: + if p, ok := st.Precision(); ok { + prec = p + } else { + prec = 6 + } + } + + var unit SizeB1000 + switch { + case self < _KB: + unit = _b + case self < _MB: + unit = _KB + case self < _GB: + unit = _MB + case self < _TB: + unit = _GB + case self <= math.MaxInt64: + unit = _TB + } + + io.WriteString(st, strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64)) + + if st.Flag(' ') { + io.WriteString(st, " ") + } + io.WriteString(st, unit.String()) +} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/sizeb1000_string.go b/vendor/github.com/vbauerster/mpb/v4/decor/sizeb1000_string.go new file mode 100644 index 000000000..3f32ef715 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/decor/sizeb1000_string.go @@ -0,0 +1,41 @@ +// Code generated by "stringer -type=SizeB1000 -trimprefix=_"; DO NOT EDIT. + +package decor + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[_b-1] + _ = x[_KB-1000] + _ = x[_MB-1000000] + _ = x[_GB-1000000000] + _ = x[_TB-1000000000000] +} + +const ( + _SizeB1000_name_0 = "b" + _SizeB1000_name_1 = "KB" + _SizeB1000_name_2 = "MB" + _SizeB1000_name_3 = "GB" + _SizeB1000_name_4 = "TB" +) + +func (i SizeB1000) String() string { + switch { + case i == 1: + return _SizeB1000_name_0 + case i == 1000: + return _SizeB1000_name_1 + case i == 1000000: + return _SizeB1000_name_2 + case i == 1000000000: + return _SizeB1000_name_3 + case i == 1000000000000: + return _SizeB1000_name_4 + default: + return "SizeB1000(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/sizeb1024_string.go b/vendor/github.com/vbauerster/mpb/v4/decor/sizeb1024_string.go new file mode 100644 index 000000000..9fca66cc7 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/decor/sizeb1024_string.go @@ -0,0 +1,41 @@ +// Code generated by "stringer -type=SizeB1024 -trimprefix=_i"; DO NOT EDIT. + +package decor + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[_ib-1] + _ = x[_iKiB-1024] + _ = x[_iMiB-1048576] + _ = x[_iGiB-1073741824] + _ = x[_iTiB-1099511627776] +} + +const ( + _SizeB1024_name_0 = "b" + _SizeB1024_name_1 = "KiB" + _SizeB1024_name_2 = "MiB" + _SizeB1024_name_3 = "GiB" + _SizeB1024_name_4 = "TiB" +) + +func (i SizeB1024) String() string { + switch { + case i == 1: + return _SizeB1024_name_0 + case i == 1024: + return _SizeB1024_name_1 + case i == 1048576: + return _SizeB1024_name_2 + case i == 1073741824: + return _SizeB1024_name_3 + case i == 1099511627776: + return _SizeB1024_name_4 + default: + return "SizeB1024(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/speed.go b/vendor/github.com/vbauerster/mpb/v4/decor/speed.go new file mode 100644 index 000000000..795a5536f --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/decor/speed.go @@ -0,0 +1,175 @@ +package decor + +import ( + "fmt" + "io" + "math" + "time" + + "github.com/VividCortex/ewma" +) + +// SpeedFormatter is wrapper for SizeB1024 and SizeB1000 to format value as speed/s. +type SpeedFormatter struct { + fmt.Formatter +} + +func (self *SpeedFormatter) Format(st fmt.State, verb rune) { + self.Formatter.Format(st, verb) + io.WriteString(st, "/s") +} + +// EwmaSpeed exponential-weighted-moving-average based speed decorator. +// Note that it's necessary to supply bar.Incr* methods with incremental +// work duration as second argument, in order for this decorator to +// work correctly. This decorator is a wrapper of MovingAverageSpeed. +func EwmaSpeed(unit int, format string, age float64, wcc ...WC) Decorator { + var average MovingAverage + if age == 0 { + average = ewma.NewMovingAverage() + } else { + average = ewma.NewMovingAverage(age) + } + return MovingAverageSpeed(unit, format, average, wcc...) +} + +// MovingAverageSpeed decorator relies on MovingAverage implementation +// to calculate its average. +// +// `unit` one of [0|UnitKiB|UnitKB] zero for no unit +// +// `format` printf compatible verb for value, like "%f" or "%d" +// +// `average` MovingAverage implementation +// +// `wcc` optional WC config +// +// format examples: +// +// unit=UnitKiB, format="%.1f" output: "1.0MiB/s" +// unit=UnitKiB, format="% .1f" output: "1.0 MiB/s" +// unit=UnitKB, format="%.1f" output: "1.0MB/s" +// 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(), + average: average, + producer: chooseSpeedProducer(unit, format), + } + return d +} + +type movingAverageSpeed struct { + WC + producer func(float64) string + average ewma.MovingAverage + msg string +} + +func (d *movingAverageSpeed) Decor(st *Statistics) string { + if !st.Completed { + var speed float64 + if v := d.average.Value(); v > 0 { + speed = 1 / v + } + d.msg = d.producer(speed * 1e9) + } + return d.FormatMsg(d.msg) +} + +func (d *movingAverageSpeed) NextAmount(n int64, wdd ...time.Duration) { + var workDuration time.Duration + for _, wd := range wdd { + workDuration = wd + } + durPerByte := float64(workDuration) / float64(n) + if math.IsInf(durPerByte, 0) || math.IsNaN(durPerByte) { + return + } + d.average.Add(durPerByte) +} + +// AverageSpeed decorator with dynamic unit measure adjustment. It's +// a wrapper of NewAverageSpeed. +func AverageSpeed(unit int, format string, wcc ...WC) Decorator { + return NewAverageSpeed(unit, format, time.Now(), wcc...) +} + +// NewAverageSpeed decorator with dynamic unit measure adjustment and +// user provided start time. +// +// `unit` one of [0|UnitKiB|UnitKB] zero for no unit +// +// `format` printf compatible verb for value, like "%f" or "%d" +// +// `startTime` start time +// +// `wcc` optional WC config +// +// format examples: +// +// unit=UnitKiB, format="%.1f" output: "1.0MiB/s" +// unit=UnitKiB, format="% .1f" output: "1.0 MiB/s" +// unit=UnitKB, format="%.1f" output: "1.0MB/s" +// 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(), + startTime: startTime, + producer: chooseSpeedProducer(unit, format), + } + return d +} + +type averageSpeed struct { + WC + startTime time.Time + producer func(float64) string + msg string +} + +func (d *averageSpeed) Decor(st *Statistics) string { + if !st.Completed { + speed := float64(st.Current) / float64(time.Since(d.startTime)) + d.msg = d.producer(speed * 1e9) + } + + return d.FormatMsg(d.msg) +} + +func (d *averageSpeed) AverageAdjust(startTime time.Time) { + d.startTime = startTime +} + +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))}) + } + case UnitKB: + return func(speed float64) string { + return fmt.Sprintf(format, &SpeedFormatter{SizeB1000(math.Round(speed))}) + } + default: + return func(speed float64) string { + return fmt.Sprintf(format, speed) + } + } +} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/spinner.go b/vendor/github.com/vbauerster/mpb/v4/decor/spinner.go new file mode 100644 index 000000000..24f553142 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/decor/spinner.go @@ -0,0 +1,35 @@ +package decor + +var defaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"} + +// Spinner returns spinner decorator. +// +// `frames` spinner frames, if nil or len==0, default is used +// +// `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, + } + 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) +} diff --git a/vendor/github.com/vbauerster/mpb/v4/doc.go b/vendor/github.com/vbauerster/mpb/v4/doc.go new file mode 100644 index 000000000..5ada71774 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/doc.go @@ -0,0 +1,2 @@ +// Package mpb is a library for rendering progress bars in terminal applications. +package mpb diff --git a/vendor/github.com/vbauerster/mpb/v4/go.mod b/vendor/github.com/vbauerster/mpb/v4/go.mod new file mode 100644 index 000000000..0c5ce51f1 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/go.mod @@ -0,0 +1,9 @@ +module github.com/vbauerster/mpb/v4 + +require ( + github.com/VividCortex/ewma v1.1.1 + golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708 + golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 // indirect +) + +go 1.13 diff --git a/vendor/github.com/vbauerster/mpb/v4/go.sum b/vendor/github.com/vbauerster/mpb/v4/go.sum new file mode 100644 index 000000000..94a9f1a28 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/go.sum @@ -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= +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/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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/vendor/github.com/vbauerster/mpb/v4/internal/percentage.go b/vendor/github.com/vbauerster/mpb/v4/internal/percentage.go new file mode 100644 index 000000000..7e261cb22 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/internal/percentage.go @@ -0,0 +1,15 @@ +package internal + +import "math" + +// Percentage is a helper function, to calculate percentage. +func Percentage(total, current int64, width int) float64 { + if total <= 0 { + return 0 + } + return float64(int64(width)*current) / float64(total) +} + +func PercentageRound(total, current int64, width int) float64 { + return math.Round(Percentage(total, current, width)) +} diff --git a/vendor/github.com/vbauerster/mpb/v4/options.go b/vendor/github.com/vbauerster/mpb/v4/options.go new file mode 100644 index 000000000..6b34fb340 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/options.go @@ -0,0 +1,105 @@ +package mpb + +import ( + "io" + "io/ioutil" + "sync" + "time" +) + +// ContainerOption is a function option which changes the default +// behavior of progress container, if passed to mpb.New(...ContainerOption). +type ContainerOption func(*pState) + +// WithWaitGroup provides means to have a single joint point. If +// *sync.WaitGroup is provided, you can safely call just p.Wait() +// without calling Wait() on provided *sync.WaitGroup. Makes sense +// when there are more than one bar to render. +func WithWaitGroup(wg *sync.WaitGroup) ContainerOption { + return func(s *pState) { + s.uwg = wg + } +} + +// WithWidth sets container width. Default is 80. Bars inherit this +// width, as long as no BarWidth is applied. +func WithWidth(w int) ContainerOption { + return func(s *pState) { + if w < 0 { + return + } + s.width = w + } +} + +// WithRefreshRate overrides default 120ms refresh rate. +func WithRefreshRate(d time.Duration) ContainerOption { + return func(s *pState) { + s.rr = d + } +} + +// WithManualRefresh disables internal auto refresh time.Ticker. +// Refresh will occur upon receive value from provided ch. +func WithManualRefresh(ch <-chan time.Time) ContainerOption { + return func(s *pState) { + s.refreshSrc = ch + } +} + +// WithRenderDelay delays rendering. By default rendering starts as +// soon as bar is added, with this option it's possible to delay +// rendering process by keeping provided chan unclosed. In other words +// rendering will start as soon as provided chan is closed. +func WithRenderDelay(ch <-chan struct{}) ContainerOption { + return func(s *pState) { + s.renderDelay = ch + } +} + +// WithShutdownNotifier provided chanel will be closed, after all bars +// have been rendered. +func WithShutdownNotifier(ch chan struct{}) ContainerOption { + return func(s *pState) { + s.shutdownNotifier = ch + } +} + +// WithOutput overrides default os.Stdout output. Setting it to nil +// will effectively disable auto refresh rate and discard any output, +// useful if you want to disable progress bars with little overhead. +func WithOutput(w io.Writer) ContainerOption { + return func(s *pState) { + if w == nil { + s.refreshSrc = make(chan time.Time) + s.output = ioutil.Discard + return + } + s.output = w + } +} + +// WithDebugOutput sets debug output. +func WithDebugOutput(w io.Writer) ContainerOption { + if w == nil { + return nil + } + return func(s *pState) { + s.debugOut = w + } +} + +// PopCompletedMode will pop and stop rendering completed bars. +func PopCompletedMode() ContainerOption { + return func(s *pState) { + s.popCompleted = true + } +} + +// ContainerOptOnCond returns option when condition evaluates to true. +func ContainerOptOnCond(option ContainerOption, condition func() bool) ContainerOption { + if condition() { + return option + } + return nil +} diff --git a/vendor/github.com/vbauerster/mpb/priority_queue.go b/vendor/github.com/vbauerster/mpb/v4/priority_queue.go index 7bc588c29..29d9bd5a8 100644 --- a/vendor/github.com/vbauerster/mpb/priority_queue.go +++ b/vendor/github.com/vbauerster/mpb/v4/priority_queue.go @@ -1,7 +1,5 @@ package mpb -import "container/heap" - // A priorityQueue implements heap.Interface type priorityQueue []*Bar @@ -18,23 +16,17 @@ func (pq priorityQueue) Swap(i, j int) { } func (pq *priorityQueue) Push(x interface{}) { - n := len(*pq) + s := *pq bar := x.(*Bar) - bar.index = n - *pq = append(*pq, bar) + bar.index = len(s) + s = append(s, bar) + *pq = s } func (pq *priorityQueue) Pop() interface{} { - old := *pq - n := len(old) - bar := old[n-1] + s := *pq + *pq = s[0 : len(s)-1] + bar := s[len(s)-1] bar.index = -1 // for safety - *pq = old[0 : n-1] return bar } - -// update modifies the priority of a Bar in the queue. -func (pq *priorityQueue) update(bar *Bar, priority int) { - bar.priority = priority - heap.Fix(pq, bar.index) -} diff --git a/vendor/github.com/vbauerster/mpb/v4/progress.go b/vendor/github.com/vbauerster/mpb/v4/progress.go new file mode 100644 index 000000000..1150d50bd --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/progress.go @@ -0,0 +1,394 @@ +package mpb + +import ( + "bytes" + "container/heap" + "context" + "io" + "io/ioutil" + "log" + "os" + "sync" + "time" + + "github.com/vbauerster/mpb/v4/cwriter" + "github.com/vbauerster/mpb/v4/decor" +) + +const ( + // default RefreshRate + prr = 120 * time.Millisecond + // default width + pwidth = 80 +) + +// Progress represents the container that renders Progress bars +type Progress struct { + ctx context.Context + uwg *sync.WaitGroup + cwg *sync.WaitGroup + bwg *sync.WaitGroup + operateState chan func(*pState) + done chan struct{} + refreshCh chan time.Time + once sync.Once + dlogger *log.Logger +} + +type pState struct { + bHeap priorityQueue + heapUpdated bool + pMatrix map[int][]chan int + aMatrix map[int][]chan int + barShutdownQueue []*Bar + barPopQueue []*Bar + + // following are provided/overrided by user + idCount int + width int + popCompleted bool + rr time.Duration + uwg *sync.WaitGroup + refreshSrc <-chan time.Time + renderDelay <-chan struct{} + shutdownNotifier chan struct{} + parkedBars map[*Bar]*Bar + output io.Writer + debugOut io.Writer +} + +// New creates new Progress container instance. It's not possible to +// reuse instance after *Progress.Wait() method has been called. +func New(options ...ContainerOption) *Progress { + return NewWithContext(context.Background(), options...) +} + +// NewWithContext creates new Progress container instance with provided +// context. It's not possible to reuse instance after *Progress.Wait() +// method has been called. +func NewWithContext(ctx context.Context, options ...ContainerOption) *Progress { + s := &pState{ + bHeap: priorityQueue{}, + width: pwidth, + rr: prr, + parkedBars: make(map[*Bar]*Bar), + output: os.Stdout, + debugOut: ioutil.Discard, + } + + for _, opt := range options { + if opt != nil { + opt(s) + } + } + + p := &Progress{ + ctx: ctx, + uwg: s.uwg, + cwg: new(sync.WaitGroup), + bwg: new(sync.WaitGroup), + operateState: make(chan func(*pState)), + done: make(chan struct{}), + dlogger: log.New(s.debugOut, "[mpb] ", log.Lshortfile), + } + + p.cwg.Add(1) + go p.serve(s, cwriter.New(s.output)) + return p +} + +// AddBar creates a new progress bar and adds to the container. +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. +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. +func (p *Progress) Add(total int64, filler Filler, options ...BarOption) *Bar { + if filler == nil { + filler = NewBarFiller(DefaultBarStyle, false) + } + p.bwg.Add(1) + result := make(chan *Bar) + select { + case p.operateState <- func(ps *pState) { + bs := ps.makeBarState(total, filler, options...) + bar := newBar(p, bs) + if bs.runningBar != nil { + bs.runningBar.noPop = true + ps.parkedBars[bs.runningBar] = bar + } else { + heap.Push(&ps.bHeap, bar) + ps.heapUpdated = true + } + ps.idCount++ + result <- bar + }: + bar := <-result + bar.subscribeDecorators() + return bar + case <-p.done: + p.bwg.Done() + return nil + } +} + +func (p *Progress) dropBar(b *Bar) { + select { + case p.operateState <- func(s *pState) { + if b.index < 0 { + return + } + heap.Remove(&s.bHeap, b.index) + s.heapUpdated = true + }: + case <-p.done: + } +} + +func (p *Progress) setBarPriority(b *Bar, priority int) { + select { + case p.operateState <- func(s *pState) { + if b.index < 0 { + return + } + b.priority = priority + heap.Fix(&s.bHeap, b.index) + }: + case <-p.done: + } +} + +// UpdateBarPriority same as *Bar.SetPriority. +func (p *Progress) UpdateBarPriority(b *Bar, priority int) { + p.setBarPriority(b, priority) +} + +// BarCount returns bars count +func (p *Progress) BarCount() int { + result := make(chan int, 1) + select { + case p.operateState <- func(s *pState) { result <- s.bHeap.Len() }: + return <-result + case <-p.done: + return 0 + } +} + +// Wait waits far all bars to complete and finally shutdowns container. +// After this method has been called, there is no way to reuse *Progress +// instance. +func (p *Progress) Wait() { + if p.uwg != nil { + // wait for user wg + p.uwg.Wait() + } + + // wait for bars to quit, if any + p.bwg.Wait() + + p.once.Do(p.shutdown) + + // wait for container to quit + p.cwg.Wait() +} + +func (p *Progress) shutdown() { + close(p.done) +} + +func (p *Progress) serve(s *pState, cw *cwriter.Writer) { + defer p.cwg.Done() + + p.refreshCh = s.newTicker(p.done) + + for { + select { + case op := <-p.operateState: + op(s) + case <-p.refreshCh: + if err := s.render(cw); err != nil { + go p.dlogger.Println(err) + } + case <-s.shutdownNotifier: + return + } + } +} + +func (s *pState) render(cw *cwriter.Writer) error { + if s.heapUpdated { + s.updateSyncMatrix() + s.heapUpdated = false + } + syncWidth(s.pMatrix) + syncWidth(s.aMatrix) + + tw, err := cw.GetWidth() + if err != nil { + tw = s.width + } + for i := 0; i < s.bHeap.Len(); i++ { + bar := s.bHeap[i] + go bar.render(tw) + } + + return s.flush(cw) +} + +func (s *pState) flush(cw *cwriter.Writer) error { + var lineCount int + bm := make(map[*Bar]struct{}, s.bHeap.Len()) + for s.bHeap.Len() > 0 { + b := heap.Pop(&s.bHeap).(*Bar) + cw.ReadFrom(<-b.frameCh) + if b.toShutdown { + // shutdown at next flush + // this ensures no bar ends up with less than 100% rendered + defer func() { + s.barShutdownQueue = append(s.barShutdownQueue, b) + }() + } + lineCount += b.extendedLines + 1 + bm[b] = struct{}{} + } + + for _, b := range s.barShutdownQueue { + if parkedBar := s.parkedBars[b]; parkedBar != nil { + parkedBar.priority = b.priority + heap.Push(&s.bHeap, parkedBar) + delete(s.parkedBars, b) + b.toDrop = true + } + if b.toDrop { + delete(bm, b) + s.heapUpdated = true + } else if s.popCompleted { + if b := b; !b.noPop { + defer func() { + s.barPopQueue = append(s.barPopQueue, b) + }() + } + } + b.cancel() + } + s.barShutdownQueue = s.barShutdownQueue[0:0] + + for _, b := range s.barPopQueue { + delete(bm, b) + s.heapUpdated = true + lineCount -= b.extendedLines + 1 + } + s.barPopQueue = s.barPopQueue[0:0] + + for b := range bm { + heap.Push(&s.bHeap, b) + } + + return cw.Flush(lineCount) +} + +func (s *pState) newTicker(done <-chan struct{}) chan time.Time { + ch := make(chan time.Time) + if s.shutdownNotifier == nil { + s.shutdownNotifier = make(chan struct{}) + } + go func() { + if s.renderDelay != nil { + <-s.renderDelay + } + if s.refreshSrc == nil { + ticker := time.NewTicker(s.rr) + defer ticker.Stop() + s.refreshSrc = ticker.C + } + for { + select { + case tick := <-s.refreshSrc: + ch <- tick + case <-done: + close(s.shutdownNotifier) + return + } + } + }() + return ch +} + +func (s *pState) updateSyncMatrix() { + s.pMatrix = make(map[int][]chan int) + s.aMatrix = make(map[int][]chan int) + for i := 0; i < s.bHeap.Len(); i++ { + bar := s.bHeap[i] + table := bar.wSyncTable() + pRow, aRow := table[0], table[1] + + for i, ch := range pRow { + s.pMatrix[i] = append(s.pMatrix[i], ch) + } + + for i, ch := range aRow { + s.aMatrix[i] = append(s.aMatrix[i], ch) + } + } +} + +func (s *pState) makeBarState(total int64, filler Filler, options ...BarOption) *bState { + bs := &bState{ + total: total, + baseF: extractBaseFiller(filler), + filler: filler, + priority: s.idCount, + id: s.idCount, + width: s.width, + debugOut: s.debugOut, + extender: func(r io.Reader, _ int, _ *decor.Statistics) (io.Reader, int) { + return r, 0 + }, + } + + for _, opt := range options { + if opt != nil { + opt(bs) + } + } + + if s.popCompleted && !bs.noPop { + bs.priority = -1 + } + + bs.bufP = bytes.NewBuffer(make([]byte, 0, bs.width)) + bs.bufB = bytes.NewBuffer(make([]byte, 0, bs.width)) + bs.bufA = bytes.NewBuffer(make([]byte, 0, bs.width)) + + return bs +} + +func syncWidth(matrix map[int][]chan int) { + for _, column := range matrix { + column := column + go func() { + var maxWidth int + for _, ch := range column { + if w := <-ch; w > maxWidth { + maxWidth = w + } + } + for _, ch := range column { + ch <- maxWidth + } + }() + } +} + +func extractBaseFiller(f Filler) Filler { + if f, ok := f.(Wrapper); ok { + return extractBaseFiller(f.Base()) + } + return f +} diff --git a/vendor/github.com/vbauerster/mpb/v4/proxyreader.go b/vendor/github.com/vbauerster/mpb/v4/proxyreader.go new file mode 100644 index 000000000..736142412 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v4/proxyreader.go @@ -0,0 +1,45 @@ +package mpb + +import ( + "io" + "time" +) + +type proxyReader struct { + io.ReadCloser + bar *Bar + iT time.Time +} + +func (prox *proxyReader) Read(p []byte) (n int, err error) { + n, err = prox.ReadCloser.Read(p) + if n > 0 { + prox.bar.IncrBy(n, time.Since(prox.iT)) + prox.iT = time.Now() + } + if err == io.EOF { + go func() { + prox.bar.SetTotal(0, true) + }() + } + return +} + +type proxyWriterTo struct { + *proxyReader + wt io.WriterTo +} + +func (prox *proxyWriterTo) WriteTo(w io.Writer) (n int64, err error) { + n, err = prox.wt.WriteTo(w) + if n > 0 { + prox.bar.IncrInt64(n, time.Since(prox.iT)) + prox.iT = time.Now() + } + if err == io.EOF { + go func() { + prox.bar.SetTotal(0, true) + }() + } + return +} diff --git a/vendor/github.com/vbauerster/mpb/spinner_filler.go b/vendor/github.com/vbauerster/mpb/v4/spinner_filler.go index 36299fef0..9f383fb33 100644 --- a/vendor/github.com/vbauerster/mpb/spinner_filler.go +++ b/vendor/github.com/vbauerster/mpb/v4/spinner_filler.go @@ -5,7 +5,7 @@ import ( "strings" "unicode/utf8" - "github.com/vbauerster/mpb/decor" + "github.com/vbauerster/mpb/v4/decor" ) // SpinnerAlignment enum. @@ -18,7 +18,8 @@ const ( SpinnerOnRight ) -var defaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"} +// DefaultSpinnerStyle is applied when bar constructed with *Progress.AddSpinner method. +var DefaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"} type spinnerFiller struct { frames []string @@ -26,6 +27,18 @@ type spinnerFiller struct { alignment SpinnerAlignment } +// NewSpinnerFiller constucts mpb.Filler, to be used with *Progress.Add method. +func NewSpinnerFiller(style []string, alignment SpinnerAlignment) Filler { + if len(style) == 0 { + style = DefaultSpinnerStyle + } + filler := &spinnerFiller{ + frames: style, + alignment: alignment, + } + return filler +} + func (s *spinnerFiller) Fill(w io.Writer, width int, stat *decor.Statistics) { frame := s.frames[s.count%uint(len(s.frames))] |