vendor containers/image v1.4

This requires some additional changes to the dependencies since the
progress-bar library has been changed to github.com/vbauerster/mpb.

Please refer to the following link for the release notes:
https://github.com/containers/image/releases/tag/v1.4

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
Valentin Rothberg
2019-02-21 11:54:04 +01:00
parent 4934bf2327
commit c069d11759
62 changed files with 3171 additions and 2531 deletions

29
vendor/github.com/vbauerster/mpb/LICENSE generated vendored Normal file
View File

@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (C) 2016-2018 Vladimir Bauer
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

117
vendor/github.com/vbauerster/mpb/README.md generated vendored Normal file
View File

@ -0,0 +1,117 @@
# Multi Progress Bar
[![GoDoc](https://godoc.org/github.com/vbauerster/mpb?status.svg)](https://godoc.org/github.com/vbauerster/mpb)
[![Build Status](https://travis-ci.org/vbauerster/mpb.svg?branch=master)](https://travis-ci.org/vbauerster/mpb)
[![Go Report Card](https://goreportcard.com/badge/github.com/vbauerster/mpb)](https://goreportcard.com/report/github.com/vbauerster/mpb)
[![codecov](https://codecov.io/gh/vbauerster/mpb/branch/master/graph/badge.svg)](https://codecov.io/gh/vbauerster/mpb)
**mpb** is a Go lib for rendering progress bars in terminal applications.
## Features
* __Multiple Bars__: Multiple progress bars are supported
* __Dynamic Total__: [Set total](https://github.com/vbauerster/mpb/issues/9#issuecomment-344448984) while bar is running
* __Dynamic Add/Remove__: Dynamically add or remove bars
* __Cancellation__: Cancel whole rendering process
* __Predefined Decorators__: Elapsed time, [ewma](https://github.com/VividCortex/ewma) based ETA, Percentage, Bytes counter
* __Decorator's width sync__: Synchronized decorator's width among multiple bars
## Installation
```sh
go get github.com/vbauerster/mpb
```
_Note:_ it is preferable to go get from github.com, rather than gopkg.in. See issue [#11](https://github.com/vbauerster/mpb/issues/11).
## Usage
#### [Rendering single bar](examples/singleBar/main.go)
```go
p := mpb.New(
// override default (80) width
mpb.WithWidth(64),
// override default "[=>-]" format
mpb.WithFormat("╢▌▌░╟"),
// override default 120ms refresh rate
mpb.WithRefreshRate(180*time.Millisecond),
)
total := 100
name := "Single Bar:"
// adding a single bar
bar := p.AddBar(int64(total),
mpb.PrependDecorators(
// display our name with one space on the right
decor.Name(name, decor.WC{W: len(name) + 1, C: decor.DidentRight}),
// replace ETA decorator with "done" message, OnComplete event
decor.OnComplete(
// ETA decorator with ewma age of 60, and width reservation of 4
decor.EwmaETA(decor.ET_STYLE_GO, 60, decor.WC{W: 4}), "done",
),
),
mpb.AppendDecorators(decor.Percentage()),
)
// simulating some work
max := 100 * time.Millisecond
for i := 0; i < total; i++ {
start := time.Now()
time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10)
// ewma based decorators require work duration measurement
bar.IncrBy(1, time.Since(start))
}
// wait for our bar to complete and flush
p.Wait()
```
#### [Rendering multiple bars](examples/simple/main.go)
```go
var wg sync.WaitGroup
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()
max := 100 * time.Millisecond
for i := 0; i < total; i++ {
start := time.Now()
time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10)
// ewma based decorators require work duration measurement
bar.IncrBy(1, time.Since(start))
}
}()
}
// wait for all bars to complete and flush
p.Wait()
```
#### [Dynamic total](examples/dynTotal/main.go)
![dynamic total](examples/gifs/godEMrCZmJkHYH1X9dN4Nm0U7.svg)
#### [Complex example](examples/complex/main.go)
![complex](examples/gifs/wHzf1M7sd7B3zVa2scBMnjqRf.svg)
#### [Bytes counters](examples/io/single/main.go)
![byte counters](examples/gifs/hIpTa3A5rQz65ssiVuRJu87X6.svg)

455
vendor/github.com/vbauerster/mpb/bar.go generated vendored Normal file
View File

@ -0,0 +1,455 @@
package mpb
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"strings"
"sync"
"time"
"unicode/utf8"
"github.com/vbauerster/mpb/decor"
"github.com/vbauerster/mpb/internal"
)
const (
rLeft = iota
rFill
rTip
rEmpty
rRight
)
const formatLen = 5
type barRunes [formatLen]rune
// Bar represents a progress Bar
type Bar struct {
priority int
index int
runningBar *Bar
cacheState *bState
operateState chan func(*bState)
int64Ch chan int64
boolCh chan bool
frameReaderCh chan *frameReader
syncTableCh chan [][]chan int
// done is closed by Bar's goroutine, after cacheState is written
done chan struct{}
// shutdown is closed from master Progress goroutine only
shutdown chan struct{}
}
type (
bState struct {
id int
width int
total int64
current int64
runes barRunes
trimLeftSpace bool
trimRightSpace bool
toComplete bool
removeOnComplete bool
barClearOnComplete bool
completeFlushed bool
aDecorators []decor.Decorator
pDecorators []decor.Decorator
amountReceivers []decor.AmountReceiver
shutdownListeners []decor.ShutdownListener
refill *refill
bufP, bufB, bufA *bytes.Buffer
bufNL *bytes.Buffer
panicMsg string
newLineExtendFn func(io.Writer, *decor.Statistics)
// following options are assigned to the *Bar
priority int
runningBar *Bar
}
refill struct {
char rune
till int64
}
frameReader struct {
io.Reader
extendedLines int
toShutdown bool
removeOnComplete bool
}
)
func newBar(wg *sync.WaitGroup, id int, total int64, cancel <-chan struct{}, options ...BarOption) *Bar {
if total <= 0 {
total = time.Now().Unix()
}
s := &bState{
id: id,
priority: id,
total: total,
}
for _, opt := range options {
if opt != nil {
opt(s)
}
}
s.bufP = bytes.NewBuffer(make([]byte, 0, s.width))
s.bufB = bytes.NewBuffer(make([]byte, 0, s.width))
s.bufA = bytes.NewBuffer(make([]byte, 0, s.width))
b := &Bar{
priority: s.priority,
runningBar: s.runningBar,
operateState: make(chan func(*bState)),
int64Ch: make(chan int64),
boolCh: make(chan bool),
frameReaderCh: make(chan *frameReader, 1),
syncTableCh: make(chan [][]chan int),
done: make(chan struct{}),
shutdown: make(chan struct{}),
}
if b.runningBar != nil {
b.priority = b.runningBar.priority
}
if s.newLineExtendFn != nil {
s.bufNL = bytes.NewBuffer(make([]byte, 0, s.width))
}
go b.serve(wg, s, cancel)
return b
}
// RemoveAllPrependers removes all prepend functions.
func (b *Bar) RemoveAllPrependers() {
select {
case b.operateState <- func(s *bState) { s.pDecorators = nil }:
case <-b.done:
}
}
// RemoveAllAppenders removes all append functions.
func (b *Bar) RemoveAllAppenders() {
select {
case b.operateState <- func(s *bState) { s.aDecorators = nil }:
case <-b.done:
}
}
// ProxyReader wraps r with metrics required for progress tracking.
func (b *Bar) ProxyReader(r io.Reader) io.ReadCloser {
if r == nil {
panic("expect io.Reader, got nil")
}
rc, ok := r.(io.ReadCloser)
if !ok {
rc = ioutil.NopCloser(r)
}
return &proxyReader{rc, b, time.Now()}
}
// ID returs id of the bar.
func (b *Bar) ID() int {
select {
case b.operateState <- func(s *bState) { b.int64Ch <- int64(s.id) }:
return int(<-b.int64Ch)
case <-b.done:
return b.cacheState.id
}
}
// Current returns bar's current number, in other words sum of all increments.
func (b *Bar) Current() int64 {
select {
case b.operateState <- func(s *bState) { b.int64Ch <- s.current }:
return <-b.int64Ch
case <-b.done:
return b.cacheState.current
}
}
// SetTotal sets total dynamically.
// Set final to true, when total is known, it will trigger bar complete event.
func (b *Bar) SetTotal(total int64, final bool) bool {
select {
case b.operateState <- func(s *bState) {
if total > 0 {
s.total = total
}
if final {
s.current = s.total
s.toComplete = true
}
}:
return true
case <-b.done:
return false
}
}
// SetRefill sets fill rune to r, up until n.
func (b *Bar) SetRefill(n int, r rune) {
if n <= 0 {
return
}
b.operateState <- func(s *bState) {
s.refill = &refill{r, int64(n)}
}
}
// RefillBy is deprecated, use SetRefill
func (b *Bar) RefillBy(n int, r rune) {
b.SetRefill(n, r)
}
// Increment is a shorthand for b.IncrBy(1).
func (b *Bar) Increment() {
b.IncrBy(1)
}
// IncrBy increments progress bar by amount of n.
// wdd is optional work duration i.e. time.Since(start),
// which expected to be provided, if any ewma based decorator is used.
func (b *Bar) IncrBy(n int, wdd ...time.Duration) {
select {
case b.operateState <- func(s *bState) {
s.current += int64(n)
if s.current >= s.total {
s.current = s.total
s.toComplete = true
}
for _, ar := range s.amountReceivers {
ar.NextAmount(n, wdd...)
}
}:
case <-b.done:
}
}
// Completed reports whether the bar is in completed state.
func (b *Bar) Completed() bool {
// omit select here, because primary usage of the method is for loop
// condition, like for !bar.Completed() {...}
// so when toComplete=true it is called once (at which time, the bar is still alive),
// then quits the loop and never suppose to be called afterwards.
return <-b.boolCh
}
func (b *Bar) wSyncTable() [][]chan int {
select {
case b.operateState <- func(s *bState) { b.syncTableCh <- s.wSyncTable() }:
return <-b.syncTableCh
case <-b.done:
return b.cacheState.wSyncTable()
}
}
func (b *Bar) serve(wg *sync.WaitGroup, s *bState, cancel <-chan struct{}) {
defer wg.Done()
for {
select {
case op := <-b.operateState:
op(s)
case b.boolCh <- s.toComplete:
case <-cancel:
s.toComplete = true
cancel = nil
case <-b.shutdown:
b.cacheState = s
close(b.done)
for _, sl := range s.shutdownListeners {
sl.Shutdown()
}
return
}
}
}
func (b *Bar) render(debugOut io.Writer, tw int) {
select {
case b.operateState <- func(s *bState) {
defer func() {
// recovering if user defined decorator panics for example
if p := recover(); p != nil {
s.panicMsg = fmt.Sprintf("panic: %v", p)
fmt.Fprintf(debugOut, "%s %s bar id %02d %v\n", "[mpb]", time.Now(), s.id, s.panicMsg)
b.frameReaderCh <- &frameReader{
Reader: strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%ds\n", tw), s.panicMsg)),
toShutdown: true,
}
}
}()
r := s.draw(tw)
var extendedLines int
if s.newLineExtendFn != nil {
s.bufNL.Reset()
s.newLineExtendFn(s.bufNL, newStatistics(s))
extendedLines = countLines(s.bufNL.Bytes())
r = io.MultiReader(r, s.bufNL)
}
b.frameReaderCh <- &frameReader{
Reader: r,
extendedLines: extendedLines,
toShutdown: s.toComplete && !s.completeFlushed,
removeOnComplete: s.removeOnComplete,
}
s.completeFlushed = s.toComplete
}:
case <-b.done:
s := b.cacheState
r := s.draw(tw)
var extendedLines int
if s.newLineExtendFn != nil {
s.bufNL.Reset()
s.newLineExtendFn(s.bufNL, newStatistics(s))
extendedLines = countLines(s.bufNL.Bytes())
r = io.MultiReader(r, s.bufNL)
}
b.frameReaderCh <- &frameReader{
Reader: r,
extendedLines: extendedLines,
}
}
}
func (s *bState) draw(termWidth int) io.Reader {
defer s.bufA.WriteByte('\n')
if s.panicMsg != "" {
return strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%ds\n", termWidth), s.panicMsg))
}
stat := newStatistics(s)
for _, d := range s.pDecorators {
s.bufP.WriteString(d.Decor(stat))
}
for _, d := range s.aDecorators {
s.bufA.WriteString(d.Decor(stat))
}
prependCount := utf8.RuneCount(s.bufP.Bytes())
appendCount := utf8.RuneCount(s.bufA.Bytes())
if s.barClearOnComplete && s.completeFlushed {
return io.MultiReader(s.bufP, s.bufA)
}
s.fillBar(s.width)
barCount := utf8.RuneCount(s.bufB.Bytes())
totalCount := prependCount + barCount + appendCount
if spaceCount := 0; totalCount > termWidth {
if !s.trimLeftSpace {
spaceCount++
}
if !s.trimRightSpace {
spaceCount++
}
s.fillBar(termWidth - prependCount - appendCount - spaceCount)
}
return io.MultiReader(s.bufP, s.bufB, s.bufA)
}
func (s *bState) fillBar(width int) {
defer func() {
s.bufB.WriteRune(s.runes[rRight])
if !s.trimRightSpace {
s.bufB.WriteByte(' ')
}
}()
s.bufB.Reset()
if !s.trimLeftSpace {
s.bufB.WriteByte(' ')
}
s.bufB.WriteRune(s.runes[rLeft])
if width <= 2 {
return
}
// bar s.width without leftEnd and rightEnd runes
barWidth := width - 2
completedWidth := internal.Percentage(s.total, s.current, int64(barWidth))
if s.refill != nil {
till := internal.Percentage(s.total, s.refill.till, int64(barWidth))
// append refill rune
var i int64
for i = 0; i < till; i++ {
s.bufB.WriteRune(s.refill.char)
}
for i = till; i < completedWidth; i++ {
s.bufB.WriteRune(s.runes[rFill])
}
} else {
var i int64
for i = 0; i < completedWidth; i++ {
s.bufB.WriteRune(s.runes[rFill])
}
}
if completedWidth < int64(barWidth) && completedWidth > 0 {
_, size := utf8.DecodeLastRune(s.bufB.Bytes())
s.bufB.Truncate(s.bufB.Len() - size)
s.bufB.WriteRune(s.runes[rTip])
}
for i := completedWidth; i < int64(barWidth); i++ {
s.bufB.WriteRune(s.runes[rEmpty])
}
}
func (s *bState) wSyncTable() [][]chan int {
columns := make([]chan int, 0, len(s.pDecorators)+len(s.aDecorators))
var pCount int
for _, d := range s.pDecorators {
if ok, ch := d.Syncable(); ok {
columns = append(columns, ch)
pCount++
}
}
var aCount int
for _, d := range s.aDecorators {
if ok, ch := d.Syncable(); ok {
columns = append(columns, ch)
aCount++
}
}
table := make([][]chan int, 2)
table[0] = columns[0:pCount]
table[1] = columns[pCount : pCount+aCount : pCount+aCount]
return table
}
func newStatistics(s *bState) *decor.Statistics {
return &decor.Statistics{
ID: s.id,
Completed: s.completeFlushed,
Total: s.total,
Current: s.current,
}
}
func strToBarRunes(format string) (array barRunes) {
for i, n := 0, 0; len(format) > 0; i++ {
array[i], n = utf8.DecodeRuneInString(format)
format = format[n:]
}
return
}
func countLines(b []byte) int {
return bytes.Count(b, []byte("\n"))
}

124
vendor/github.com/vbauerster/mpb/bar_option.go generated vendored Normal file
View File

@ -0,0 +1,124 @@
package mpb
import (
"io"
"github.com/vbauerster/mpb/decor"
)
// BarOption is a function option which changes the default behavior of a bar,
// if passed to p.AddBar(int64, ...BarOption)
type BarOption func(*bState)
// AppendDecorators let you inject decorators to the bar's right side
func AppendDecorators(appenders ...decor.Decorator) BarOption {
return func(s *bState) {
for _, decorator := range appenders {
if ar, ok := decorator.(decor.AmountReceiver); ok {
s.amountReceivers = append(s.amountReceivers, ar)
}
if sl, ok := decorator.(decor.ShutdownListener); ok {
s.shutdownListeners = append(s.shutdownListeners, sl)
}
s.aDecorators = append(s.aDecorators, decorator)
}
}
}
// PrependDecorators let you inject decorators to the bar's left side
func PrependDecorators(prependers ...decor.Decorator) BarOption {
return func(s *bState) {
for _, decorator := range prependers {
if ar, ok := decorator.(decor.AmountReceiver); ok {
s.amountReceivers = append(s.amountReceivers, ar)
}
if sl, ok := decorator.(decor.ShutdownListener); ok {
s.shutdownListeners = append(s.shutdownListeners, sl)
}
s.pDecorators = append(s.pDecorators, decorator)
}
}
}
// BarTrimLeft trims left side space of the bar
func BarTrimLeft() BarOption {
return func(s *bState) {
s.trimLeftSpace = true
}
}
// BarTrimRight trims right space of the bar
func BarTrimRight() BarOption {
return func(s *bState) {
s.trimRightSpace = true
}
}
// BarTrim trims both left and right spaces of the bar
func BarTrim() BarOption {
return func(s *bState) {
s.trimLeftSpace = true
s.trimRightSpace = true
}
}
// BarID overwrites internal bar id
func BarID(id int) BarOption {
return func(s *bState) {
s.id = id
}
}
// BarRemoveOnComplete is a flag, if set whole bar line will be removed on complete event.
// If both BarRemoveOnComplete and BarClearOnComplete are set, first bar section gets cleared
// and then whole bar line gets removed completely.
func BarRemoveOnComplete() BarOption {
return func(s *bState) {
s.removeOnComplete = true
}
}
// BarReplaceOnComplete is indicator for delayed bar start, after the `runningBar` is complete.
// To achieve bar replacement effect, `runningBar` should has its `BarRemoveOnComplete` option set.
func BarReplaceOnComplete(runningBar *Bar) BarOption {
return func(s *bState) {
s.runningBar = runningBar
}
}
// BarClearOnComplete is a flag, if set will clear bar section on complete event.
// If you need to remove a whole bar line, refer to BarRemoveOnComplete.
func BarClearOnComplete() BarOption {
return func(s *bState) {
s.barClearOnComplete = true
}
}
// BarPriority sets bar's priority.
// Zero is highest priority, i.e. bar will be on top.
// If `BarReplaceOnComplete` option is supplied, this option is ignored.
func BarPriority(priority int) BarOption {
return func(s *bState) {
s.priority = priority
}
}
// BarNewLineExtend takes user defined efn, which gets called each render cycle.
// Any write to provided writer of efn, will appear on new line of respective bar.
func BarNewLineExtend(efn func(io.Writer, *decor.Statistics)) BarOption {
return func(s *bState) {
s.newLineExtendFn = efn
}
}
func barWidth(w int) BarOption {
return func(s *bState) {
s.width = w
}
}
func barFormat(format string) BarOption {
return func(s *bState) {
s.runes = strToBarRunes(format)
}
}

78
vendor/github.com/vbauerster/mpb/cwriter/writer.go generated vendored Normal file
View File

@ -0,0 +1,78 @@
package cwriter
import (
"bytes"
"errors"
"fmt"
"io"
"os"
isatty "github.com/mattn/go-isatty"
"golang.org/x/crypto/ssh/terminal"
)
// ESC is the ASCII code for escape character
const ESC = 27
var NotATTY = errors.New("not a terminal")
var (
cursorUp = fmt.Sprintf("%c[%dA", ESC, 1)
clearLine = fmt.Sprintf("%c[2K\r", ESC)
clearCursorAndLine = cursorUp + clearLine
)
// Writer is a buffered the writer that updates the terminal.
// The contents of writer will be flushed when Flush is called.
type Writer struct {
out io.Writer
buf bytes.Buffer
isTerminal bool
fd int
lineCount int
}
// New returns a new Writer with defaults
func New(out io.Writer) *Writer {
w := &Writer{out: out}
if f, ok := out.(*os.File); ok {
fd := f.Fd()
w.isTerminal = isatty.IsTerminal(fd)
w.fd = int(fd)
}
return w
}
// Flush flushes the underlying buffer
func (w *Writer) Flush(lineCount int) error {
err := w.clearLines()
w.lineCount = lineCount
// WriteTo takes care of w.buf.Reset
if _, e := w.buf.WriteTo(w.out); err == nil {
err = e
}
return err
}
// 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)
}
func (w *Writer) GetWidth() (int, error) {
if w.isTerminal {
tw, _, err := terminal.GetSize(w.fd)
return tw, err
}
return -1, NotATTY
}

View File

@ -0,0 +1,13 @@
// +build !windows
package cwriter
import (
"io"
"strings"
)
func (w *Writer) clearLines() error {
_, err := io.WriteString(w.out, strings.Repeat(clearCursorAndLine, w.lineCount))
return err
}

View File

@ -0,0 +1,77 @@
// +build windows
package cwriter
import (
"io"
"strings"
"syscall"
"unsafe"
"github.com/mattn/go-isatty"
)
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
var (
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute")
)
type (
short int16
word uint16
dword uint32
coord struct {
x short
y short
}
smallRect struct {
left short
top short
right short
bottom short
}
consoleScreenBufferInfo struct {
size coord
cursorPosition coord
attributes word
window smallRect
maximumWindowSize coord
}
)
// FdWriter is a writer with a file descriptor.
type FdWriter interface {
io.Writer
Fd() uintptr
}
func (w *Writer) clearLines() error {
f, ok := w.out.(FdWriter)
if ok && !isatty.IsTerminal(f.Fd()) {
_, err := io.WriteString(w.out, strings.Repeat(clearCursorAndLine, w.lineCount))
return err
}
fd := f.Fd()
var info consoleScreenBufferInfo
procGetConsoleScreenBufferInfo.Call(fd, uintptr(unsafe.Pointer(&info)))
for i := 0; i < w.lineCount; i++ {
// move the cursor up
info.cursorPosition.y--
procSetConsoleCursorPosition.Call(fd, uintptr(*(*int32)(unsafe.Pointer(&info.cursorPosition))))
// clear the line
cursor := coord{
x: info.window.left,
y: info.window.top + info.cursorPosition.y,
}
var count, w dword
count = dword(info.size.x)
procFillConsoleOutputCharacter.Call(fd, uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&w)))
}
return nil
}

206
vendor/github.com/vbauerster/mpb/decor/counters.go generated vendored Normal file
View File

@ -0,0 +1,206 @@
package decor
import (
"fmt"
"io"
"strconv"
"strings"
)
const (
_ = iota
KiB = 1 << (iota * 10)
MiB
GiB
TiB
)
const (
KB = 1000
MB = KB * 1000
GB = MB * 1000
TB = GB * 1000
)
const (
_ = iota
UnitKiB
UnitKB
)
type CounterKiB int64
func (c CounterKiB) Format(st fmt.State, verb rune) {
prec, ok := st.Precision()
if verb == 'd' || !ok {
prec = 0
}
if verb == 'f' && !ok {
prec = 6
}
// retain old beahavior if s verb used
if verb == 's' {
prec = 1
}
var res, unit string
switch {
case c >= TiB:
unit = "TiB"
res = strconv.FormatFloat(float64(c)/TiB, 'f', prec, 64)
case c >= GiB:
unit = "GiB"
res = strconv.FormatFloat(float64(c)/GiB, 'f', prec, 64)
case c >= MiB:
unit = "MiB"
res = strconv.FormatFloat(float64(c)/MiB, 'f', prec, 64)
case c >= KiB:
unit = "KiB"
res = strconv.FormatFloat(float64(c)/KiB, 'f', prec, 64)
default:
unit = "b"
res = strconv.FormatInt(int64(c), 10)
}
if st.Flag(' ') {
res += " "
}
res += unit
if w, ok := st.Width(); ok {
if len(res) < w {
pad := strings.Repeat(" ", w-len(res))
if st.Flag(int('-')) {
res += pad
} else {
res = pad + res
}
}
}
io.WriteString(st, res)
}
type CounterKB int64
func (c CounterKB) Format(st fmt.State, verb rune) {
prec, ok := st.Precision()
if verb == 'd' || !ok {
prec = 0
}
if verb == 'f' && !ok {
prec = 6
}
// retain old beahavior if s verb used
if verb == 's' {
prec = 1
}
var res, unit string
switch {
case c >= TB:
unit = "TB"
res = strconv.FormatFloat(float64(c)/TB, 'f', prec, 64)
case c >= GB:
unit = "GB"
res = strconv.FormatFloat(float64(c)/GB, 'f', prec, 64)
case c >= MB:
unit = "MB"
res = strconv.FormatFloat(float64(c)/MB, 'f', prec, 64)
case c >= KB:
unit = "kB"
res = strconv.FormatFloat(float64(c)/KB, 'f', prec, 64)
default:
unit = "b"
res = strconv.FormatInt(int64(c), 10)
}
if st.Flag(' ') {
res += " "
}
res += unit
if w, ok := st.Width(); ok {
if len(res) < w {
pad := strings.Repeat(" ", w-len(res))
if st.Flag(int('-')) {
res += pad
} else {
res = pad + res
}
}
}
io.WriteString(st, res)
}
// CountersNoUnit is a wrapper around Counters with no unit param.
func CountersNoUnit(pairFormat string, wcc ...WC) Decorator {
return Counters(0, pairFormat, wcc...)
}
// CountersKibiByte is a wrapper around Counters with predefined unit UnitKiB (bytes/1024).
func CountersKibiByte(pairFormat string, wcc ...WC) Decorator {
return Counters(UnitKiB, pairFormat, wcc...)
}
// CountersKiloByte is a wrapper around Counters with predefined unit UnitKB (bytes/1000).
func CountersKiloByte(pairFormat string, wcc ...WC) Decorator {
return Counters(UnitKB, pairFormat, wcc...)
}
// Counters decorator with dynamic unit measure adjustment.
//
// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
//
// `pairFormat` printf compatible verbs for current and total, like "%f" or "%d"
//
// `wcc` optional WC config
//
// pairFormat example if UnitKB is chosen:
//
// "%.1f / %.1f" = "1.0MB / 12.0MB" or "% .1f / % .1f" = "1.0 MB / 12.0 MB"
func Counters(unit int, pairFormat string, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
wc.Init()
d := &countersDecorator{
WC: wc,
unit: unit,
pairFormat: pairFormat,
}
return d
}
type countersDecorator struct {
WC
unit int
pairFormat string
completeMsg *string
}
func (d *countersDecorator) Decor(st *Statistics) string {
if st.Completed && d.completeMsg != nil {
return d.FormatMsg(*d.completeMsg)
}
var str string
switch d.unit {
case UnitKiB:
str = fmt.Sprintf(d.pairFormat, CounterKiB(st.Current), CounterKiB(st.Total))
case UnitKB:
str = fmt.Sprintf(d.pairFormat, CounterKB(st.Current), CounterKB(st.Total))
default:
str = fmt.Sprintf(d.pairFormat, st.Current, st.Total)
}
return d.FormatMsg(str)
}
func (d *countersDecorator) OnCompleteMessage(msg string) {
d.completeMsg = &msg
}

144
vendor/github.com/vbauerster/mpb/decor/decorator.go generated vendored Normal file
View File

@ -0,0 +1,144 @@
package decor
import (
"fmt"
"time"
"unicode/utf8"
)
const (
// DidentRight bit specifies identation direction.
// |foo |b | With DidentRight
// | foo| b| Without DidentRight
DidentRight = 1 << iota
// DextraSpace bit adds extra space, makes sense with DSyncWidth only.
// When DidentRight bit set, the space will be added to the right,
// otherwise to the left.
DextraSpace
// DSyncWidth bit enables same column width synchronization.
// Effective with multiple bars only.
DSyncWidth
// DSyncWidthR is shortcut for DSyncWidth|DidentRight
DSyncWidthR = DSyncWidth | DidentRight
// DSyncSpace is shortcut for DSyncWidth|DextraSpace
DSyncSpace = DSyncWidth | DextraSpace
// DSyncSpaceR is shortcut for DSyncWidth|DextraSpace|DidentRight
DSyncSpaceR = DSyncWidth | DextraSpace | DidentRight
)
const (
ET_STYLE_GO = iota
ET_STYLE_HHMMSS
ET_STYLE_HHMM
ET_STYLE_MMSS
)
// Statistics is a struct, which gets passed to a Decorator.
type Statistics struct {
ID int
Completed bool
Total int64
Current int64
}
// Decorator interface.
// A decorator must implement this interface, in order to be used with mpb library.
type Decorator interface {
Decor(*Statistics) string
Syncable
}
// Syncable interface.
// All decorators implement this interface implicitly.
// Its Syncable method exposes width sync channel, if sync is enabled.
type Syncable interface {
Syncable() (bool, chan int)
}
// OnCompleteMessenger interface.
// Decorators implementing this interface suppose to return provided string on complete event.
type OnCompleteMessenger interface {
OnCompleteMessage(string)
}
// AmountReceiver interface.
// If decorator needs to receive increment amount,
// so this is the right interface to implement.
type AmountReceiver interface {
NextAmount(int, ...time.Duration)
}
// ShutdownListener interface.
// If decorator needs to be notified once upon bar shutdown event,
// so this is the right interface to implement.
type ShutdownListener interface {
Shutdown()
}
// Global convenience shortcuts
var (
WCSyncWidth = WC{C: DSyncWidth}
WCSyncWidthR = WC{C: DSyncWidthR}
WCSyncSpace = WC{C: DSyncSpace}
WCSyncSpaceR = WC{C: DSyncSpaceR}
)
// WC is a struct with two public fields W and C, both of int type.
// W represents width and C represents bit set of width related config.
type WC struct {
W int
C int
format string
wsync chan int
}
// FormatMsg formats final message according to WC.W and WC.C.
// Should be called by any Decorator implementation.
func (wc WC) FormatMsg(msg string) string {
if (wc.C & DSyncWidth) != 0 {
wc.wsync <- utf8.RuneCountInString(msg)
max := <-wc.wsync
if max == 0 {
max = wc.W
}
if (wc.C & DextraSpace) != 0 {
max++
}
return fmt.Sprintf(fmt.Sprintf(wc.format, max), msg)
}
return fmt.Sprintf(fmt.Sprintf(wc.format, wc.W), msg)
}
// Init initializes width related config.
func (wc *WC) Init() {
wc.format = "%%"
if (wc.C & DidentRight) != 0 {
wc.format += "-"
}
wc.format += "%ds"
if (wc.C & DSyncWidth) != 0 {
wc.wsync = make(chan int)
}
}
func (wc *WC) Syncable() (bool, chan int) {
return (wc.C & DSyncWidth) != 0, wc.wsync
}
// OnComplete returns decorator, which wraps provided decorator, with sole
// purpose to display provided message on complete event.
//
// `decorator` Decorator to wrap
//
// `message` message to display on complete event
func OnComplete(decorator Decorator, message string) Decorator {
if d, ok := decorator.(OnCompleteMessenger); ok {
d.OnCompleteMessage(message)
}
return decorator
}

25
vendor/github.com/vbauerster/mpb/decor/doc.go generated vendored Normal file
View File

@ -0,0 +1,25 @@
// Copyright (C) 2016-2018 Vladimir Bauer
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
Package decor contains common decorators used by "github.com/vbauerster/mpb" package.
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

68
vendor/github.com/vbauerster/mpb/decor/elapsed.go generated vendored Normal file
View File

@ -0,0 +1,68 @@
package decor
import (
"fmt"
"time"
)
// Elapsed returns elapsed time decorator.
//
// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
//
// `wcc` optional WC config
func Elapsed(style int, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
wc.Init()
d := &elapsedDecorator{
WC: wc,
style: style,
startTime: time.Now(),
}
return d
}
type elapsedDecorator struct {
WC
style int
startTime time.Time
msg string
completeMsg *string
}
func (d *elapsedDecorator) Decor(st *Statistics) string {
if st.Completed {
if d.completeMsg != nil {
return d.FormatMsg(*d.completeMsg)
}
return d.FormatMsg(d.msg)
}
timeElapsed := time.Since(d.startTime)
hours := int64((timeElapsed / time.Hour) % 60)
minutes := int64((timeElapsed / time.Minute) % 60)
seconds := int64((timeElapsed / time.Second) % 60)
switch d.style {
case ET_STYLE_GO:
d.msg = fmt.Sprint(time.Duration(timeElapsed.Seconds()) * time.Second)
case ET_STYLE_HHMMSS:
d.msg = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds)
case ET_STYLE_HHMM:
d.msg = fmt.Sprintf("%02d:%02d", hours, minutes)
case ET_STYLE_MMSS:
if hours > 0 {
d.msg = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds)
} else {
d.msg = fmt.Sprintf("%02d:%02d", minutes, seconds)
}
}
return d.FormatMsg(d.msg)
}
func (d *elapsedDecorator) OnCompleteMessage(msg string) {
d.completeMsg = &msg
}

207
vendor/github.com/vbauerster/mpb/decor/eta.go generated vendored Normal file
View File

@ -0,0 +1,207 @@
package decor
import (
"fmt"
"math"
"time"
"github.com/VividCortex/ewma"
"github.com/vbauerster/mpb/internal"
)
type TimeNormalizer func(time.Duration) time.Duration
// EwmaETA exponential-weighted-moving-average based ETA decorator.
//
// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
//
// `age` is the previous N samples to average over.
//
// `wcc` optional WC config
func EwmaETA(style int, age float64, wcc ...WC) Decorator {
return MovingAverageETA(style, ewma.NewMovingAverage(age), NopNormalizer(), wcc...)
}
// MovingAverageETA decorator relies on MovingAverage implementation to calculate its average.
//
// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
//
// `average` available implementations of MovingAverage [ewma.MovingAverage|NewMedian|NewMedianEwma]
//
// `normalizer` available implementations are [NopNormalizer|FixedIntervalTimeNormalizer|MaxTolerateTimeNormalizer]
//
// `wcc` optional WC config
func MovingAverageETA(style int, average MovingAverage, normalizer TimeNormalizer, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
wc.Init()
d := &movingAverageETA{
WC: wc,
style: style,
average: average,
normalizer: normalizer,
}
return d
}
type movingAverageETA struct {
WC
style int
average ewma.MovingAverage
completeMsg *string
normalizer TimeNormalizer
}
func (d *movingAverageETA) Decor(st *Statistics) string {
if st.Completed && d.completeMsg != nil {
return d.FormatMsg(*d.completeMsg)
}
v := internal.Round(d.average.Value())
remaining := d.normalizer(time.Duration((st.Total - st.Current) * int64(v)))
hours := int64((remaining / time.Hour) % 60)
minutes := int64((remaining / time.Minute) % 60)
seconds := int64((remaining / time.Second) % 60)
var str string
switch d.style {
case ET_STYLE_GO:
str = fmt.Sprint(time.Duration(remaining.Seconds()) * time.Second)
case ET_STYLE_HHMMSS:
str = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds)
case ET_STYLE_HHMM:
str = fmt.Sprintf("%02d:%02d", hours, minutes)
case ET_STYLE_MMSS:
if hours > 0 {
str = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds)
} else {
str = fmt.Sprintf("%02d:%02d", minutes, seconds)
}
}
return d.FormatMsg(str)
}
func (d *movingAverageETA) NextAmount(n int, wdd ...time.Duration) {
var workDuration time.Duration
for _, wd := range wdd {
workDuration = wd
}
lastItemEstimate := float64(workDuration) / float64(n)
if math.IsInf(lastItemEstimate, 0) || math.IsNaN(lastItemEstimate) {
return
}
d.average.Add(lastItemEstimate)
}
func (d *movingAverageETA) OnCompleteMessage(msg string) {
d.completeMsg = &msg
}
// AverageETA decorator.
//
// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
//
// `wcc` optional WC config
func AverageETA(style int, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
wc.Init()
d := &averageETA{
WC: wc,
style: style,
startTime: time.Now(),
}
return d
}
type averageETA struct {
WC
style int
startTime time.Time
completeMsg *string
}
func (d *averageETA) Decor(st *Statistics) string {
if st.Completed && d.completeMsg != nil {
return d.FormatMsg(*d.completeMsg)
}
var str string
timeElapsed := time.Since(d.startTime)
v := internal.Round(float64(timeElapsed) / float64(st.Current))
if math.IsInf(v, 0) || math.IsNaN(v) {
v = 0
}
remaining := time.Duration((st.Total - st.Current) * int64(v))
hours := int64((remaining / time.Hour) % 60)
minutes := int64((remaining / time.Minute) % 60)
seconds := int64((remaining / time.Second) % 60)
switch d.style {
case ET_STYLE_GO:
str = fmt.Sprint(time.Duration(remaining.Seconds()) * time.Second)
case ET_STYLE_HHMMSS:
str = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds)
case ET_STYLE_HHMM:
str = fmt.Sprintf("%02d:%02d", hours, minutes)
case ET_STYLE_MMSS:
if hours > 0 {
str = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds)
} else {
str = fmt.Sprintf("%02d:%02d", minutes, seconds)
}
}
return d.FormatMsg(str)
}
func (d *averageETA) OnCompleteMessage(msg string) {
d.completeMsg = &msg
}
func MaxTolerateTimeNormalizer(maxTolerate time.Duration) TimeNormalizer {
var normalized time.Duration
var lastCall time.Time
return func(remaining time.Duration) time.Duration {
if diff := normalized - remaining; diff <= 0 || diff > maxTolerate || remaining < maxTolerate/2 {
normalized = remaining
lastCall = time.Now()
return remaining
}
normalized -= time.Since(lastCall)
lastCall = time.Now()
return normalized
}
}
func FixedIntervalTimeNormalizer(updInterval int) TimeNormalizer {
var normalized time.Duration
var lastCall time.Time
var count int
return func(remaining time.Duration) time.Duration {
if count == 0 || remaining <= time.Duration(15*time.Second) {
count = updInterval
normalized = remaining
lastCall = time.Now()
return remaining
}
count--
normalized -= time.Since(lastCall)
lastCall = time.Now()
if normalized > 0 {
return normalized
}
return remaining
}
}
func NopNormalizer() TimeNormalizer {
return func(remaining time.Duration) time.Duration {
return remaining
}
}

View File

@ -0,0 +1,66 @@
package decor
import (
"sort"
"github.com/VividCortex/ewma"
)
// MovingAverage is the interface that computes a moving average over a time-
// series stream of numbers. The average may be over a window or exponentially
// decaying.
type MovingAverage interface {
Add(float64)
Value() float64
Set(float64)
}
type medianWindow [3]float64
func (s *medianWindow) Len() int { return len(s) }
func (s *medianWindow) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s *medianWindow) Less(i, j int) bool { return s[i] < s[j] }
func (s *medianWindow) Add(value float64) {
s[0], s[1] = s[1], s[2]
s[2] = value
}
func (s *medianWindow) Value() float64 {
tmp := *s
sort.Sort(&tmp)
return tmp[1]
}
func (s *medianWindow) Set(value float64) {
for i := 0; i < len(s); i++ {
s[i] = value
}
}
// NewMedian is fixed last 3 samples median MovingAverage.
func NewMedian() MovingAverage {
return new(medianWindow)
}
type medianEwma struct {
count uint
median MovingAverage
MovingAverage
}
func (s *medianEwma) Add(v float64) {
s.median.Add(v)
if s.count >= 2 {
s.MovingAverage.Add(s.median.Value())
}
s.count++
}
// NewMedianEwma is ewma based MovingAverage, which gets its values from median MovingAverage.
func NewMedianEwma(age ...float64) MovingAverage {
return &medianEwma{
MovingAverage: ewma.NewMovingAverage(age...),
median: NewMedian(),
}
}

