Merge pull request #15495 from containers/dependabot/go_modules/github.com/vbauerster/mpb/v7-7.5.2

Bump github.com/vbauerster/mpb/v7 from 7.4.2 to 7.5.2
This commit is contained in:
OpenShift Merge Robot
2022-08-26 12:00:52 -04:00
committed by GitHub
11 changed files with 220 additions and 132 deletions

2
go.mod
View File

@ -58,7 +58,7 @@ require (
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
github.com/uber/jaeger-client-go v2.30.0+incompatible
github.com/ulikunitz/xz v0.5.10
github.com/vbauerster/mpb/v7 v7.4.2
github.com/vbauerster/mpb/v7 v7.5.2
github.com/vishvananda/netlink v1.1.1-0.20220115184804-dd687eb2f2d4
go.etcd.io/bbolt v1.3.6
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f

3
go.sum
View File

@ -1593,8 +1593,9 @@ github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/V
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME=
github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI=
github.com/vbauerster/mpb/v7 v7.4.2 h1:n917F4d8EWdUKc9c81wFkksyG6P6Mg7IETfKCE1Xqng=
github.com/vbauerster/mpb/v7 v7.4.2/go.mod h1:UmOiIUI8aPqWXIps0ciik3RKMdzx7+ooQpq+fBcXwBA=
github.com/vbauerster/mpb/v7 v7.5.2 h1:Ph3JvpBcoIwzIG1QwbUq97KQifrTRbKcMXN9rN5BYAs=
github.com/vbauerster/mpb/v7 v7.5.2/go.mod h1:UmOiIUI8aPqWXIps0ciik3RKMdzx7+ooQpq+fBcXwBA=
github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE=
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=

View File

@ -29,7 +29,7 @@ type Bar struct {
recoveredPanic interface{}
}
type extenderFunc func(in io.Reader, reqWidth int, st decor.Statistics) (out io.Reader, lines int)
type extenderFunc func(rows []io.Reader, width int, stat decor.Statistics) []io.Reader
// bState is actual bar's state.
type bState struct {
@ -57,14 +57,15 @@ type bState struct {
extender extenderFunc
debugOut io.Writer
afterBar *Bar // key for (*pState).queueBars
sync bool
wait struct {
bar *Bar // key for (*pState).queueBars
sync bool
}
}
type renderFrame struct {
reader io.Reader
lines int
shutdown bool
rows []io.Reader
shutdown int
}
func newBar(container *Progress, bs *bState) *Bar {
@ -339,8 +340,8 @@ func (b *Bar) Wait() {
func (b *Bar) serve(ctx context.Context, bs *bState) {
defer b.container.bwg.Done()
if bs.afterBar != nil && bs.sync {
bs.afterBar.Wait()
if bs.wait.bar != nil && bs.wait.sync {
bs.wait.bar.Wait()
}
for {
select {
@ -359,48 +360,58 @@ func (b *Bar) serve(ctx context.Context, bs *bState) {
func (b *Bar) render(tw int) {
select {
case b.operateState <- func(s *bState) {
var reader io.Reader
var lines int
var rows []io.Reader
stat := newStatistics(tw, s)
defer func() {
// recovering if user defined decorator panics for example
if p := recover(); p != nil {
if s.debugOut != nil {
fmt.Fprintln(s.debugOut, p)
_, _ = s.debugOut.Write(debug.Stack())
for _, fn := range []func() (int, error){
func() (int, error) {
return fmt.Fprintln(s.debugOut, p)
},
func() (int, error) {
return s.debugOut.Write(debug.Stack())
},
} {
if _, err := fn(); err != nil {
panic(err)
}
}
}
s.aborted = !s.completed
s.extender = makePanicExtender(p)
reader, lines = s.extender(nil, s.reqWidth, stat)
b.recoveredPanic = p
}
frame := renderFrame{
reader: reader,
lines: lines + 1,
shutdown: s.completed || s.aborted,
if fn := s.extender; fn != nil {
rows = fn(rows, s.reqWidth, stat)
}
if frame.shutdown {
frame := &renderFrame{
rows: rows,
}
if s.completed || s.aborted {
b.cancel()
frame.shutdown++
}
b.frameCh <- &frame
b.frameCh <- frame
}()
if b.recoveredPanic == nil {
reader = s.draw(stat)
rows = append(rows, s.draw(stat))
}
reader, lines = s.extender(reader, s.reqWidth, stat)
}:
case <-b.done:
var reader io.Reader
var lines int
stat, s := newStatistics(tw, b.bs), b.bs
var rows []io.Reader
s, stat := b.bs, newStatistics(tw, b.bs)
if b.recoveredPanic == nil {
reader = s.draw(stat)
rows = append(rows, s.draw(stat))
}
reader, lines = s.extender(reader, s.reqWidth, stat)
b.frameCh <- &renderFrame{
reader: reader,
lines: lines + 1,
if fn := s.extender; fn != nil {
rows = fn(rows, s.reqWidth, stat)
}
frame := &renderFrame{
rows: rows,
}
b.frameCh <- frame
}
}
@ -446,7 +457,7 @@ func (b *Bar) wSyncTable() [][]chan int {
func (s *bState) draw(stat decor.Statistics) io.Reader {
bufP, bufB, bufA := s.buffers[0], s.buffers[1], s.buffers[2]
nlr := strings.NewReader("\n")
nlr := bytes.NewReader([]byte("\n"))
tw := stat.AvailableWidth
for _, d := range s.pDecorators {
str := d.Decor(stat)
@ -596,11 +607,11 @@ func extractBaseDecorator(d decor.Decorator) decor.Decorator {
func makePanicExtender(p interface{}) extenderFunc {
pstr := fmt.Sprint(p)
return func(_ io.Reader, _ int, st decor.Statistics) (io.Reader, int) {
mr := io.MultiReader(
strings.NewReader(runewidth.Truncate(pstr, st.AvailableWidth, "…")),
strings.NewReader("\n"),
return func(rows []io.Reader, _ int, stat decor.Statistics) []io.Reader {
r := io.MultiReader(
strings.NewReader(runewidth.Truncate(pstr, stat.AvailableWidth, "…")),
bytes.NewReader([]byte("\n")),
)
return mr, 0
return append(rows, r)
}
}

View File

@ -60,6 +60,7 @@ func BarWidth(width int) BarOption {
}
// BarQueueAfter puts this (being constructed) bar into the queue.
// BarPriority will be inherited from the argument bar.
// When argument bar completes or aborts queued bar replaces its place.
// If sync is true queued bar is suspended until argument bar completes
// or aborts.
@ -68,8 +69,8 @@ func BarQueueAfter(bar *Bar, sync bool) BarOption {
return nil
}
return func(s *bState) {
s.afterBar = bar
s.sync = sync
s.wait.bar = bar
s.wait.sync = sync
}
}
@ -111,29 +112,61 @@ func BarFillerMiddleware(middle func(BarFiller) BarFiller) BarOption {
}
// 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.
// will be on top. This option isn't effective with `BarQueueAfter` option.
func BarPriority(priority int) BarOption {
return func(s *bState) {
s.priority = priority
}
}
// BarExtender provides a way to extend bar to the next new line.
// BarExtender extends bar with arbitrary lines. Provided BarFiller will be
// called at each render/flush cycle. Any lines written to the underlying
// io.Writer will be printed after the bar itself.
func BarExtender(filler BarFiller) BarOption {
return barExtender(filler, false)
}
// BarExtenderRev extends bar with arbitrary lines in reverse order. Provided
// BarFiller will be called at each render/flush cycle. Any lines written
// to the underlying io.Writer will be printed before the bar itself.
func BarExtenderRev(filler BarFiller) BarOption {
return barExtender(filler, true)
}
func barExtender(filler BarFiller, rev bool) BarOption {
if filler == nil {
return nil
}
return func(s *bState) {
s.extender = makeExtenderFunc(filler)
s.extender = makeExtenderFunc(filler, rev)
}
}
func makeExtenderFunc(filler BarFiller) extenderFunc {
func makeExtenderFunc(filler BarFiller, rev bool) extenderFunc {
buf := new(bytes.Buffer)
return func(r io.Reader, reqWidth int, st decor.Statistics) (io.Reader, int) {
filler.Fill(buf, reqWidth, st)
return io.MultiReader(r, buf), bytes.Count(buf.Bytes(), []byte("\n"))
base := func(rows []io.Reader, width int, stat decor.Statistics) []io.Reader {
buf.Reset()
filler.Fill(buf, width, stat)
for {
b, err := buf.ReadBytes('\n')
if err != nil {
break
}
rows = append(rows, bytes.NewReader(b))
}
return rows
}
if !rev {
return base
} else {
return func(rows []io.Reader, width int, stat decor.Statistics) []io.Reader {
rows = base(rows, width, stat)
for left, right := 0, len(rows)-1; left < right; left, right = left+1, right-1 {
rows[left], rows[right] = rows[right], rows[left]
}
return rows
}
}
}

View File

@ -31,7 +31,7 @@ func WithWidth(width int) ContainerOption {
}
}
// WithRefreshRate overrides default 120ms refresh rate.
// WithRefreshRate overrides default 150ms refresh rate.
func WithRefreshRate(d time.Duration) ContainerOption {
return func(s *pState) {
s.rr = d

View File

@ -20,19 +20,30 @@ const (
// 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
lines int
fd int
isTerminal bool
out io.Writer
buf bytes.Buffer
lines int // how much lines to clear before flushing new ones
fd int
terminal bool
termSize func(int) (int, int, error)
}
// New returns a new Writer with defaults.
func New(out io.Writer) *Writer {
w := &Writer{out: out}
w := &Writer{
out: out,
termSize: func(_ int) (int, int, error) {
return -1, -1, ErrNotTTY
},
}
if f, ok := out.(*os.File); ok {
w.fd = int(f.Fd())
w.isTerminal = IsTerminal(w.fd)
if IsTerminal(w.fd) {
w.terminal = true
w.termSize = func(fd int) (int, int, error) {
return GetSize(fd)
}
}
}
return w
}
@ -67,13 +78,9 @@ 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 {
return -1, ErrNotTTY
}
tw, _, err := GetSize(w.fd)
return tw, err
// GetTermSize returns WxH of underlying terminal.
func (w *Writer) GetTermSize() (width, height int, err error) {
return w.termSize(w.fd)
}
func (w *Writer) ansiCuuAndEd() error {

View File

@ -16,7 +16,7 @@ var (
)
func (w *Writer) clearLines() error {
if !w.isTerminal {
if !w.terminal {
// hope it's cygwin or similar
return w.ansiCuuAndEd()
}

View File

@ -1,27 +1,55 @@
package decor
// OnPredicate returns decorator if predicate evaluates to true.
//
// `decorator` Decorator
//
// `predicate` func() bool
//
func OnPredicate(decorator Decorator, predicate func() bool) Decorator {
if predicate() {
return decorator
}
return nil
}
// OnCondition returns decorator if condition is true.
// OnCondition applies decorator only if a condition is true.
//
// `decorator` Decorator
//
// `cond` bool
//
func OnCondition(decorator Decorator, cond bool) Decorator {
if cond {
return decorator
}
return nil
return Conditional(cond, decorator, nil)
}
// OnPredicate applies decorator only if a predicate evaluates to true.
//
// `decorator` Decorator
//
// `predicate` func() bool
//
func OnPredicate(decorator Decorator, predicate func() bool) Decorator {
return Predicative(predicate, decorator, nil)
}
// Conditional returns decorator `a` if condition is true, otherwise
// decorator `b`.
//
// `cond` bool
//
// `a` Decorator
//
// `b` Decorator
//
func Conditional(cond bool, a, b Decorator) Decorator {
if cond {
return a
} else {
return b
}
}
// Predicative returns decorator `a` if predicate evaluates to true,
// otherwise decorator `b`.
//
// `predicate` func() bool
//
// `a` Decorator
//
// `b` Decorator
//
func Predicative(predicate func() bool, a, b Decorator) Decorator {
if predicate() {
return a
} else {
return b
}
}

View File

@ -6,7 +6,8 @@ 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
// less priority pops first
return pq[i].priority > pq[j].priority
}
func (pq priorityQueue) Swap(i, j int) {

View File

@ -12,7 +12,6 @@ import (
"time"
"github.com/vbauerster/mpb/v7/cwriter"
"github.com/vbauerster/mpb/v7/decor"
)
const (
@ -41,6 +40,7 @@ type pState struct {
// following are provided/overrided by user
idCount int
reqWidth int
popPriority int
popCompleted bool
outputDiscarded bool
rr time.Duration
@ -64,10 +64,11 @@ func New(options ...ContainerOption) *Progress {
// method has been called.
func NewWithContext(ctx context.Context, options ...ContainerOption) *Progress {
s := &pState{
bHeap: priorityQueue{},
rr: prr,
queueBars: make(map[*Bar]*Bar),
output: os.Stdout,
bHeap: priorityQueue{},
rr: prr,
queueBars: make(map[*Bar]*Bar),
output: os.Stdout,
popPriority: math.MinInt32,
}
for _, opt := range options {
@ -118,8 +119,8 @@ func (p *Progress) Add(total int64, filler BarFiller, options ...BarOption) *Bar
case p.operateState <- func(ps *pState) {
bs := ps.makeBarState(total, filler, options...)
bar := newBar(p, bs)
if bs.afterBar != nil {
ps.queueBars[bs.afterBar] = bar
if bs.wait.bar != nil {
ps.queueBars[bs.wait.bar] = bar
} else {
heap.Push(&ps.bHeap, bar)
ps.heapUpdated = true
@ -204,33 +205,27 @@ func (p *Progress) serve(s *pState, cw *cwriter.Writer) {
p.refreshCh = s.newTicker(p.done)
render := func(debugOut io.Writer) {
err := s.render(cw)
for err != nil {
if debugOut != nil {
_, err = fmt.Fprintln(debugOut, err)
} else {
panic(err)
}
debugOut = nil
}
}
for {
select {
case op := <-p.operateState:
op(s)
case <-p.refreshCh:
if err := s.render(cw); err != nil {
if s.debugOut != nil {
_, e := fmt.Fprintln(s.debugOut, err)
if e != nil {
panic(err)
}
} else {
panic(err)
}
}
render(s.debugOut)
case <-s.shutdownNotifier:
for s.heapUpdated {
if err := s.render(cw); err != nil {
if s.debugOut != nil {
_, e := fmt.Fprintln(s.debugOut, err)
if e != nil {
panic(err)
}
} else {
panic(err)
}
}
render(s.debugOut)
}
return
}
@ -245,42 +240,52 @@ func (s *pState) render(cw *cwriter.Writer) error {
syncWidth(s.pMatrix)
syncWidth(s.aMatrix)
tw, err := cw.GetWidth()
width, height, err := cw.GetTermSize()
if err != nil {
tw = s.reqWidth
width = s.reqWidth
height = s.bHeap.Len()
}
for i := 0; i < s.bHeap.Len(); i++ {
bar := s.bHeap[i]
go bar.render(tw)
go bar.render(width)
}
return s.flush(cw)
return s.flush(cw, height)
}
func (s *pState) flush(cw *cwriter.Writer) error {
var lines int
func (s *pState) flush(cw *cwriter.Writer, height int) error {
var popCount int
rows := make([]io.Reader, 0, height)
pool := make([]*Bar, 0, s.bHeap.Len())
for s.bHeap.Len() > 0 {
var frameRowsUsed int
b := heap.Pop(&s.bHeap).(*Bar)
frame := <-b.frameCh
lines += frame.lines
_, err := cw.ReadFrom(frame.reader)
if err != nil {
return err
for i := len(frame.rows) - 1; i >= 0; i-- {
if len(rows) == height {
break
}
rows = append(rows, frame.rows[i])
frameRowsUsed++
}
if frame.shutdown {
if frame.shutdown != 0 {
b.Wait() // waiting for b.done, so it's safe to read b.bs
var toDrop bool
drop := b.bs.dropOnComplete
if qb, ok := s.queueBars[b]; ok {
delete(s.queueBars, b)
qb.priority = b.priority
pool = append(pool, qb)
toDrop = true
drop = true
} else if s.popCompleted && !b.bs.noPop {
lines -= frame.lines
toDrop = true
if frame.shutdown > 1 {
popCount += frameRowsUsed
drop = true
} else {
s.popPriority++
b.priority = s.popPriority
}
}
if toDrop || b.bs.dropOnComplete {
if drop {
s.heapUpdated = true
continue
}
@ -292,7 +297,14 @@ func (s *pState) flush(cw *cwriter.Writer) error {
heap.Push(&s.bHeap, b)
}
return cw.Flush(lines)
for i := len(rows) - 1; i >= 0; i-- {
_, err := cw.ReadFrom(rows[i])
if err != nil {
return err
}
}
return cw.Flush(len(rows) - popCount)
}
func (s *pState) newTicker(done <-chan struct{}) chan time.Time {
@ -358,7 +370,6 @@ func (s *pState) makeBarState(total int64, filler BarFiller, options ...BarOptio
reqWidth: s.reqWidth,
total: total,
filler: filler,
extender: func(r io.Reader, _ int, _ decor.Statistics) (io.Reader, int) { return r, 0 },
debugOut: s.debugOut,
}
@ -377,10 +388,6 @@ func (s *pState) makeBarState(total int64, filler BarFiller, options ...BarOptio
bs.middleware = nil
}
if s.popCompleted && !bs.noPop {
bs.priority = -(math.MaxInt32 - s.idCount)
}
for i := 0; i < len(bs.buffers); i++ {
bs.buffers[i] = bytes.NewBuffer(make([]byte, 0, 512))
}

2
vendor/modules.txt vendored
View File

@ -720,7 +720,7 @@ github.com/ulikunitz/xz/lzma
github.com/vbatts/tar-split/archive/tar
github.com/vbatts/tar-split/tar/asm
github.com/vbatts/tar-split/tar/storage
# github.com/vbauerster/mpb/v7 v7.4.2
# github.com/vbauerster/mpb/v7 v7.5.2
## explicit
github.com/vbauerster/mpb/v7
github.com/vbauerster/mpb/v7/cwriter