mirror of
https://github.com/containers/skopeo.git
synced 2025-09-25 12:16:17 +00:00
Bump github.com/containers/image/v5 from 5.3.1 to 5.4.0
Bumps [github.com/containers/image/v5](https://github.com/containers/image) from 5.3.1 to 5.4.0. - [Release notes](https://github.com/containers/image/releases) - [Commits](https://github.com/containers/image/compare/v5.3.1...v5.4.0) Signed-off-by: dependabot-preview[bot] <support@dependabot.com> Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
committed by
Miloslav Trmač
parent
bd20786c38
commit
325327dc3f
5
vendor/github.com/vbauerster/mpb/v5/.gitignore
generated
vendored
Normal file
5
vendor/github.com/vbauerster/mpb/v5/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
8
vendor/github.com/vbauerster/mpb/v5/.travis.yml
generated
vendored
Normal file
8
vendor/github.com/vbauerster/mpb/v5/.travis.yml
generated
vendored
Normal file
@@ -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
|
118
vendor/github.com/vbauerster/mpb/v5/README.md
generated
vendored
Normal file
118
vendor/github.com/vbauerster/mpb/v5/README.md
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
# Multi Progress Bar
|
||||
|
||||
[](https://godoc.org/github.com/vbauerster/mpb)
|
||||
[](https://travis-ci.org/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)
|
||||
|
||||

|
||||
|
||||
#### [Complex example](_examples/complex/main.go)
|
||||
|
||||

|
||||
|
||||
#### [Bytes counters](_examples/io/main.go)
|
||||
|
||||

|
24
vendor/github.com/vbauerster/mpb/v5/UNLICENSE
generated
vendored
Normal file
24
vendor/github.com/vbauerster/mpb/v5/UNLICENSE
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
476
vendor/github.com/vbauerster/mpb/v5/bar.go
generated
vendored
Normal file
476
vendor/github.com/vbauerster/mpb/v5/bar.go
generated
vendored
Normal file
@@ -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)
|
||||
}
|
||||
}
|
138
vendor/github.com/vbauerster/mpb/v5/bar_filler.go
generated
vendored
Normal file
138
vendor/github.com/vbauerster/mpb/v5/bar_filler.go
generated
vendored
Normal file
@@ -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])
|
||||
}
|
||||
}
|
204
vendor/github.com/vbauerster/mpb/v5/bar_option.go
generated
vendored
Normal file
204
vendor/github.com/vbauerster/mpb/v5/bar_option.go
generated
vendored
Normal file
@@ -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
|
||||
}
|
71
vendor/github.com/vbauerster/mpb/v5/cwriter/writer.go
generated
vendored
Normal file
71
vendor/github.com/vbauerster/mpb/v5/cwriter/writer.go
generated
vendored
Normal file
@@ -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
|
||||
}
|
9
vendor/github.com/vbauerster/mpb/v5/cwriter/writer_posix.go
generated
vendored
Normal file
9
vendor/github.com/vbauerster/mpb/v5/cwriter/writer_posix.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// +build !windows
|
||||
|
||||
package cwriter
|
||||
|
||||
import "fmt"
|
||||
|
||||
func (w *Writer) clearLines() {
|
||||
fmt.Fprintf(w.out, cuuAndEd, w.lineCount)
|
||||
}
|
60
vendor/github.com/vbauerster/mpb/v5/cwriter/writer_windows.go
generated
vendored
Normal file
60
vendor/github.com/vbauerster/mpb/v5/cwriter/writer_windows.go
generated
vendored
Normal file
@@ -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))))
|
||||
}
|
21
vendor/github.com/vbauerster/mpb/v5/decor/any.go
generated
vendored
Normal file
21
vendor/github.com/vbauerster/mpb/v5/decor/any.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
package decor
|
||||
|
||||
// Any decorator displays text, that can be changed during decorator's
|
||||
// lifetime via provided func call back.
|
||||
//
|
||||
// `f` call back which provides string to display
|
||||
//
|
||||
// `wcc` optional WC config
|
||||
//
|
||||
func Any(f func(*Statistics) string, wcc ...WC) Decorator {
|
||||
return &any{initWC(wcc...), f}
|
||||
}
|
||||
|
||||
type any struct {
|
||||
WC
|
||||
f func(*Statistics) string
|
||||
}
|
||||
|
||||
func (d *any) Decor(s *Statistics) string {
|
||||
return d.FormatMsg(d.f(s))
|
||||
}
|
67
vendor/github.com/vbauerster/mpb/v5/decor/counters.go
generated
vendored
Normal file
67
vendor/github.com/vbauerster/mpb/v5/decor/counters.go
generated
vendored
Normal file
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
184
vendor/github.com/vbauerster/mpb/v5/decor/decorator.go
generated
vendored
Normal file
184
vendor/github.com/vbauerster/mpb/v5/decor/decorator.go
generated
vendored
Normal file
@@ -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()
|
||||
}
|
21
vendor/github.com/vbauerster/mpb/v5/decor/doc.go
generated
vendored
Normal file
21
vendor/github.com/vbauerster/mpb/v5/decor/doc.go
generated
vendored
Normal file
@@ -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
|
35
vendor/github.com/vbauerster/mpb/v5/decor/elapsed.go
generated
vendored
Normal file
35
vendor/github.com/vbauerster/mpb/v5/decor/elapsed.go
generated
vendored
Normal file
@@ -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...)
|
||||
}
|
203
vendor/github.com/vbauerster/mpb/v5/decor/eta.go
generated
vendored
Normal file
203
vendor/github.com/vbauerster/mpb/v5/decor/eta.go
generated
vendored
Normal file
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
106
vendor/github.com/vbauerster/mpb/v5/decor/merge.go
generated
vendored
Normal file
106
vendor/github.com/vbauerster/mpb/v5/decor/merge.go
generated
vendored
Normal file
@@ -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 ""
|
||||
}
|
68
vendor/github.com/vbauerster/mpb/v5/decor/moving_average.go
generated
vendored
Normal file
68
vendor/github.com/vbauerster/mpb/v5/decor/moving_average.go
generated
vendored
Normal file
@@ -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))
|
||||
}
|
12
vendor/github.com/vbauerster/mpb/v5/decor/name.go
generated
vendored
Normal file
12
vendor/github.com/vbauerster/mpb/v5/decor/name.go
generated
vendored
Normal file
@@ -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...)
|
||||
}
|
37
vendor/github.com/vbauerster/mpb/v5/decor/on_complete.go
generated
vendored
Normal file
37
vendor/github.com/vbauerster/mpb/v5/decor/on_complete.go
generated
vendored
Normal file
@@ -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
|
||||
}
|
58
vendor/github.com/vbauerster/mpb/v5/decor/percentage.go
generated
vendored
Normal file
58
vendor/github.com/vbauerster/mpb/v5/decor/percentage.go
generated
vendored
Normal file
@@ -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...)
|
||||
}
|
109
vendor/github.com/vbauerster/mpb/v5/decor/size_type.go
generated
vendored
Normal file
109
vendor/github.com/vbauerster/mpb/v5/decor/size_type.go
generated
vendored
Normal file
@@ -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())
|
||||
}
|
41
vendor/github.com/vbauerster/mpb/v5/decor/sizeb1000_string.go
generated
vendored
Normal file
41
vendor/github.com/vbauerster/mpb/v5/decor/sizeb1000_string.go
generated
vendored
Normal file
@@ -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) + ")"
|
||||
}
|
||||
}
|
41
vendor/github.com/vbauerster/mpb/v5/decor/sizeb1024_string.go
generated
vendored
Normal file
41
vendor/github.com/vbauerster/mpb/v5/decor/sizeb1024_string.go
generated
vendored
Normal file
@@ -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) + ")"
|
||||
}
|
||||
}
|
171
vendor/github.com/vbauerster/mpb/v5/decor/speed.go
generated
vendored
Normal file
171
vendor/github.com/vbauerster/mpb/v5/decor/speed.go
generated
vendored
Normal file
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
21
vendor/github.com/vbauerster/mpb/v5/decor/spinner.go
generated
vendored
Normal file
21
vendor/github.com/vbauerster/mpb/v5/decor/spinner.go
generated
vendored
Normal file
@@ -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...)
|
||||
}
|
2
vendor/github.com/vbauerster/mpb/v5/doc.go
generated
vendored
Normal file
2
vendor/github.com/vbauerster/mpb/v5/doc.go
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
// Package mpb is a library for rendering progress bars in terminal applications.
|
||||
package mpb
|
10
vendor/github.com/vbauerster/mpb/v5/go.mod
generated
vendored
Normal file
10
vendor/github.com/vbauerster/mpb/v5/go.mod
generated
vendored
Normal file
@@ -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
|
13
vendor/github.com/vbauerster/mpb/v5/go.sum
generated
vendored
Normal file
13
vendor/github.com/vbauerster/mpb/v5/go.sum
generated
vendored
Normal file
@@ -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=
|
15
vendor/github.com/vbauerster/mpb/v5/internal/percentage.go
generated
vendored
Normal file
15
vendor/github.com/vbauerster/mpb/v5/internal/percentage.go
generated
vendored
Normal file
@@ -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))
|
||||
}
|
105
vendor/github.com/vbauerster/mpb/v5/options.go
generated
vendored
Normal file
105
vendor/github.com/vbauerster/mpb/v5/options.go
generated
vendored
Normal file
@@ -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
|
||||
}
|
32
vendor/github.com/vbauerster/mpb/v5/priority_queue.go
generated
vendored
Normal file
32
vendor/github.com/vbauerster/mpb/v5/priority_queue.go
generated
vendored
Normal file
@@ -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
|
||||
}
|
399
vendor/github.com/vbauerster/mpb/v5/progress.go
generated
vendored
Normal file
399
vendor/github.com/vbauerster/mpb/v5/progress.go
generated
vendored
Normal file
@@ -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
|
||||
}
|
90
vendor/github.com/vbauerster/mpb/v5/proxyreader.go
generated
vendored
Normal file
90
vendor/github.com/vbauerster/mpb/v5/proxyreader.go
generated
vendored
Normal file
@@ -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)
|
||||
}
|
61
vendor/github.com/vbauerster/mpb/v5/spinner_filler.go
generated
vendored
Normal file
61
vendor/github.com/vbauerster/mpb/v5/spinner_filler.go
generated
vendored
Normal file
@@ -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++
|
||||
}
|
Reference in New Issue
Block a user