45
vendor/github.com/vbauerster/mpb/decor/name.go generated vendored Normal file
View File

@ -0,0 +1,45 @@
package decor
// StaticName returns name decorator.
//
// `name` string to display
//
// `wcc` optional WC config
func StaticName(name string, wcc ...WC) Decorator {
return Name(name, wcc...)
}
// Name returns name decorator.
//
// `name` string to display
//
// `wcc` optional WC config
func Name(name string, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
wc.Init()
d := &nameDecorator{
WC: wc,
msg: name,
}
return d
}
type nameDecorator struct {
WC
msg string
complete *string
}
func (d *nameDecorator) Decor(st *Statistics) string {
if st.Completed && d.complete != nil {
return d.FormatMsg(*d.complete)
}
return d.FormatMsg(d.msg)
}
func (d *nameDecorator) OnCompleteMessage(msg string) {
d.complete = &msg
}

39
vendor/github.com/vbauerster/mpb/decor/percentage.go generated vendored Normal file
View File

@ -0,0 +1,39 @@
package decor
import (
"fmt"
"github.com/vbauerster/mpb/internal"
)
// Percentage returns percentage decorator.
//
// `wcc` optional WC config
func Percentage(wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
wc.Init()
d := &percentageDecorator{
WC: wc,
}
return d
}
type percentageDecorator struct {
WC
completeMsg *string
}
func (d *percentageDecorator) Decor(st *Statistics) string {
if st.Completed && d.completeMsg != nil {
return d.FormatMsg(*d.completeMsg)
}
str := fmt.Sprintf("%d %%", internal.Percentage(st.Total, st.Current, 100))
return d.FormatMsg(str)
}
func (d *percentageDecorator) OnCompleteMessage(msg string) {
d.completeMsg = &msg
}

