From 42fcdbf1a85c8e23ccc25a0e7e66b3a51b8f11dd Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Tue, 7 Apr 2020 12:09:48 +0200 Subject: vendor c/image v5.4.2 Signed-off-by: Valentin Rothberg --- vendor/github.com/vbauerster/mpb/v4/.gitignore | 5 - vendor/github.com/vbauerster/mpb/v4/.travis.yml | 12 - vendor/github.com/vbauerster/mpb/v4/README.md | 118 ----- vendor/github.com/vbauerster/mpb/v4/UNLICENSE | 24 -- vendor/github.com/vbauerster/mpb/v4/bar.go | 477 --------------------- vendor/github.com/vbauerster/mpb/v4/bar_filler.go | 138 ------ vendor/github.com/vbauerster/mpb/v4/bar_option.go | 208 --------- .../github.com/vbauerster/mpb/v4/cwriter/writer.go | 71 --- .../vbauerster/mpb/v4/cwriter/writer_posix.go | 9 - .../vbauerster/mpb/v4/cwriter/writer_windows.go | 60 --- vendor/github.com/vbauerster/mpb/v4/decor/any.go | 21 - .../github.com/vbauerster/mpb/v4/decor/counters.go | 67 --- .../vbauerster/mpb/v4/decor/decorator.go | 186 -------- vendor/github.com/vbauerster/mpb/v4/decor/doc.go | 21 - .../github.com/vbauerster/mpb/v4/decor/elapsed.go | 35 -- vendor/github.com/vbauerster/mpb/v4/decor/eta.go | 207 --------- vendor/github.com/vbauerster/mpb/v4/decor/merge.go | 106 ----- .../vbauerster/mpb/v4/decor/moving_average.go | 73 ---- vendor/github.com/vbauerster/mpb/v4/decor/name.go | 12 - .../vbauerster/mpb/v4/decor/on_complete.go | 37 -- .../vbauerster/mpb/v4/decor/percentage.go | 58 --- .../vbauerster/mpb/v4/decor/size_type.go | 109 ----- .../vbauerster/mpb/v4/decor/sizeb1000_string.go | 41 -- .../vbauerster/mpb/v4/decor/sizeb1024_string.go | 41 -- vendor/github.com/vbauerster/mpb/v4/decor/speed.go | 175 -------- .../github.com/vbauerster/mpb/v4/decor/spinner.go | 21 - vendor/github.com/vbauerster/mpb/v4/doc.go | 2 - vendor/github.com/vbauerster/mpb/v4/go.mod | 10 - vendor/github.com/vbauerster/mpb/v4/go.sum | 13 - .../vbauerster/mpb/v4/internal/percentage.go | 15 - vendor/github.com/vbauerster/mpb/v4/options.go | 105 ----- .../github.com/vbauerster/mpb/v4/priority_queue.go | 32 -- vendor/github.com/vbauerster/mpb/v4/progress.go | 396 ----------------- vendor/github.com/vbauerster/mpb/v4/proxyreader.go | 41 -- .../github.com/vbauerster/mpb/v4/spinner_filler.go | 61 --- vendor/github.com/vbauerster/mpb/v5/.gitignore | 5 + vendor/github.com/vbauerster/mpb/v5/.travis.yml | 8 + vendor/github.com/vbauerster/mpb/v5/README.md | 118 +++++ vendor/github.com/vbauerster/mpb/v5/UNLICENSE | 24 ++ vendor/github.com/vbauerster/mpb/v5/bar.go | 476 ++++++++++++++++++++ vendor/github.com/vbauerster/mpb/v5/bar_filler.go | 138 ++++++ vendor/github.com/vbauerster/mpb/v5/bar_option.go | 204 +++++++++ .../github.com/vbauerster/mpb/v5/cwriter/writer.go | 71 +++ .../vbauerster/mpb/v5/cwriter/writer_posix.go | 9 + .../vbauerster/mpb/v5/cwriter/writer_windows.go | 60 +++ vendor/github.com/vbauerster/mpb/v5/decor/any.go | 21 + .../github.com/vbauerster/mpb/v5/decor/counters.go | 67 +++ .../vbauerster/mpb/v5/decor/decorator.go | 184 ++++++++ vendor/github.com/vbauerster/mpb/v5/decor/doc.go | 21 + .../github.com/vbauerster/mpb/v5/decor/elapsed.go | 35 ++ vendor/github.com/vbauerster/mpb/v5/decor/eta.go | 203 +++++++++ vendor/github.com/vbauerster/mpb/v5/decor/merge.go | 106 +++++ .../vbauerster/mpb/v5/decor/moving_average.go | 68 +++ vendor/github.com/vbauerster/mpb/v5/decor/name.go | 12 + .../vbauerster/mpb/v5/decor/on_complete.go | 37 ++ .../vbauerster/mpb/v5/decor/percentage.go | 58 +++ .../vbauerster/mpb/v5/decor/size_type.go | 109 +++++ .../vbauerster/mpb/v5/decor/sizeb1000_string.go | 41 ++ .../vbauerster/mpb/v5/decor/sizeb1024_string.go | 41 ++ vendor/github.com/vbauerster/mpb/v5/decor/speed.go | 171 ++++++++ .../github.com/vbauerster/mpb/v5/decor/spinner.go | 21 + vendor/github.com/vbauerster/mpb/v5/doc.go | 2 + vendor/github.com/vbauerster/mpb/v5/go.mod | 10 + vendor/github.com/vbauerster/mpb/v5/go.sum | 13 + .../vbauerster/mpb/v5/internal/percentage.go | 15 + vendor/github.com/vbauerster/mpb/v5/options.go | 105 +++++ .../github.com/vbauerster/mpb/v5/priority_queue.go | 32 ++ vendor/github.com/vbauerster/mpb/v5/progress.go | 399 +++++++++++++++++ vendor/github.com/vbauerster/mpb/v5/proxyreader.go | 90 ++++ .../github.com/vbauerster/mpb/v5/spinner_filler.go | 61 +++ 70 files changed, 3035 insertions(+), 3007 deletions(-) delete mode 100644 vendor/github.com/vbauerster/mpb/v4/.gitignore delete mode 100644 vendor/github.com/vbauerster/mpb/v4/.travis.yml delete mode 100644 vendor/github.com/vbauerster/mpb/v4/README.md delete mode 100644 vendor/github.com/vbauerster/mpb/v4/UNLICENSE delete mode 100644 vendor/github.com/vbauerster/mpb/v4/bar.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/bar_filler.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/bar_option.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/cwriter/writer.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/cwriter/writer_posix.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/cwriter/writer_windows.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/any.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/counters.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/decorator.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/doc.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/elapsed.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/eta.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/merge.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/moving_average.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/name.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/on_complete.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/percentage.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/size_type.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/sizeb1000_string.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/sizeb1024_string.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/speed.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/decor/spinner.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/doc.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/go.mod delete mode 100644 vendor/github.com/vbauerster/mpb/v4/go.sum delete mode 100644 vendor/github.com/vbauerster/mpb/v4/internal/percentage.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/options.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/priority_queue.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/progress.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/proxyreader.go delete mode 100644 vendor/github.com/vbauerster/mpb/v4/spinner_filler.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/.gitignore create mode 100644 vendor/github.com/vbauerster/mpb/v5/.travis.yml create mode 100644 vendor/github.com/vbauerster/mpb/v5/README.md create mode 100644 vendor/github.com/vbauerster/mpb/v5/UNLICENSE create mode 100644 vendor/github.com/vbauerster/mpb/v5/bar.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/bar_filler.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/bar_option.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/cwriter/writer.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/cwriter/writer_posix.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/cwriter/writer_windows.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/any.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/counters.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/decorator.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/doc.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/elapsed.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/eta.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/merge.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/moving_average.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/name.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/on_complete.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/percentage.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/size_type.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/sizeb1000_string.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/sizeb1024_string.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/speed.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/decor/spinner.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/doc.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/go.mod create mode 100644 vendor/github.com/vbauerster/mpb/v5/go.sum create mode 100644 vendor/github.com/vbauerster/mpb/v5/internal/percentage.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/options.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/priority_queue.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/progress.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/proxyreader.go create mode 100644 vendor/github.com/vbauerster/mpb/v5/spinner_filler.go (limited to 'vendor/github.com/vbauerster') diff --git a/vendor/github.com/vbauerster/mpb/v4/.gitignore b/vendor/github.com/vbauerster/mpb/v4/.gitignore deleted file mode 100644 index 63bd91672..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out diff --git a/vendor/github.com/vbauerster/mpb/v4/.travis.yml b/vendor/github.com/vbauerster/mpb/v4/.travis.yml deleted file mode 100644 index 997ae32d6..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -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/v4/README.md b/vendor/github.com/vbauerster/mpb/v4/README.md deleted file mode 100644 index 003fb5987..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/README.md +++ /dev/null @@ -1,118 +0,0 @@ -# Multi Progress Bar - -[![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) - -**mpb** is a Go lib for rendering progress bars in terminal applications. - -## Features - -* __Multiple Bars__: Multiple progress bars are supported -* __Dynamic Total__: Set total while bar is running -* __Dynamic Add/Remove__: Dynamically add or remove bars -* __Cancellation__: Cancel whole rendering process -* __Predefined Decorators__: Elapsed time, [ewma](https://github.com/VividCortex/ewma) based ETA, Percentage, Bytes counter -* __Decorator's width sync__: Synchronized decorator's width among multiple bars - -## Usage - -#### [Rendering single bar](_examples/singleBar/main.go) -```go -package main - -import ( - "math/rand" - "time" - - "github.com/vbauerster/mpb/v4" - "github.com/vbauerster/mpb/v4/decor" -) - -func main() { - // initialize progress container, with custom width - p := mpb.New(mpb.WithWidth(64)) - - total := 100 - name := "Single Bar:" - // adding a single bar, which will inherit container's width - bar := p.AddBar(int64(total), - // override DefaultBarStyle, which is "[=>-]<+" - mpb.BarStyle("╢▌▌░╟"), - mpb.PrependDecorators( - // display our name with one space on the right - decor.Name(name, decor.WC{W: len(name) + 1, C: decor.DidentRight}), - // replace ETA decorator with "done" message, OnComplete event - decor.OnComplete( - // ETA decorator with ewma age of 60, and width reservation of 4 - decor.EwmaETA(decor.ET_STYLE_GO, 60, decor.WC{W: 4}), "done", - ), - ), - mpb.AppendDecorators(decor.Percentage()), - ) - // simulating some work - max := 100 * time.Millisecond - for i := 0; i < total; i++ { - start := time.Now() - time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) - // 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/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) - - for i := 0; i < numBars; i++ { - name := fmt.Sprintf("Bar#%d:", i) - bar := p.AddBar(int64(total), - mpb.PrependDecorators( - // simple name decorator - decor.Name(name), - // decor.DSyncWidth bit enables column width synchronization - decor.Percentage(decor.WCSyncSpace), - ), - mpb.AppendDecorators( - // replace ETA decorator with "done" message, OnComplete event - decor.OnComplete( - // ETA decorator with ewma age of 60 - decor.EwmaETA(decor.ET_STYLE_GO, 60), "done", - ), - ), - ) - // 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(rng.Intn(10)+1) * max / 10) - // since ewma decorator is used, we need to pass time.Since(start) - bar.Increment(time.Since(start)) - } - }() - } - // Waiting for passed &wg and for all bars to complete and flush - p.Wait() -``` - -#### [Dynamic total](_examples/dynTotal/main.go) - -![dynamic total](_svg/godEMrCZmJkHYH1X9dN4Nm0U7.svg) - -#### [Complex example](_examples/complex/main.go) - -![complex](_svg/wHzf1M7sd7B3zVa2scBMnjqRf.svg) - -#### [Bytes counters](_examples/io/main.go) - -![byte counters](_svg/hIpTa3A5rQz65ssiVuRJu87X6.svg) diff --git a/vendor/github.com/vbauerster/mpb/v4/UNLICENSE b/vendor/github.com/vbauerster/mpb/v4/UNLICENSE deleted file mode 100644 index 68a49daad..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/UNLICENSE +++ /dev/null @@ -1,24 +0,0 @@ -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 diff --git a/vendor/github.com/vbauerster/mpb/v4/bar.go b/vendor/github.com/vbauerster/mpb/v4/bar.go deleted file mode 100644 index 1828e67a6..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/bar.go +++ /dev/null @@ -1,477 +0,0 @@ -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) -} - -// WrapFiller interface. -// If you're implementing custom Filler by wrapping a built-in one, -// it is necessary to implement this interface to retain functionality -// of built-in Filler. -type WrapFiller 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 deleted file mode 100644 index fab4aa229..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/bar_filler.go +++ /dev/null @@ -1,138 +0,0 @@ -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 a string containing 7 runes. -// Each rune is a building block of a progress bar. -// -// '1st rune' stands for left boundary rune -// -// '2nd rune' stands for fill rune -// -// '3rd 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(...) *Bar method. -func NewBarFiller(style string, reverse bool) Filler { - if style == "" { - style = DefaultBarStyle - } - bf := &barFiller{ - format: make([][]byte, utf8.RuneCountInString(style)), - reverse: reverse, - } - bf.SetStyle(style) - 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) - s.SetReverse(s.reverse) -} - -func (s *barFiller) SetReverse(reverse bool) { - if reverse { - s.tip = s.format[rRevTip] - s.flush = reverseFlush - } else { - s.tip = s.format[rTip] - s.flush = normalFlush - } - 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) -} - -func normalFlush(w io.Writer, bb [][]byte) { - for i := 0; i < len(bb); i++ { - w.Write(bb[i]) - } -} - -func reverseFlush(w io.Writer, bb [][]byte) { - for i := len(bb) - 1; i >= 0; i-- { - w.Write(bb[i]) - } -} diff --git a/vendor/github.com/vbauerster/mpb/v4/bar_option.go b/vendor/github.com/vbauerster/mpb/v4/bar_option.go deleted file mode 100644 index be0c36215..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/bar_option.go +++ /dev/null @@ -1,208 +0,0 @@ -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) - -func (s *bState) addDecorators(dest *[]decor.Decorator, decorators ...decor.Decorator) { - type mergeWrapper interface { - MergeUnwrap() []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) - } - } -} - -// BarOptOn returns option when condition evaluates to true. -func BarOptOn(option BarOption, condition func() bool) BarOption { - if condition() { - return option - } - return nil -} diff --git a/vendor/github.com/vbauerster/mpb/v4/cwriter/writer.go b/vendor/github.com/vbauerster/mpb/v4/cwriter/writer.go deleted file mode 100644 index 9ec1ec66b..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/cwriter/writer.go +++ /dev/null @@ -1,71 +0,0 @@ -package cwriter - -import ( - "bytes" - "errors" - "fmt" - "io" - "os" - - "golang.org/x/crypto/ssh/terminal" -) - -// NotATTY not a TeleTYpewriter error. -var NotATTY = errors.New("not a terminal") - -var cuuAndEd = fmt.Sprintf("%c[%%dA%[1]c[J", 27) - -// 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 - lineCount int - fd uintptr - isTerminal bool -} - -// New returns a new Writer with defaults. -func New(out io.Writer) *Writer { - w := &Writer{out: out} - if f, ok := out.(*os.File); ok { - w.fd = f.Fd() - w.isTerminal = terminal.IsTerminal(int(w.fd)) - } - return w -} - -// Flush flushes the underlying buffer. -func (w *Writer) Flush(lineCount int) (err error) { - if w.lineCount > 0 { - w.clearLines() - } - w.lineCount = lineCount - _, err = w.buf.WriteTo(w.out) - return -} - -// 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. -func (w *Writer) WriteString(s string) (n int, err error) { - return w.buf.WriteString(s) -} - -// ReadFrom reads from the provided io.Reader and writes to the -// underlying buffer. -func (w *Writer) ReadFrom(r io.Reader) (n int64, err error) { - return w.buf.ReadFrom(r) -} - -// GetWidth returns width of underlying terminal. -func (w *Writer) GetWidth() (int, error) { - if w.isTerminal { - 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 deleted file mode 100644 index 3fb8b7d75..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/cwriter/writer_posix.go +++ /dev/null @@ -1,9 +0,0 @@ -// +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 deleted file mode 100644 index 712528900..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/cwriter/writer_windows.go +++ /dev/null @@ -1,60 +0,0 @@ -// +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/any.go b/vendor/github.com/vbauerster/mpb/v4/decor/any.go deleted file mode 100644 index bf9cf51a5..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/any.go +++ /dev/null @@ -1,21 +0,0 @@ -package decor - -// Any decorator displays text, that can be changed during decorator's -// lifetime via provided func call back. -// -// `f` call back which provides string to display -// -// `wcc` optional WC config -// -func Any(f func(*Statistics) string, wcc ...WC) Decorator { - return &any{initWC(wcc...), f} -} - -type any struct { - WC - f func(*Statistics) string -} - -func (d *any) Decor(s *Statistics) string { - return d.FormatMsg(d.f(s)) -} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/counters.go b/vendor/github.com/vbauerster/mpb/v4/decor/counters.go deleted file mode 100644 index 297bf937b..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/counters.go +++ /dev/null @@ -1,67 +0,0 @@ -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 { - return Any(chooseSizeProducer(unit, pairFmt), wcc...) -} - -func chooseSizeProducer(unit int, format string) func(*Statistics) string { - if format == "" { - format = "%d / %d" - } - switch unit { - case UnitKiB: - return func(s *Statistics) string { - return fmt.Sprintf(format, SizeB1024(s.Current), SizeB1024(s.Total)) - } - case UnitKB: - return func(s *Statistics) string { - return fmt.Sprintf(format, SizeB1000(s.Current), SizeB1000(s.Total)) - } - default: - return func(s *Statistics) string { - return fmt.Sprintf(format, s.Current, s.Total) - } - } -} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/decorator.go b/vendor/github.com/vbauerster/mpb/v4/decor/decorator.go deleted file mode 100644 index 01b67802c..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/decorator.go +++ /dev/null @@ -1,186 +0,0 @@ -package decor - -import ( - "fmt" - "time" - "unicode/utf8" - - "github.com/acarl005/stripansi" -) - -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 - 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 { - var format string - runeCount := utf8.RuneCountInString(stripansi.Strip(msg)) - ansiCount := utf8.RuneCountInString(msg) - runeCount - if (wc.C & DSyncWidth) != 0 { - if (wc.C & DextraSpace) != 0 { - runeCount++ - } - wc.wsync <- runeCount - max := <-wc.wsync - format = fmt.Sprintf(wc.dynFormat, ansiCount+max) - } else { - format = fmt.Sprintf(wc.dynFormat, ansiCount+wc.W) - } - return fmt.Sprintf(format, msg) -} - -// Init initializes width related config. -func (wc *WC) Init() WC { - wc.dynFormat = "%%" - if (wc.C & DidentRight) != 0 { - wc.dynFormat += "-" - } - wc.dynFormat += "%ds" - 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() -} - -func initWC(wcc ...WC) WC { - var wc WC - for _, nwc := range wcc { - wc = nwc - } - return wc.Init() -} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/doc.go b/vendor/github.com/vbauerster/mpb/v4/decor/doc.go deleted file mode 100644 index b595e8015..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/doc.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - 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 - *mpb.Bar instances. To avoid data races, create new decorator per *mpb.Bar instance. - - Don't: - - p := mpb.New() - name := decor.Name("bar") - p.AddBar(100, mpb.AppendDecorators(name)) - p.AddBar(100, mpb.AppendDecorators(name)) - - Do: - - p := mpb.New() - p.AddBar(100, mpb.AppendDecorators(decor.Name("bar1"))) - p.AddBar(100, mpb.AppendDecorators(decor.Name("bar2"))) -*/ -package decor diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/elapsed.go b/vendor/github.com/vbauerster/mpb/v4/decor/elapsed.go deleted file mode 100644 index c9999a3b5..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/elapsed.go +++ /dev/null @@ -1,35 +0,0 @@ -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 msg string - producer := chooseTimeProducer(style) - f := func(s *Statistics) string { - if !s.Completed { - msg = producer(time.Since(startTime)) - } - return msg - } - return Any(f, wcc...) -} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/eta.go b/vendor/github.com/vbauerster/mpb/v4/decor/eta.go deleted file mode 100644 index e875e96fa..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/eta.go +++ /dev/null @@ -1,207 +0,0 @@ -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, NewThreadSafeMovingAverage(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 { - d := &movingAverageETA{ - WC: initWC(wcc...), - 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(s *Statistics) string { - v := math.Round(d.average.Value()) - remaining := time.Duration((s.Total - s.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 { - d := &averageETA{ - WC: initWC(wcc...), - 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(s *Statistics) string { - var remaining time.Duration - if s.Current != 0 { - durPerItem := float64(time.Since(d.startTime)) / float64(s.Current) - durPerItem = math.Round(durPerItem) - remaining = time.Duration((s.Total - s.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 deleted file mode 100644 index 520f13a7f..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/merge.go +++ /dev/null @@ -1,106 +0,0 @@ -package decor - -import ( - "fmt" - "strings" - "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.Init()} - } - 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(s *Statistics) string { - msg := d.Decorator.Decor(s) - msgLen := utf8.RuneCountInString(msg) - if (d.wc.C & DextraSpace) != 0 { - msgLen++ - } - - var total int - max := utf8.RuneCountInString(d.placeHolders[0].FormatMsg("")) - total += max - pw := (msgLen - max) / len(d.placeHolders) - rem := (msgLen - max) % len(d.placeHolders) - - var diff int - for i := 1; i < len(d.placeHolders); i++ { - ph := d.placeHolders[i] - width := pw - diff - if (ph.WC.C & DextraSpace) != 0 { - width-- - if width < 0 { - width = 0 - } - } - max = utf8.RuneCountInString(ph.FormatMsg(strings.Repeat(" ", width))) - total += max - diff = max - pw - } - - d.wc.wsync <- pw + rem - max = <-d.wc.wsync - return fmt.Sprintf(fmt.Sprintf(d.wc.dynFormat, max+total), msg) -} - -type placeHolderDecorator struct { - WC -} - -func (d *placeHolderDecorator) Decor(*Statistics) string { - return "" -} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/moving_average.go b/vendor/github.com/vbauerster/mpb/v4/decor/moving_average.go deleted file mode 100644 index 6acdb4ace..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/moving_average.go +++ /dev/null @@ -1,73 +0,0 @@ -package decor - -import ( - "sort" - "sync" - - "github.com/VividCortex/ewma" -) - -// 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 = ewma.MovingAverage - -type threadSafeMovingAverage struct { - ewma.MovingAverage - mu sync.Mutex -} - -func (s *threadSafeMovingAverage) Add(value float64) { - s.mu.Lock() - s.MovingAverage.Add(value) - s.mu.Unlock() -} - -func (s *threadSafeMovingAverage) Value() float64 { - s.mu.Lock() - defer s.mu.Unlock() - return s.MovingAverage.Value() -} - -func (s *threadSafeMovingAverage) Set(value float64) { - s.mu.Lock() - s.MovingAverage.Set(value) - s.mu.Unlock() -} - -// NewThreadSafeMovingAverage converts provided ewma.MovingAverage -// into thread safe ewma.MovingAverage. -func NewThreadSafeMovingAverage(average ewma.MovingAverage) ewma.MovingAverage { - if tsma, ok := average.(*threadSafeMovingAverage); ok { - return tsma - } - return &threadSafeMovingAverage{MovingAverage: average} -} - -type medianWindow [3]float64 - -func (s *medianWindow) Len() int { return len(s) } -func (s *medianWindow) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s *medianWindow) Less(i, j int) bool { return s[i] < s[j] } - -func (s *medianWindow) Add(value float64) { - s[0], s[1] = s[1], s[2] - s[2] = value -} - -func (s *medianWindow) Value() float64 { - tmp := *s - sort.Sort(&tmp) - return tmp[1] -} - -func (s *medianWindow) Set(value float64) { - for i := 0; i < len(s); i++ { - s[i] = value - } -} - -// NewMedian is fixed last 3 samples median MovingAverage. -func NewMedian() MovingAverage { - return NewThreadSafeMovingAverage(new(medianWindow)) -} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/name.go b/vendor/github.com/vbauerster/mpb/v4/decor/name.go deleted file mode 100644 index a7d477e07..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/name.go +++ /dev/null @@ -1,12 +0,0 @@ -package decor - -// Name decorator displays text that is set once and can't be changed -// during decorator's lifetime. -// -// `str` string to display -// -// `wcc` optional WC config -// -func Name(str string, wcc ...WC) Decorator { - return Any(func(*Statistics) string { return str }, wcc...) -} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/on_complete.go b/vendor/github.com/vbauerster/mpb/v4/decor/on_complete.go deleted file mode 100644 index 0a1526bf5..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/on_complete.go +++ /dev/null @@ -1,37 +0,0 @@ -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(s *Statistics) string { - if s.Completed { - wc := d.GetConf() - return wc.FormatMsg(d.msg) - } - return d.Decorator.Decor(s) -} - -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 deleted file mode 100644 index efb2f3ef5..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/percentage.go +++ /dev/null @@ -1,58 +0,0 @@ -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 format string. -// -// format examples: -// -// format="%.1f" output: "1.0%" -// format="% .1f" output: "1.0 %" -// format="%d" output: "1%" -// format="% d" output: "1 %" -// -func NewPercentage(format string, wcc ...WC) Decorator { - if format == "" { - format = "% d" - } - f := func(s *Statistics) string { - p := internal.Percentage(s.Total, s.Current, 100) - return fmt.Sprintf(format, percentageType(p)) - } - return Any(f, wcc...) -} diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/size_type.go b/vendor/github.com/vbauerster/mpb/v4/decor/size_type.go deleted file mode 100644 index e4b974058..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/size_type.go +++ /dev/null @@ -1,109 +0,0 @@ -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 deleted file mode 100644 index 3f32ef715..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/sizeb1000_string.go +++ /dev/null @@ -1,41 +0,0 @@ -// 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 deleted file mode 100644 index 9fca66cc7..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/sizeb1024_string.go +++ /dev/null @@ -1,41 +0,0 @@ -// 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 deleted file mode 100644 index 93f5763e1..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/speed.go +++ /dev/null @@ -1,175 +0,0 @@ -package decor - -import ( - "fmt" - "io" - "math" - "time" - - "github.com/VividCortex/ewma" -) - -// FmtAsSpeed adds "/s" to the end of the input formatter. To be -// used with SizeB1000 or SizeB1024 types, for example: -// -// fmt.Printf("%.1f", FmtAsSpeed(SizeB1024(2048))) -// -func FmtAsSpeed(input fmt.Formatter) fmt.Formatter { - return &speedFormatter{input} -} - -type speedFormatter struct { - fmt.Formatter -} - -func (self *speedFormatter) Format(st fmt.State, verb rune) { - 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, NewThreadSafeMovingAverage(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 { - if format == "" { - format = "%.0f" - } - d := &movingAverageSpeed{ - WC: initWC(wcc...), - 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(s *Statistics) string { - if !s.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 { - if format == "" { - format = "%.0f" - } - d := &averageSpeed{ - WC: initWC(wcc...), - 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(s *Statistics) string { - if !s.Completed { - speed := float64(s.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, FmtAsSpeed(SizeB1024(math.Round(speed)))) - } - case UnitKB: - return func(speed float64) string { - return fmt.Sprintf(format, FmtAsSpeed(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 deleted file mode 100644 index abfb2f76c..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/decor/spinner.go +++ /dev/null @@ -1,21 +0,0 @@ -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 { - if len(frames) == 0 { - frames = defaultSpinnerStyle - } - var count uint - f := func(s *Statistics) string { - frame := frames[count%uint(len(frames))] - count++ - return frame - } - return Any(f, wcc...) -} diff --git a/vendor/github.com/vbauerster/mpb/v4/doc.go b/vendor/github.com/vbauerster/mpb/v4/doc.go deleted file mode 100644 index 5ada71774..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// 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 deleted file mode 100644 index 43b42d496..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/go.mod +++ /dev/null @@ -1,10 +0,0 @@ -module github.com/vbauerster/mpb/v4 - -require ( - github.com/VividCortex/ewma v1.1.1 - github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d - golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6 - golang.org/x/sys v0.0.0-20200217220822-9197077df867 // indirect -) - -go 1.13 diff --git a/vendor/github.com/vbauerster/mpb/v4/go.sum b/vendor/github.com/vbauerster/mpb/v4/go.sum deleted file mode 100644 index 3d6d33a5c..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/go.sum +++ /dev/null @@ -1,13 +0,0 @@ -github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM= -github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6 h1:Sy5bstxEqwwbYs6n0/pBuxKENqOeZUgD45Gp3Q3pqLg= -golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200217220822-9197077df867 h1:JoRuNIf+rpHl+VhScRQQvzbHed86tKkqwPMV34T8myw= -golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/vendor/github.com/vbauerster/mpb/v4/internal/percentage.go b/vendor/github.com/vbauerster/mpb/v4/internal/percentage.go deleted file mode 100644 index 7e261cb22..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/internal/percentage.go +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index 048870284..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/options.go +++ /dev/null @@ -1,105 +0,0 @@ -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 - } -} - -// ContainerOptOn returns option when condition evaluates to true. -func ContainerOptOn(option ContainerOption, condition func() bool) ContainerOption { - if condition() { - return option - } - return nil -} diff --git a/vendor/github.com/vbauerster/mpb/v4/priority_queue.go b/vendor/github.com/vbauerster/mpb/v4/priority_queue.go deleted file mode 100644 index 29d9bd5a8..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/priority_queue.go +++ /dev/null @@ -1,32 +0,0 @@ -package mpb - -// A priorityQueue implements heap.Interface -type priorityQueue []*Bar - -func (pq priorityQueue) Len() int { return len(pq) } - -func (pq priorityQueue) Less(i, j int) bool { - return pq[i].priority < pq[j].priority -} - -func (pq priorityQueue) Swap(i, j int) { - pq[i], pq[j] = pq[j], pq[i] - pq[i].index = i - pq[j].index = j -} - -func (pq *priorityQueue) Push(x interface{}) { - s := *pq - bar := x.(*Bar) - bar.index = len(s) - s = append(s, bar) - *pq = s -} - -func (pq *priorityQueue) Pop() interface{} { - s := *pq - *pq = s[0 : len(s)-1] - bar := s[len(s)-1] - bar.index = -1 // for safety - return bar -} diff --git a/vendor/github.com/vbauerster/mpb/v4/progress.go b/vendor/github.com/vbauerster/mpb/v4/progress.go deleted file mode 100644 index c9b72b0e7..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/progress.go +++ /dev/null @@ -1,396 +0,0 @@ -package mpb - -import ( - "bytes" - "container/heap" - "context" - "fmt" - "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 it to the rendering queue. -func (p *Progress) AddBar(total int64, options ...BarOption) *Bar { - return p.Add(total, NewBarFiller(DefaultBarStyle, false), options...) -} - -// AddSpinner creates a new spinner bar and adds it to the rendering queue. -func (p *Progress) AddSpinner(total int64, alignment SpinnerAlignment, options ...BarOption) *Bar { - return p.Add(total, NewSpinnerFiller(DefaultSpinnerStyle, alignment), options...) -} - -// Add creates a bar which renders itself by provided filler. -// Set total to 0, if you plan to update it later. -// Panics if *Progress instance is done, i.e. called after *Progress.Wait(). -func (p *Progress) Add(total int64, filler Filler, options ...BarOption) *Bar { - if filler == nil { - filler = NewBarFiller(DefaultBarStyle, false) - } - 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() - panic(fmt.Sprintf("%T instance can't be reused after it's done!", p)) - } -} - -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.(WrapFiller); 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 deleted file mode 100644 index 0e4b51f09..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/proxyreader.go +++ /dev/null @@ -1,41 +0,0 @@ -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 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 prox.bar.SetTotal(0, true) - } - return -} diff --git a/vendor/github.com/vbauerster/mpb/v4/spinner_filler.go b/vendor/github.com/vbauerster/mpb/v4/spinner_filler.go deleted file mode 100644 index f855be44e..000000000 --- a/vendor/github.com/vbauerster/mpb/v4/spinner_filler.go +++ /dev/null @@ -1,61 +0,0 @@ -package mpb - -import ( - "io" - "strings" - "unicode/utf8" - - "github.com/vbauerster/mpb/v4/decor" -) - -// SpinnerAlignment enum. -type SpinnerAlignment int - -// SpinnerAlignment kinds. -const ( - SpinnerOnLeft SpinnerAlignment = iota - SpinnerOnMiddle - SpinnerOnRight -) - -// DefaultSpinnerStyle is a slice of strings, which makes a spinner. -var DefaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"} - -type spinnerFiller struct { - frames []string - count uint - alignment SpinnerAlignment -} - -// NewSpinnerFiller constucts mpb.Filler, to be used with *Progress.Add(...) *Bar method. -func NewSpinnerFiller(style []string, alignment SpinnerAlignment) Filler { - if len(style) == 0 { - style = DefaultSpinnerStyle - } - 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))] - frameWidth := utf8.RuneCountInString(frame) - - if width < frameWidth { - return - } - - switch rest := width - frameWidth; s.alignment { - case SpinnerOnLeft: - io.WriteString(w, frame+strings.Repeat(" ", rest)) - case SpinnerOnMiddle: - str := strings.Repeat(" ", rest/2) + frame + strings.Repeat(" ", rest/2+rest%2) - io.WriteString(w, str) - case SpinnerOnRight: - io.WriteString(w, strings.Repeat(" ", rest)+frame) - } - s.count++ -} diff --git a/vendor/github.com/vbauerster/mpb/v5/.gitignore b/vendor/github.com/vbauerster/mpb/v5/.gitignore new file mode 100644 index 000000000..63bd91672 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/.gitignore @@ -0,0 +1,5 @@ +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out diff --git a/vendor/github.com/vbauerster/mpb/v5/.travis.yml b/vendor/github.com/vbauerster/mpb/v5/.travis.yml new file mode 100644 index 000000000..0eb0f2f20 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/.travis.yml @@ -0,0 +1,8 @@ +language: go + +go: + - 1.14.x + +script: + - go test -race ./... + - for i in _examples/*/; do go build $i/*.go || exit 1; done diff --git a/vendor/github.com/vbauerster/mpb/v5/README.md b/vendor/github.com/vbauerster/mpb/v5/README.md new file mode 100644 index 000000000..bfb0c4d18 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/README.md @@ -0,0 +1,118 @@ +# Multi Progress Bar + +[![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) + +**mpb** is a Go lib for rendering progress bars in terminal applications. + +## Features + +* __Multiple Bars__: Multiple progress bars are supported +* __Dynamic Total__: Set total while bar is running +* __Dynamic Add/Remove__: Dynamically add or remove bars +* __Cancellation__: Cancel whole rendering process +* __Predefined Decorators__: Elapsed time, [ewma](https://github.com/VividCortex/ewma) based ETA, Percentage, Bytes counter +* __Decorator's width sync__: Synchronized decorator's width among multiple bars + +## Usage + +#### [Rendering single bar](_examples/singleBar/main.go) +```go +package main + +import ( + "math/rand" + "time" + + "github.com/vbauerster/mpb/v5" + "github.com/vbauerster/mpb/v5/decor" +) + +func main() { + // initialize progress container, with custom width + p := mpb.New(mpb.WithWidth(64)) + + total := 100 + name := "Single Bar:" + // adding a single bar, which will inherit container's width + bar := p.AddBar(int64(total), + // override DefaultBarStyle, which is "[=>-]<+" + mpb.BarStyle("╢▌▌░╟"), + mpb.PrependDecorators( + // display our name with one space on the right + decor.Name(name, decor.WC{W: len(name) + 1, C: decor.DidentRight}), + // replace ETA decorator with "done" message, OnComplete event + decor.OnComplete( + decor.AverageETA(decor.ET_STYLE_GO, decor.WC{W: 4}), "done", + ), + ), + mpb.AppendDecorators(decor.Percentage()), + ) + // simulating some work + max := 100 * time.Millisecond + for i := 0; i < total; i++ { + time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) + bar.Increment() + } + // wait for our bar to complete and flush + p.Wait() +} +``` + +#### [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) + + for i := 0; i < numBars; i++ { + name := fmt.Sprintf("Bar#%d:", i) + bar := p.AddBar(int64(total), + mpb.PrependDecorators( + // simple name decorator + decor.Name(name), + // decor.DSyncWidth bit enables column width synchronization + decor.Percentage(decor.WCSyncSpace), + ), + mpb.AppendDecorators( + // replace ETA decorator with "done" message, OnComplete event + decor.OnComplete( + // ETA decorator with ewma age of 60 + decor.EwmaETA(decor.ET_STYLE_GO, 60), "done", + ), + ), + ) + // 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 variable is solely for EWMA calculation + // EWMA's unit of measure is an iteration's duration + start := time.Now() + time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) + bar.Increment() + // we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract + bar.DecoratorEwmaUpdate(time.Since(start)) + } + }() + } + // Waiting for passed &wg and for all bars to complete and flush + p.Wait() +``` + +#### [Dynamic total](_examples/dynTotal/main.go) + +![dynamic total](_svg/godEMrCZmJkHYH1X9dN4Nm0U7.svg) + +#### [Complex example](_examples/complex/main.go) + +![complex](_svg/wHzf1M7sd7B3zVa2scBMnjqRf.svg) + +#### [Bytes counters](_examples/io/main.go) + +![byte counters](_svg/hIpTa3A5rQz65ssiVuRJu87X6.svg) diff --git a/vendor/github.com/vbauerster/mpb/v5/UNLICENSE b/vendor/github.com/vbauerster/mpb/v5/UNLICENSE new file mode 100644 index 000000000..68a49daad --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/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 diff --git a/vendor/github.com/vbauerster/mpb/v5/bar.go b/vendor/github.com/vbauerster/mpb/v5/bar.go new file mode 100644 index 000000000..1a4c66fe1 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/bar.go @@ -0,0 +1,476 @@ +package mpb + +import ( + "bytes" + "context" + "fmt" + "io" + "log" + "strings" + "time" + "unicode/utf8" + + "github.com/vbauerster/mpb/v5/decor" +) + +// BarFiller interface. +// Bar renders itself by calling BarFiller's Fill method. You can +// literally have any bar kind, by implementing this interface and +// passing it to the *Progress.Add(...) *Bar method. +type BarFiller interface { + Fill(w io.Writer, width int, stat *decor.Statistics) +} + +// BarFillerFunc is function type adapter to convert function into Filler. +type BarFillerFunc func(w io.Writer, width int, stat *decor.Statistics) + +func (f BarFillerFunc) Fill(w io.Writer, width int, stat *decor.Statistics) { + f(w, width, stat) +} + +// 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 + hasEwmaDecorators 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 BarFiller + filler BarFiller + id int + width int + total int64 + current int64 + lastN int64 + iterated bool + trimSpace bool + toComplete bool + completeFlushed bool + noPop bool + aDecorators []decor.Decorator + pDecorators []decor.Decorator + averageDecorators []decor.AverageDecorator + ewmaDecorators []decor.EwmaDecorator + shutdownListeners []decor.ShutdownListener + 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 +} + +// ProxyReader wraps r with metrics required for progress tracking. +// Panics if r is nil. +func (b *Bar) ProxyReader(r io.Reader) io.ReadCloser { + if r == nil { + panic("expected non nil io.Reader") + } + return newProxyReader(r, b) +} + +// 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 fills bar with refill rune up to amount argument. +// Given default bar style is "[=>-]<+", refill rune is '+'. +// To set bar style use mpb.BarStyle(string) BarOption. +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) + } + } +} + +// TraverseDecorators traverses all available decorators and calls cb func on each. +func (b *Bar) TraverseDecorators(cb func(decor.Decorator)) { + 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. +// If total is less or equal to zero it takes progress' current value. +// If complete is true, complete event will be triggered. +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 an arbitrary value. +func (b *Bar) SetCurrent(current int64) { + select { + case b.operateState <- func(s *bState) { + s.iterated = true + s.lastN = current - s.current + 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). +func (b *Bar) Increment() { + b.IncrInt64(1) +} + +// IncrBy is a shorthand for b.IncrInt64(int64(n)). +func (b *Bar) IncrBy(n int) { + b.IncrInt64(int64(n)) +} + +// IncrInt64 increments progress by amount of n. +func (b *Bar) IncrInt64(n int64) { + select { + case b.operateState <- func(s *bState) { + s.iterated = true + s.lastN = n + s.current += n + if s.total > 0 && s.current >= s.total { + s.current = s.total + s.toComplete = true + go b.refreshTillShutdown() + } + }: + case <-b.done: + } +} + +// DecoratorEwmaUpdate updates all EWMA based decorators. Should be +// called on each iteration, because EWMA's unit of measure is an +// iteration's duration. Panics if called before *Bar.Incr... family +// methods. +func (b *Bar) DecoratorEwmaUpdate(dur time.Duration) { + select { + case b.operateState <- func(s *bState) { + ewmaIterationUpdate(false, s, dur) + }: + case <-b.done: + ewmaIterationUpdate(true, b.cacheState, dur) + } +} + +// DecoratorAverageAdjust adjusts all average based decorators. Call +// if you need to adjust start time of all average based decorators +// or after progress resume. +func (b *Bar) DecoratorAverageAdjust(start time.Time) { + select { + case b.operateState <- func(s *bState) { + for _, d := range s.averageDecorators { + d.AverageAdjust(start) + } + }: + 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 averageDecorators []decor.AverageDecorator + var ewmaDecorators []decor.EwmaDecorator + var shutdownListeners []decor.ShutdownListener + b.TraverseDecorators(func(d decor.Decorator) { + if d, ok := d.(decor.AverageDecorator); ok { + averageDecorators = append(averageDecorators, d) + } + if d, ok := d.(decor.EwmaDecorator); ok { + ewmaDecorators = append(ewmaDecorators, d) + } + if d, ok := d.(decor.ShutdownListener); ok { + shutdownListeners = append(shutdownListeners, d) + } + }) + b.operateState <- func(s *bState) { + s.averageDecorators = averageDecorators + s.ewmaDecorators = ewmaDecorators + s.shutdownListeners = shutdownListeners + } + b.hasEwmaDecorators = len(ewmaDecorators) != 0 +} + +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 +} + +func ewmaIterationUpdate(done bool, s *bState, dur time.Duration) { + if !done && !s.iterated { + panic("increment required before ewma iteration update") + } else { + s.iterated = false + } + for _, d := range s.ewmaDecorators { + d.EwmaUpdate(s.lastN, dur) + } +} diff --git a/vendor/github.com/vbauerster/mpb/v5/bar_filler.go b/vendor/github.com/vbauerster/mpb/v5/bar_filler.go new file mode 100644 index 000000000..00bf0a494 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/bar_filler.go @@ -0,0 +1,138 @@ +package mpb + +import ( + "io" + "unicode/utf8" + + "github.com/vbauerster/mpb/v5/decor" + "github.com/vbauerster/mpb/v5/internal" +) + +const ( + rLeft = iota + rFill + rTip + rEmpty + rRight + rRevTip + rRefill +) + +// DefaultBarStyle is a string containing 7 runes. +// Each rune is a building block of a progress bar. +// +// '1st rune' stands for left boundary rune +// +// '2nd rune' stands for fill rune +// +// '3rd 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.BarFiller, to be used with *Progress.Add(...) *Bar method. +func NewBarFiller(style string, reverse bool) BarFiller { + if style == "" { + style = DefaultBarStyle + } + bf := &barFiller{ + format: make([][]byte, utf8.RuneCountInString(style)), + reverse: reverse, + } + bf.SetStyle(style) + 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) + s.SetReverse(s.reverse) +} + +func (s *barFiller) SetReverse(reverse bool) { + if reverse { + s.tip = s.format[rRevTip] + s.flush = reverseFlush + } else { + s.tip = s.format[rTip] + s.flush = normalFlush + } + 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) +} + +func normalFlush(w io.Writer, bb [][]byte) { + for i := 0; i < len(bb); i++ { + w.Write(bb[i]) + } +} + +func reverseFlush(w io.Writer, bb [][]byte) { + for i := len(bb) - 1; i >= 0; i-- { + w.Write(bb[i]) + } +} diff --git a/vendor/github.com/vbauerster/mpb/v5/bar_option.go b/vendor/github.com/vbauerster/mpb/v5/bar_option.go new file mode 100644 index 000000000..76f2050f1 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/bar_option.go @@ -0,0 +1,204 @@ +package mpb + +import ( + "bytes" + "io" + + "github.com/vbauerster/mpb/v5/decor" +) + +// BarOption is a function option which changes the default behavior of a bar. +type BarOption func(*bState) + +func (s *bState) addDecorators(dest *[]decor.Decorator, decorators ...decor.Decorator) { + type mergeWrapper interface { + MergeUnwrap() []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 + } +} + +// BarQueueAfter queues this (being constructed) bar to relplace +// runningBar after it has been completed. +func BarQueueAfter(runningBar *Bar) BarOption { + if runningBar == nil { + return nil + } + return func(s *bState) { + s.runningBar = runningBar + } +} + +// BarRemoveOnComplete removes both bar's filler and its decorators +// on complete event. +func BarRemoveOnComplete() BarOption { + return func(s *bState) { + s.dropOnComplete = true + } +} + +// BarFillerClearOnComplete clears bar's filler on complete event. +// It's shortcut for BarFillerOnComplete(""). +func BarFillerClearOnComplete() BarOption { + return BarFillerOnComplete("") +} + +// BarFillerOnComplete replaces bar's filler with message, on complete event. +func BarFillerOnComplete(message string) BarOption { + return func(s *bState) { + s.filler = makeBarFillerOnComplete(s.baseF, message) + } +} + +func makeBarFillerOnComplete(filler BarFiller, message string) BarFiller { + return BarFillerFunc(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 BarFiller) BarOption { + if extender == nil { + return nil + } + return func(s *bState) { + s.extender = makeExtFunc(extender) + } +} + +func makeExtFunc(extender BarFiller) 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 which is "[=>-]<+". +// It's ok to pass string containing just 5 runes, for example "╢▌▌░╟", +// if you don't need to override '<' (reverse tip) and '+' (refill rune). +func BarStyle(style string) BarOption { + if style == "" { + return nil + } + type styleSetter interface { + SetStyle(string) + } + return func(s *bState) { + if t, ok := s.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 BarFiller) (interface{}, bool) { + t, ok := filler.(*spinnerFiller) + return t, ok + } + cb := func(t interface{}) { + t.(*spinnerFiller).frames = frames + } + return MakeFillerTypeSpecificBarOption(chk, cb) +} + +// MakeFillerTypeSpecificBarOption makes BarOption specific to Filler's +// actual type. If you implement your own Filler, so most probably +// you'll need this. See BarStyle or SpinnerStyle for example. +func MakeFillerTypeSpecificBarOption( + typeChecker func(BarFiller) (interface{}, bool), + cb func(interface{}), +) BarOption { + return func(s *bState) { + if t, ok := typeChecker(s.baseF); ok { + cb(t) + } + } +} + +// BarOptOn returns option when condition evaluates to true. +func BarOptOn(option BarOption, condition func() bool) BarOption { + if condition() { + return option + } + return nil +} diff --git a/vendor/github.com/vbauerster/mpb/v5/cwriter/writer.go b/vendor/github.com/vbauerster/mpb/v5/cwriter/writer.go new file mode 100644 index 000000000..9ec1ec66b --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/cwriter/writer.go @@ -0,0 +1,71 @@ +package cwriter + +import ( + "bytes" + "errors" + "fmt" + "io" + "os" + + "golang.org/x/crypto/ssh/terminal" +) + +// NotATTY not a TeleTYpewriter error. +var NotATTY = errors.New("not a terminal") + +var cuuAndEd = fmt.Sprintf("%c[%%dA%[1]c[J", 27) + +// 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 + lineCount int + fd uintptr + isTerminal bool +} + +// New returns a new Writer with defaults. +func New(out io.Writer) *Writer { + w := &Writer{out: out} + if f, ok := out.(*os.File); ok { + w.fd = f.Fd() + w.isTerminal = terminal.IsTerminal(int(w.fd)) + } + return w +} + +// Flush flushes the underlying buffer. +func (w *Writer) Flush(lineCount int) (err error) { + if w.lineCount > 0 { + w.clearLines() + } + w.lineCount = lineCount + _, err = w.buf.WriteTo(w.out) + return +} + +// 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. +func (w *Writer) WriteString(s string) (n int, err error) { + return w.buf.WriteString(s) +} + +// ReadFrom reads from the provided io.Reader and writes to the +// underlying buffer. +func (w *Writer) ReadFrom(r io.Reader) (n int64, err error) { + return w.buf.ReadFrom(r) +} + +// GetWidth returns width of underlying terminal. +func (w *Writer) GetWidth() (int, error) { + if w.isTerminal { + tw, _, err := terminal.GetSize(int(w.fd)) + return tw, err + } + return -1, NotATTY +} diff --git a/vendor/github.com/vbauerster/mpb/v5/cwriter/writer_posix.go b/vendor/github.com/vbauerster/mpb/v5/cwriter/writer_posix.go new file mode 100644 index 000000000..3fb8b7d75 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/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/v5/cwriter/writer_windows.go b/vendor/github.com/vbauerster/mpb/v5/cwriter/writer_windows.go new file mode 100644 index 000000000..712528900 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/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/v5/decor/any.go b/vendor/github.com/vbauerster/mpb/v5/decor/any.go new file mode 100644 index 000000000..bf9cf51a5 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/decor/any.go @@ -0,0 +1,21 @@ +package decor + +// Any decorator displays text, that can be changed during decorator's +// lifetime via provided func call back. +// +// `f` call back which provides string to display +// +// `wcc` optional WC config +// +func Any(f func(*Statistics) string, wcc ...WC) Decorator { + return &any{initWC(wcc...), f} +} + +type any struct { + WC + f func(*Statistics) string +} + +func (d *any) Decor(s *Statistics) string { + return d.FormatMsg(d.f(s)) +} diff --git a/vendor/github.com/vbauerster/mpb/v5/decor/counters.go b/vendor/github.com/vbauerster/mpb/v5/decor/counters.go new file mode 100644 index 000000000..297bf937b --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/decor/counters.go @@ -0,0 +1,67 @@ +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 { + return Any(chooseSizeProducer(unit, pairFmt), wcc...) +} + +func chooseSizeProducer(unit int, format string) func(*Statistics) string { + if format == "" { + format = "%d / %d" + } + switch unit { + case UnitKiB: + return func(s *Statistics) string { + return fmt.Sprintf(format, SizeB1024(s.Current), SizeB1024(s.Total)) + } + case UnitKB: + return func(s *Statistics) string { + return fmt.Sprintf(format, SizeB1000(s.Current), SizeB1000(s.Total)) + } + default: + return func(s *Statistics) string { + return fmt.Sprintf(format, s.Current, s.Total) + } + } +} diff --git a/vendor/github.com/vbauerster/mpb/v5/decor/decorator.go b/vendor/github.com/vbauerster/mpb/v5/decor/decorator.go new file mode 100644 index 000000000..5bca63d52 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/decor/decorator.go @@ -0,0 +1,184 @@ +package decor + +import ( + "fmt" + "time" + "unicode/utf8" + + "github.com/acarl005/stripansi" +) + +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 +} + +// EwmaDecorator interface. +// EWMA based decorators should implement this one. +type EwmaDecorator interface { + EwmaUpdate(int64, time.Duration) +} + +// AverageDecorator interface. +// Average decorators should implement this interface to provide start +// time adjustment facility, for resume-able tasks. +type AverageDecorator interface { + AverageAdjust(time.Time) +} + +// 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 instances of WC with sync width bit set. +// To be used with multiple bars only, i.e. not effective for single bar usage. +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 + 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 { + var format string + runeCount := utf8.RuneCountInString(stripansi.Strip(msg)) + ansiCount := utf8.RuneCountInString(msg) - runeCount + if (wc.C & DSyncWidth) != 0 { + if (wc.C & DextraSpace) != 0 { + runeCount++ + } + wc.wsync <- runeCount + max := <-wc.wsync + format = fmt.Sprintf(wc.dynFormat, ansiCount+max) + } else { + format = fmt.Sprintf(wc.dynFormat, ansiCount+wc.W) + } + return fmt.Sprintf(format, msg) +} + +// Init initializes width related config. +func (wc *WC) Init() WC { + wc.dynFormat = "%%" + if (wc.C & DidentRight) != 0 { + wc.dynFormat += "-" + } + wc.dynFormat += "%ds" + 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() +} + +func initWC(wcc ...WC) WC { + var wc WC + for _, nwc := range wcc { + wc = nwc + } + return wc.Init() +} diff --git a/vendor/github.com/vbauerster/mpb/v5/decor/doc.go b/vendor/github.com/vbauerster/mpb/v5/decor/doc.go new file mode 100644 index 000000000..6d2614451 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/decor/doc.go @@ -0,0 +1,21 @@ +/* + Package decor provides common decorators for "github.com/vbauerster/mpb/v5" module. + + Some decorators returned by this package might have a closure state. It is ok to use + decorators concurrently, unless you share the same decorator among multiple + *mpb.Bar instances. To avoid data races, create new decorator per *mpb.Bar instance. + + Don't: + + p := mpb.New() + name := decor.Name("bar") + p.AddBar(100, mpb.AppendDecorators(name)) + p.AddBar(100, mpb.AppendDecorators(name)) + + Do: + + p := mpb.New() + p.AddBar(100, mpb.AppendDecorators(decor.Name("bar1"))) + p.AddBar(100, mpb.AppendDecorators(decor.Name("bar2"))) +*/ +package decor diff --git a/vendor/github.com/vbauerster/mpb/v5/decor/elapsed.go b/vendor/github.com/vbauerster/mpb/v5/decor/elapsed.go new file mode 100644 index 000000000..c9999a3b5 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/decor/elapsed.go @@ -0,0 +1,35 @@ +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 msg string + producer := chooseTimeProducer(style) + f := func(s *Statistics) string { + if !s.Completed { + msg = producer(time.Since(startTime)) + } + return msg + } + return Any(f, wcc...) +} diff --git a/vendor/github.com/vbauerster/mpb/v5/decor/eta.go b/vendor/github.com/vbauerster/mpb/v5/decor/eta.go new file mode 100644 index 000000000..6cb27a247 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/decor/eta.go @@ -0,0 +1,203 @@ +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. +// For this decorator to work correctly you have to measure each +// iteration's duration and pass it to the +// *Bar.DecoratorEwmaUpdate(time.Duration) method after each increment. +func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator { + var average ewma.MovingAverage + if age == 0 { + average = ewma.NewMovingAverage() + } else { + average = ewma.NewMovingAverage(age) + } + return MovingAverageETA(style, NewThreadSafeMovingAverage(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 ewma.MovingAverage, normalizer TimeNormalizer, wcc ...WC) Decorator { + d := &movingAverageETA{ + WC: initWC(wcc...), + 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(s *Statistics) string { + v := math.Round(d.average.Value()) + remaining := time.Duration((s.Total - s.Current) * int64(v)) + if d.normalizer != nil { + remaining = d.normalizer.Normalize(remaining) + } + return d.FormatMsg(d.producer(remaining)) +} + +func (d *movingAverageETA) EwmaUpdate(n int64, dur time.Duration) { + durPerItem := float64(dur) / 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 { + d := &averageETA{ + WC: initWC(wcc...), + 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(s *Statistics) string { + var remaining time.Duration + if s.Current != 0 { + durPerItem := float64(time.Since(d.startTime)) / float64(s.Current) + durPerItem = math.Round(durPerItem) + remaining = time.Duration((s.Total - s.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/v5/decor/merge.go b/vendor/github.com/vbauerster/mpb/v5/decor/merge.go new file mode 100644 index 000000000..520f13a7f --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/decor/merge.go @@ -0,0 +1,106 @@ +package decor + +import ( + "fmt" + "strings" + "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.Init()} + } + 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(s *Statistics) string { + msg := d.Decorator.Decor(s) + msgLen := utf8.RuneCountInString(msg) + if (d.wc.C & DextraSpace) != 0 { + msgLen++ + } + + var total int + max := utf8.RuneCountInString(d.placeHolders[0].FormatMsg("")) + total += max + pw := (msgLen - max) / len(d.placeHolders) + rem := (msgLen - max) % len(d.placeHolders) + + var diff int + for i := 1; i < len(d.placeHolders); i++ { + ph := d.placeHolders[i] + width := pw - diff + if (ph.WC.C & DextraSpace) != 0 { + width-- + if width < 0 { + width = 0 + } + } + max = utf8.RuneCountInString(ph.FormatMsg(strings.Repeat(" ", width))) + total += max + diff = max - pw + } + + d.wc.wsync <- pw + rem + max = <-d.wc.wsync + return fmt.Sprintf(fmt.Sprintf(d.wc.dynFormat, max+total), msg) +} + +type placeHolderDecorator struct { + WC +} + +func (d *placeHolderDecorator) Decor(*Statistics) string { + return "" +} diff --git a/vendor/github.com/vbauerster/mpb/v5/decor/moving_average.go b/vendor/github.com/vbauerster/mpb/v5/decor/moving_average.go new file mode 100644 index 000000000..50ac9c393 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/decor/moving_average.go @@ -0,0 +1,68 @@ +package decor + +import ( + "sort" + "sync" + + "github.com/VividCortex/ewma" +) + +type threadSafeMovingAverage struct { + ewma.MovingAverage + mu sync.Mutex +} + +func (s *threadSafeMovingAverage) Add(value float64) { + s.mu.Lock() + s.MovingAverage.Add(value) + s.mu.Unlock() +} + +func (s *threadSafeMovingAverage) Value() float64 { + s.mu.Lock() + defer s.mu.Unlock() + return s.MovingAverage.Value() +} + +func (s *threadSafeMovingAverage) Set(value float64) { + s.mu.Lock() + s.MovingAverage.Set(value) + s.mu.Unlock() +} + +// NewThreadSafeMovingAverage converts provided ewma.MovingAverage +// into thread safe ewma.MovingAverage. +func NewThreadSafeMovingAverage(average ewma.MovingAverage) ewma.MovingAverage { + if tsma, ok := average.(*threadSafeMovingAverage); ok { + return tsma + } + return &threadSafeMovingAverage{MovingAverage: average} +} + +type medianWindow [3]float64 + +func (s *medianWindow) Len() int { return len(s) } +func (s *medianWindow) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s *medianWindow) Less(i, j int) bool { return s[i] < s[j] } + +func (s *medianWindow) Add(value float64) { + s[0], s[1] = s[1], s[2] + s[2] = value +} + +func (s *medianWindow) Value() float64 { + tmp := *s + sort.Sort(&tmp) + return tmp[1] +} + +func (s *medianWindow) Set(value float64) { + for i := 0; i < len(s); i++ { + s[i] = value + } +} + +// NewMedian is fixed last 3 samples median MovingAverage. +func NewMedian() ewma.MovingAverage { + return NewThreadSafeMovingAverage(new(medianWindow)) +} diff --git a/vendor/github.com/vbauerster/mpb/v5/decor/name.go b/vendor/github.com/vbauerster/mpb/v5/decor/name.go new file mode 100644 index 000000000..a7d477e07 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/decor/name.go @@ -0,0 +1,12 @@ +package decor + +// Name decorator displays text that is set once and can't be changed +// during decorator's lifetime. +// +// `str` string to display +// +// `wcc` optional WC config +// +func Name(str string, wcc ...WC) Decorator { + return Any(func(*Statistics) string { return str }, wcc...) +} diff --git a/vendor/github.com/vbauerster/mpb/v5/decor/on_complete.go b/vendor/github.com/vbauerster/mpb/v5/decor/on_complete.go new file mode 100644 index 000000000..0a1526bf5 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/decor/on_complete.go @@ -0,0 +1,37 @@ +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(s *Statistics) string { + if s.Completed { + wc := d.GetConf() + return wc.FormatMsg(d.msg) + } + return d.Decorator.Decor(s) +} + +func (d *onCompleteWrapper) Base() Decorator { + return d.Decorator +} diff --git a/vendor/github.com/vbauerster/mpb/v5/decor/percentage.go b/vendor/github.com/vbauerster/mpb/v5/decor/percentage.go new file mode 100644 index 000000000..65ca7d318 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/decor/percentage.go @@ -0,0 +1,58 @@ +package decor + +import ( + "fmt" + "io" + "strconv" + + "github.com/vbauerster/mpb/v5/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 format string. +// +// format examples: +// +// format="%.1f" output: "1.0%" +// format="% .1f" output: "1.0 %" +// format="%d" output: "1%" +// format="% d" output: "1 %" +// +func NewPercentage(format string, wcc ...WC) Decorator { + if format == "" { + format = "% d" + } + f := func(s *Statistics) string { + p := internal.Percentage(s.Total, s.Current, 100) + return fmt.Sprintf(format, percentageType(p)) + } + return Any(f, wcc...) +} diff --git a/vendor/github.com/vbauerster/mpb/v5/decor/size_type.go b/vendor/github.com/vbauerster/mpb/v5/decor/size_type.go new file mode 100644 index 000000000..e4b974058 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/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/v5/decor/sizeb1000_string.go b/vendor/github.com/vbauerster/mpb/v5/decor/sizeb1000_string.go new file mode 100644 index 000000000..3f32ef715 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/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/v5/decor/sizeb1024_string.go b/vendor/github.com/vbauerster/mpb/v5/decor/sizeb1024_string.go new file mode 100644 index 000000000..9fca66cc7 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/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/v5/decor/speed.go b/vendor/github.com/vbauerster/mpb/v5/decor/speed.go new file mode 100644 index 000000000..8a48e3f52 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/decor/speed.go @@ -0,0 +1,171 @@ +package decor + +import ( + "fmt" + "io" + "math" + "time" + + "github.com/VividCortex/ewma" +) + +// FmtAsSpeed adds "/s" to the end of the input formatter. To be +// used with SizeB1000 or SizeB1024 types, for example: +// +// fmt.Printf("%.1f", FmtAsSpeed(SizeB1024(2048))) +// +func FmtAsSpeed(input fmt.Formatter) fmt.Formatter { + return &speedFormatter{input} +} + +type speedFormatter struct { + fmt.Formatter +} + +func (self *speedFormatter) Format(st fmt.State, verb rune) { + self.Formatter.Format(st, verb) + io.WriteString(st, "/s") +} + +// EwmaSpeed exponential-weighted-moving-average based speed decorator. +// For this decorator to work correctly you have to measure each +// iteration's duration and pass it to the +// *Bar.DecoratorEwmaUpdate(time.Duration) method after each increment. +func EwmaSpeed(unit int, format string, age float64, wcc ...WC) Decorator { + var average ewma.MovingAverage + if age == 0 { + average = ewma.NewMovingAverage() + } else { + average = ewma.NewMovingAverage(age) + } + return MovingAverageSpeed(unit, format, NewThreadSafeMovingAverage(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 ewma.MovingAverage, wcc ...WC) Decorator { + if format == "" { + format = "%.0f" + } + d := &movingAverageSpeed{ + WC: initWC(wcc...), + 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(s *Statistics) string { + if !s.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) EwmaUpdate(n int64, dur time.Duration) { + durPerByte := float64(dur) / 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 { + if format == "" { + format = "%.0f" + } + d := &averageSpeed{ + WC: initWC(wcc...), + 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(s *Statistics) string { + if !s.Completed { + speed := float64(s.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, FmtAsSpeed(SizeB1024(math.Round(speed)))) + } + case UnitKB: + return func(speed float64) string { + return fmt.Sprintf(format, FmtAsSpeed(SizeB1000(math.Round(speed)))) + } + default: + return func(speed float64) string { + return fmt.Sprintf(format, speed) + } + } +} diff --git a/vendor/github.com/vbauerster/mpb/v5/decor/spinner.go b/vendor/github.com/vbauerster/mpb/v5/decor/spinner.go new file mode 100644 index 000000000..abfb2f76c --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/decor/spinner.go @@ -0,0 +1,21 @@ +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 { + if len(frames) == 0 { + frames = defaultSpinnerStyle + } + var count uint + f := func(s *Statistics) string { + frame := frames[count%uint(len(frames))] + count++ + return frame + } + return Any(f, wcc...) +} diff --git a/vendor/github.com/vbauerster/mpb/v5/doc.go b/vendor/github.com/vbauerster/mpb/v5/doc.go new file mode 100644 index 000000000..5ada71774 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/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/v5/go.mod b/vendor/github.com/vbauerster/mpb/v5/go.mod new file mode 100644 index 000000000..672191fc8 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/go.mod @@ -0,0 +1,10 @@ +module github.com/vbauerster/mpb/v5 + +require ( + github.com/VividCortex/ewma v1.1.1 + github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d + golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 + golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect +) + +go 1.14 diff --git a/vendor/github.com/vbauerster/mpb/v5/go.sum b/vendor/github.com/vbauerster/mpb/v5/go.sum new file mode 100644 index 000000000..9a411976a --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/go.sum @@ -0,0 +1,13 @@ +github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM= +github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= +github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= +github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 h1:QmwruyY+bKbDDL0BaglrbZABEali68eoMFhTZpCjYVA= +golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/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-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/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/v5/internal/percentage.go b/vendor/github.com/vbauerster/mpb/v5/internal/percentage.go new file mode 100644 index 000000000..7e261cb22 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/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/v5/options.go b/vendor/github.com/vbauerster/mpb/v5/options.go new file mode 100644 index 000000000..048870284 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/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 + } +} + +// ContainerOptOn returns option when condition evaluates to true. +func ContainerOptOn(option ContainerOption, condition func() bool) ContainerOption { + if condition() { + return option + } + return nil +} diff --git a/vendor/github.com/vbauerster/mpb/v5/priority_queue.go b/vendor/github.com/vbauerster/mpb/v5/priority_queue.go new file mode 100644 index 000000000..29d9bd5a8 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/priority_queue.go @@ -0,0 +1,32 @@ +package mpb + +// A priorityQueue implements heap.Interface +type priorityQueue []*Bar + +func (pq priorityQueue) Len() int { return len(pq) } + +func (pq priorityQueue) Less(i, j int) bool { + return pq[i].priority < pq[j].priority +} + +func (pq priorityQueue) Swap(i, j int) { + pq[i], pq[j] = pq[j], pq[i] + pq[i].index = i + pq[j].index = j +} + +func (pq *priorityQueue) Push(x interface{}) { + s := *pq + bar := x.(*Bar) + bar.index = len(s) + s = append(s, bar) + *pq = s +} + +func (pq *priorityQueue) Pop() interface{} { + s := *pq + *pq = s[0 : len(s)-1] + bar := s[len(s)-1] + bar.index = -1 // for safety + return bar +} diff --git a/vendor/github.com/vbauerster/mpb/v5/progress.go b/vendor/github.com/vbauerster/mpb/v5/progress.go new file mode 100644 index 000000000..a366b9295 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/progress.go @@ -0,0 +1,399 @@ +package mpb + +import ( + "bytes" + "container/heap" + "context" + "fmt" + "io" + "io/ioutil" + "log" + "os" + "sync" + "time" + + "github.com/vbauerster/mpb/v5/cwriter" + "github.com/vbauerster/mpb/v5/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 it to the rendering queue. +func (p *Progress) AddBar(total int64, options ...BarOption) *Bar { + return p.Add(total, NewBarFiller(DefaultBarStyle, false), options...) +} + +// AddSpinner creates a new spinner bar and adds it to the rendering queue. +func (p *Progress) AddSpinner(total int64, alignment SpinnerAlignment, options ...BarOption) *Bar { + return p.Add(total, NewSpinnerFiller(DefaultSpinnerStyle, alignment), options...) +} + +// Add creates a bar which renders itself by provided filler. +// Set total to 0, if you plan to update it later. +// Panics if *Progress instance is done, i.e. called after *Progress.Wait(). +func (p *Progress) Add(total int64, filler BarFiller, 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() + panic(fmt.Sprintf("%T instance can't be reused after it's done!", p)) + } +} + +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(int). +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 BarFiller, 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 BarFiller) BarFiller { + type wrapper interface { + Base() BarFiller + } + if f, ok := f.(wrapper); ok { + return extractBaseFiller(f.Base()) + } + return f +} diff --git a/vendor/github.com/vbauerster/mpb/v5/proxyreader.go b/vendor/github.com/vbauerster/mpb/v5/proxyreader.go new file mode 100644 index 000000000..316f438d7 --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/proxyreader.go @@ -0,0 +1,90 @@ +package mpb + +import ( + "io" + "io/ioutil" + "time" +) + +type proxyReader struct { + io.ReadCloser + bar *Bar +} + +func (x *proxyReader) Read(p []byte) (int, error) { + n, err := x.ReadCloser.Read(p) + x.bar.IncrBy(n) + if err == io.EOF { + go x.bar.SetTotal(0, true) + } + return n, err +} + +type proxyWriterTo struct { + io.ReadCloser // *proxyReader + wt io.WriterTo + bar *Bar +} + +func (x *proxyWriterTo) WriteTo(w io.Writer) (int64, error) { + n, err := x.wt.WriteTo(w) + x.bar.IncrInt64(n) + if err == io.EOF { + go x.bar.SetTotal(0, true) + } + return n, err +} + +type ewmaProxyReader struct { + io.ReadCloser // *proxyReader + bar *Bar + iT time.Time +} + +func (x *ewmaProxyReader) Read(p []byte) (int, error) { + n, err := x.ReadCloser.Read(p) + if n > 0 { + x.bar.DecoratorEwmaUpdate(time.Since(x.iT)) + x.iT = time.Now() + } + return n, err +} + +type ewmaProxyWriterTo struct { + io.ReadCloser // *ewmaProxyReader + wt io.WriterTo // *proxyWriterTo + bar *Bar + iT time.Time +} + +func (x *ewmaProxyWriterTo) WriteTo(w io.Writer) (int64, error) { + n, err := x.wt.WriteTo(w) + if n > 0 { + x.bar.DecoratorEwmaUpdate(time.Since(x.iT)) + x.iT = time.Now() + } + return n, err +} + +func newProxyReader(r io.Reader, bar *Bar) io.ReadCloser { + rc := toReadCloser(r) + rc = &proxyReader{rc, bar} + + if wt, isWriterTo := r.(io.WriterTo); bar.hasEwmaDecorators { + now := time.Now() + rc = &ewmaProxyReader{rc, bar, now} + if isWriterTo { + rc = &ewmaProxyWriterTo{rc, wt, bar, now} + } + } else if isWriterTo { + rc = &proxyWriterTo{rc, wt, bar} + } + return rc +} + +func toReadCloser(r io.Reader) io.ReadCloser { + if rc, ok := r.(io.ReadCloser); ok { + return rc + } + return ioutil.NopCloser(r) +} diff --git a/vendor/github.com/vbauerster/mpb/v5/spinner_filler.go b/vendor/github.com/vbauerster/mpb/v5/spinner_filler.go new file mode 100644 index 000000000..517725fbf --- /dev/null +++ b/vendor/github.com/vbauerster/mpb/v5/spinner_filler.go @@ -0,0 +1,61 @@ +package mpb + +import ( + "io" + "strings" + "unicode/utf8" + + "github.com/vbauerster/mpb/v5/decor" +) + +// SpinnerAlignment enum. +type SpinnerAlignment int + +// SpinnerAlignment kinds. +const ( + SpinnerOnLeft SpinnerAlignment = iota + SpinnerOnMiddle + SpinnerOnRight +) + +// DefaultSpinnerStyle is a slice of strings, which makes a spinner. +var DefaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"} + +type spinnerFiller struct { + frames []string + count uint + alignment SpinnerAlignment +} + +// NewSpinnerFiller constucts mpb.BarFiller, to be used with *Progress.Add(...) *Bar method. +func NewSpinnerFiller(style []string, alignment SpinnerAlignment) BarFiller { + 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))] + frameWidth := utf8.RuneCountInString(frame) + + if width < frameWidth { + return + } + + switch rest := width - frameWidth; s.alignment { + case SpinnerOnLeft: + io.WriteString(w, frame+strings.Repeat(" ", rest)) + case SpinnerOnMiddle: + str := strings.Repeat(" ", rest/2) + frame + strings.Repeat(" ", rest/2+rest%2) + io.WriteString(w, str) + case SpinnerOnRight: + io.WriteString(w, strings.Repeat(" ", rest)+frame) + } + s.count++ +} -- cgit v1.2.3-54-g00ecf