270
vendor/github.com/vbauerster/mpb/decor/speed.go generated vendored Normal file
View File

@ -0,0 +1,270 @@
package decor
import (
"fmt"
"io"
"math"
"strconv"
"strings"
"time"
"github.com/VividCortex/ewma"
)
type SpeedKiB float64
func (s SpeedKiB) Format(st fmt.State, verb rune) {
prec, ok := st.Precision()
if verb == 'd' || !ok {
prec = 0
}
if verb == 'f' && !ok {
prec = 6
}
// retain old beahavior if s verb used
if verb == 's' {
prec = 1
}
var res, unit string
switch {
case s >= TiB:
unit = "TiB/s"
res = strconv.FormatFloat(float64(s)/TiB, 'f', prec, 64)
case s >= GiB:
unit = "GiB/s"
res = strconv.FormatFloat(float64(s)/GiB, 'f', prec, 64)
case s >= MiB:
unit = "MiB/s"
res = strconv.FormatFloat(float64(s)/MiB, 'f', prec, 64)
case s >= KiB:
unit = "KiB/s"
res = strconv.FormatFloat(float64(s)/KiB, 'f', prec, 64)
default:
unit = "b/s"
res = strconv.FormatInt(int64(s), 10)
}
if st.Flag(' ') {
res += " "
}
res += unit
if w, ok := st.Width(); ok {
if len(res) < w {
pad := strings.Repeat(" ", w-len(res))
if st.Flag(int('-')) {
res += pad
} else {
res = pad + res
}
}
}
io.WriteString(st, res)
}
type SpeedKB float64
func (s SpeedKB) Format(st fmt.State, verb rune) {
prec, ok := st.Precision()
if verb == 'd' || !ok {
prec = 0
}
if verb == 'f' && !ok {
prec = 6
}
// retain old beahavior if s verb used
if verb == 's' {
prec = 1
}
var res, unit string
switch {
case s >= TB:
unit = "TB/s"
res = strconv.FormatFloat(float64(s)/TB, 'f', prec, 64)
case s >= GB:
unit = "GB/s"
res = strconv.FormatFloat(float64(s)/GB, 'f', prec, 64)
case s >= MB:
unit = "MB/s"
res = strconv.FormatFloat(float64(s)/MB, 'f', prec, 64)
case s >= KB:
unit = "kB/s"
res = strconv.FormatFloat(float64(s)/KB, 'f', prec, 64)
default:
unit = "b/s"
res = strconv.FormatInt(int64(s), 10)
}
if st.Flag(' ') {
res += " "
}
res += unit
if w, ok := st.Width(); ok {
if len(res) < w {
pad := strings.Repeat(" ", w-len(res))
if st.Flag(int('-')) {
res += pad
} else {
res = pad + res
}
}
}
io.WriteString(st, res)
}
// EwmaSpeed exponential-weighted-moving-average based speed decorator,
// with dynamic unit measure adjustment.
//
// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
//
// `unitFormat` printf compatible verb for value, like "%f" or "%d"
//
// `average` MovingAverage implementation
//
// `wcc` optional WC config
//
// unitFormat example if UnitKiB is chosen:
//
// "%.1f" = "1.0MiB/s" or "% .1f" = "1.0 MiB/s"
func EwmaSpeed(unit int, unitFormat string, age float64, wcc ...WC) Decorator {
return MovingAverageSpeed(unit, unitFormat, ewma.NewMovingAverage(age), wcc...)
}
// MovingAverageSpeed decorator relies on MovingAverage implementation to calculate its average.
//
// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
//
// `unitFormat` printf compatible verb for value, like "%f" or "%d"
//
// `average` MovingAverage implementation
//
// `wcc` optional WC config
func MovingAverageSpeed(unit int, unitFormat string, average MovingAverage, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
wc.Init()
d := &movingAverageSpeed{
WC: wc,
unit: unit,
unitFormat: unitFormat,
average: average,
}
return d
}
type movingAverageSpeed struct {
WC
unit int
unitFormat string
average ewma.MovingAverage
msg string
completeMsg *string
}
func (d *movingAverageSpeed) Decor(st *Statistics) string {
if st.Completed {
if d.completeMsg != nil {
return d.FormatMsg(*d.completeMsg)
}
return d.FormatMsg(d.msg)
}
speed := d.average.Value()
switch d.unit {
case UnitKiB:
d.msg = fmt.Sprintf(d.unitFormat, SpeedKiB(speed))
case UnitKB:
d.msg = fmt.Sprintf(d.unitFormat, SpeedKB(speed))
default:
d.msg = fmt.Sprintf(d.unitFormat, speed)
}
return d.FormatMsg(d.msg)
}
func (s *movingAverageSpeed) NextAmount(n int, wdd ...time.Duration) {
var workDuration time.Duration
for _, wd := range wdd {
workDuration = wd
}
speed := float64(n) / workDuration.Seconds() / 1000
if math.IsInf(speed, 0) || math.IsNaN(speed) {
return
}
s.average.Add(speed)
}
func (d *movingAverageSpeed) OnCompleteMessage(msg string) {
d.completeMsg = &msg
}
// AverageSpeed decorator with dynamic unit measure adjustment.
//
// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
//
// `unitFormat` printf compatible verb for value, like "%f" or "%d"
//
// `wcc` optional WC config
//
// unitFormat example if UnitKiB is chosen:
//
// "%.1f" = "1.0MiB/s" or "% .1f" = "1.0 MiB/s"
func AverageSpeed(unit int, unitFormat string, wcc ...WC) Decorator {
var wc WC
for _, widthConf := range wcc {
wc = widthConf
}
wc.Init()
d := &averageSpeed{
WC: wc,
unit: unit,
unitFormat: unitFormat,
startTime: time.Now(),
}
return d
}
type averageSpeed struct {
WC
unit int
unitFormat string
startTime time.Time
msg string
completeMsg *string
}
func (d *averageSpeed) Decor(st *Statistics) string {
if st.Completed {
if d.completeMsg != nil {
return d.FormatMsg(*d.completeMsg)
}
return d.FormatMsg(d.msg)
}
timeElapsed := time.Since(d.startTime)
speed := float64(st.Current) / timeElapsed.Seconds()
switch d.unit {
case UnitKiB:
d.msg = fmt.Sprintf(d.unitFormat, SpeedKiB(speed))
case UnitKB:
d.msg = fmt.Sprintf(d.unitFormat, SpeedKB(speed))
default:
d.msg = fmt.Sprintf(d.unitFormat, speed)
}
return d.FormatMsg(d.msg)
}
func (d *averageSpeed) OnCompleteMessage(msg string) {
d.completeMsg = &msg
}

6
vendor/github.com/vbauerster/mpb/doc.go generated vendored Normal file
View File

@ -0,0 +1,6 @@
// Copyright (C) 2016-2018 Vladimir Bauer
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package mpb is a library for rendering progress bars in terminal applications.
package mpb

View File

@ -0,0 +1,10 @@
package internal
// Percentage is a helper function, to calculate percentage.
func Percentage(total, current, width int64) int64 {
if total <= 0 {
return 0
}
p := float64(width*current) / float64(total)
return int64(Round(p))
}

49
vendor/github.com/vbauerster/mpb/internal/round.go generated vendored Normal file
View File

@ -0,0 +1,49 @@
package internal
import "math"
const (
uvone = 0x3FF0000000000000
mask = 0x7FF
shift = 64 - 11 - 1
bias = 1023
signMask = 1 << 63
fracMask = 1<<shift - 1
)
// Round returns the nearest integer, rounding half away from zero.
//
// Special cases are:
// Round(±0) = ±0
// Round(±Inf) = ±Inf
// Round(NaN) = NaN
func Round(x float64) float64 {
// Round is a faster implementation of:
//
// func Round(x float64) float64 {
// t := Trunc(x)
// if Abs(x-t) >= 0.5 {
// return t + Copysign(1, x)
// }
// return t
// }
bits := math.Float64bits(x)
e := uint(bits>>shift) & mask
if e < bias {
// Round abs(x) < 1 including denormals.
bits &= signMask // +-0
if e == bias-1 {
bits |= uvone // +-1
}
} else if e < bias+shift {
// Round any abs(x) >= 1 containing a fractional component [0,1).
//
// Numbers with larger exponents are returned unchanged since they
// must be either an integer, infinity, or NaN.
const half = 1 << (shift - 1)
e -= bias
bits += half >> e
bits &^= fracMask >> e
}
return math.Float64frombits(bits)
}

95
vendor/github.com/vbauerster/mpb/options.go generated vendored Normal file
View File

@ -0,0 +1,95 @@
package mpb
import (
"io"
"sync"
"time"
"unicode/utf8"
"github.com/vbauerster/mpb/cwriter"
)
// ProgressOption is a function option which changes the default behavior of
// progress pool, if passed to mpb.New(...ProgressOption)
type ProgressOption func(*pState)
// WithWaitGroup provides means to have a single joint point.
// If *sync.WaitGroup is provided, you can safely call just p.Wait()
// without calling Wait() on provided *sync.WaitGroup.
// Makes sense when there are more than one bar to render.
func WithWaitGroup(wg *sync.WaitGroup) ProgressOption {
return func(s *pState) {
s.uwg = wg
}
}
// WithWidth overrides default width 80
func WithWidth(w int) ProgressOption {
return func(s *pState) {
if w >= 0 {
s.width = w
}
}
}
// WithFormat overrides default bar format "[=>-]"
func WithFormat(format string) ProgressOption {
return func(s *pState) {
if utf8.RuneCountInString(format) == formatLen {
s.format = format
}
}
}
// WithRefreshRate overrides default 120ms refresh rate
func WithRefreshRate(d time.Duration) ProgressOption {
return func(s *pState) {
if d < 10*time.Millisecond {
return
}
s.rr = d
}
}
// WithManualRefresh disables internal auto refresh time.Ticker.
// Refresh will occur upon receive value from provided ch.
func WithManualRefresh(ch <-chan time.Time) ProgressOption {
return func(s *pState) {
s.manualRefreshCh = ch
}
}
// WithCancel provide your cancel channel,
// which you plan to close at some point.
func WithCancel(ch <-chan struct{}) ProgressOption {
return func(s *pState) {
s.cancel = ch
}
}
// WithShutdownNotifier provided chanel will be closed, after all bars have been rendered.
func WithShutdownNotifier(ch chan struct{}) ProgressOption {
return func(s *pState) {
s.shutdownNotifier = ch
}
}
// WithOutput overrides default output os.Stdout
func WithOutput(w io.Writer) ProgressOption {
return func(s *pState) {
if w == nil {
return
}
s.cw = cwriter.New(w)
}
}
// WithDebugOutput sets debug output.
func WithDebugOutput(w io.Writer) ProgressOption {
return func(s *pState) {
if w == nil {
return
}
s.debugOut = w
}
}

15
vendor/github.com/vbauerster/mpb/options_go1.7.go generated vendored Normal file
View File

@ -0,0 +1,15 @@
//+build go1.7
package mpb
import "context"
// WithContext provided context will be used for cancellation purposes
func WithContext(ctx context.Context) ProgressOption {
return func(s *pState) {
if ctx == nil {
panic("ctx must not be nil")
}
s.cancel = ctx.Done()
}
}

40
vendor/github.com/vbauerster/mpb/priority_queue.go generated vendored Normal file
View File

@ -0,0 +1,40 @@
package mpb
import "container/heap"
// 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{}) {
n := len(*pq)
bar := x.(*Bar)
bar.index = n
*pq = append(*pq, bar)
}
func (pq *priorityQueue) Pop() interface{} {
old := *pq
n := len(old)
bar := old[n-1]
bar.index = -1 // for safety
*pq = old[0 : n-1]
return bar
}
// update modifies the priority of a Bar in the queue.
func (pq *priorityQueue) update(bar *Bar, priority int) {
bar.priority = priority
heap.Fix(pq, bar.index)
}

251
vendor/github.com/vbauerster/mpb/progress.go generated vendored Normal file
View File

@ -0,0 +1,251 @@
package mpb
import (
"container/heap"
"fmt"
"io"
"io/ioutil"
"os"
"sync"
"time"
"github.com/vbauerster/mpb/cwriter"
)
const (
// default RefreshRate
prr = 120 * time.Millisecond
// default width
pwidth = 80
// default format
pformat = "[=>-]"
)
// Progress represents the container that renders Progress bars
type Progress struct {
wg *sync.WaitGroup
uwg *sync.WaitGroup
operateState chan func(*pState)
done chan struct{}
}
type pState struct {
bHeap *priorityQueue
shutdownPending []*Bar
heapUpdated bool
zeroWait bool
idCounter int
width int
format string
rr time.Duration
cw *cwriter.Writer
pMatrix map[int][]chan int
aMatrix map[int][]chan int
// following are provided by user
uwg *sync.WaitGroup
manualRefreshCh <-chan time.Time
cancel <-chan struct{}
shutdownNotifier chan struct{}
waitBars map[*Bar]*Bar
debugOut io.Writer
}
// New creates new Progress instance, which orchestrates bars rendering process.
// Accepts mpb.ProgressOption funcs for customization.
func New(options ...ProgressOption) *Progress {
pq := make(priorityQueue, 0)
heap.Init(&pq)
s := &pState{
bHeap: &pq,
width: pwidth,
format: pformat,
cw: cwriter.New(os.Stdout),
rr: prr,
waitBars: make(map[*Bar]*Bar),
debugOut: ioutil.Discard,
}
for _, opt := range options {
if opt != nil {
opt(s)
}
}
p := &Progress{
uwg: s.uwg,
wg: new(sync.WaitGroup),
operateState: make(chan func(*pState)),
done: make(chan struct{}),
}
go p.serve(s)
return p
}
// AddBar creates a new progress bar and adds to the container.
func (p *Progress) AddBar(total int64, options ...BarOption) *Bar {
p.wg.Add(1)
result := make(chan *Bar)
select {
case p.operateState <- func(s *pState) {
options = append(options, barWidth(s.width), barFormat(s.format))
b := newBar(p.wg, s.idCounter, total, s.cancel, options...)
if b.runningBar != nil {
s.waitBars[b.runningBar] = b
} else {
heap.Push(s.bHeap, b)
s.heapUpdated = true
}
s.idCounter++
result <- b
}:
return <-result
case <-p.done:
p.wg.Done()
return nil
}
}
// Abort is only effective while bar progress is running,
// it means remove bar now without waiting for its completion.
// If bar is already completed, there is nothing to abort.
// If you need to remove bar after completion, use BarRemoveOnComplete BarOption.
func (p *Progress) Abort(b *Bar, remove bool) {
select {
case p.operateState <- func(s *pState) {
if b.index < 0 {
return
}
if remove {
s.heapUpdated = heap.Remove(s.bHeap, b.index) != nil
}
s.shutdownPending = append(s.shutdownPending, b)
}:
case <-p.done:
}
}
// UpdateBarPriority provides a way to change bar's order position.
// Zero is highest priority, i.e. bar will be on top.
func (p *Progress) UpdateBarPriority(b *Bar, priority int) {
select {
case p.operateState <- func(s *pState) { s.bHeap.update(b, priority) }:
case <-p.done:
}
}
// BarCount returns bars count
func (p *Progress) BarCount() int {
result := make(chan int, 1)
select {
case p.operateState <- func(s *pState) { result <- s.bHeap.Len() }:
return <-result
case <-p.done:
return 0
}
}
// Wait first waits for user provided *sync.WaitGroup, if any,
// then waits far all bars to complete and finally shutdowns master goroutine.
// After this method has been called, there is no way to reuse *Progress instance.
func (p *Progress) Wait() {
if p.uwg != nil {
p.uwg.Wait()
}
p.wg.Wait()
select {
case p.operateState <- func(s *pState) { s.zeroWait = true }:
<-p.done
case <-p.done:
}
}
func (s *pState) updateSyncMatrix() {
s.pMatrix = make(map[int][]chan int)
s.aMatrix = make(map[int][]chan int)
for i := 0; i < s.bHeap.Len(); i++ {
bar := (*s.bHeap)[i]
table := bar.wSyncTable()
pRow, aRow := table[0], table[1]
for i, ch := range pRow {
s.pMatrix[i] = append(s.pMatrix[i], ch)
}
for i, ch := range aRow {
s.aMatrix[i] = append(s.aMatrix[i], ch)
}
}
}
func (s *pState) render(tw int) {
if s.heapUpdated {
s.updateSyncMatrix()
s.heapUpdated = false
}
syncWidth(s.pMatrix)
syncWidth(s.aMatrix)
for i := 0; i < s.bHeap.Len(); i++ {
bar := (*s.bHeap)[i]
go bar.render(s.debugOut, tw)
}
if err := s.flush(s.bHeap.Len()); err != nil {
fmt.Fprintf(s.debugOut, "%s %s %v\n", "[mpb]", time.Now(), err)
}
}
func (s *pState) flush(lineCount int) error {
for s.bHeap.Len() > 0 {
bar := heap.Pop(s.bHeap).(*Bar)
frameReader := <-bar.frameReaderCh
defer func() {
if frameReader.toShutdown {
// shutdown at next flush, in other words decrement underlying WaitGroup
// only after the bar with completed state has been flushed.
// this ensures no bar ends up with less than 100% rendered.
s.shutdownPending = append(s.shutdownPending, bar)
if replacementBar, ok := s.waitBars[bar]; ok {
heap.Push(s.bHeap, replacementBar)
s.heapUpdated = true
delete(s.waitBars, bar)
}
if frameReader.removeOnComplete {
s.heapUpdated = true
return
}
}
heap.Push(s.bHeap, bar)
}()
s.cw.ReadFrom(frameReader)
lineCount += frameReader.extendedLines
}
for i := len(s.shutdownPending) - 1; i >= 0; i-- {
close(s.shutdownPending[i].shutdown)
s.shutdownPending = s.shutdownPending[:i]
}
return s.cw.Flush(lineCount)
}
func syncWidth(matrix map[int][]chan int) {
for _, column := range matrix {
column := column
go func() {
var maxWidth int
for _, ch := range column {
w := <-ch
if w > maxWidth {
maxWidth = w
}
}
for _, ch := range column {
ch <- maxWidth
}
}()
}
}

70
vendor/github.com/vbauerster/mpb/progress_posix.go generated vendored Normal file
View File

@ -0,0 +1,70 @@
// +build !windows
package mpb
import (
"os"
"os/signal"
"syscall"
"time"
)
func (p *Progress) serve(s *pState) {
var ticker *time.Ticker
var refreshCh <-chan time.Time
var winch chan os.Signal
var resumeTimer *time.Timer
var resumeEvent <-chan time.Time
winchIdleDur := s.rr * 2
if s.manualRefreshCh == nil {
ticker = time.NewTicker(s.rr)
refreshCh = ticker.C
winch = make(chan os.Signal, 2)
signal.Notify(winch, syscall.SIGWINCH)
} else {
refreshCh = s.manualRefreshCh
}
for {
select {
case op := <-p.operateState:
op(s)
case <-refreshCh:
if s.zeroWait {
if s.manualRefreshCh == nil {
signal.Stop(winch)
ticker.Stop()
}
if s.shutdownNotifier != nil {
close(s.shutdownNotifier)
}
close(p.done)
return
}
tw, err := s.cw.GetWidth()
if err != nil {
tw = s.width
}
s.render(tw)
case <-winch:
tw, err := s.cw.GetWidth()
if err != nil {
tw = s.width
}
s.render(tw - tw/8)
if resumeTimer != nil && resumeTimer.Reset(winchIdleDur) {
break
}
ticker.Stop()
resumeTimer = time.NewTimer(winchIdleDur)
resumeEvent = resumeTimer.C
case <-resumeEvent:
ticker = time.NewTicker(s.rr)
refreshCh = ticker.C
resumeEvent = nil
resumeTimer = nil
}
}
}

43
vendor/github.com/vbauerster/mpb/progress_windows.go generated vendored Normal file
View File

@ -0,0 +1,43 @@
// +build windows
package mpb
import (
"time"
)
func (p *Progress) serve(s *pState) {
var ticker *time.Ticker
var refreshCh <-chan time.Time
if s.manualRefreshCh == nil {
ticker = time.NewTicker(s.rr)
refreshCh = ticker.C
} else {
refreshCh = s.manualRefreshCh
}
for {
select {
case op := <-p.operateState:
op(s)
case <-refreshCh:
if s.zeroWait {
if s.manualRefreshCh == nil {
ticker.Stop()
}
if s.shutdownNotifier != nil {
close(s.shutdownNotifier)
}
close(p.done)
return
}
tw, err := s.cw.GetWidth()
if err != nil {
tw = s.width
}
s.render(tw)
}
}
}

22
vendor/github.com/vbauerster/mpb/proxyreader.go generated vendored Normal file
View File

@ -0,0 +1,22 @@
package mpb
import (
"io"
"time"
)
// proxyReader is io.Reader wrapper, for proxy read bytes
type proxyReader struct {
io.ReadCloser
bar *Bar
iT time.Time
}
func (pr *proxyReader) Read(p []byte) (n int, err error) {
n, err = pr.ReadCloser.Read(p)
if n > 0 {
pr.bar.IncrBy(n, time.Since(pr.iT))
pr.iT = time.Now()
}
return
}