Merge pull request #19246 from containers/renovate/github.com-vbauerster-mpb-v8-8.x

fix(deps): update module github.com/vbauerster/mpb/v8 to v8.5.1
This commit is contained in:
OpenShift Merge Robot
2023-07-15 13:23:25 +02:00
committed by GitHub
18 changed files with 419 additions and 416 deletions

2
go.mod
View File

@ -59,7 +59,7 @@ require (
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
github.com/ulikunitz/xz v0.5.11 github.com/ulikunitz/xz v0.5.11
github.com/vbauerster/mpb/v8 v8.4.0 github.com/vbauerster/mpb/v8 v8.5.1
github.com/vishvananda/netlink v1.2.1-beta.2 github.com/vishvananda/netlink v1.2.1-beta.2
go.etcd.io/bbolt v1.3.7 go.etcd.io/bbolt v1.3.7
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1

4
go.sum
View File

@ -1008,8 +1008,8 @@ github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN
github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI=
github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=
github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=
github.com/vbauerster/mpb/v8 v8.4.0 h1:Jq2iNA7T6SydpMVOwaT+2OBWlXS9Th8KEvBqeu5eeTo= github.com/vbauerster/mpb/v8 v8.5.1 h1:HVscg+TKXvAMPizij6g1zDR5monCAX9Vifq+VDFp/hE=
github.com/vbauerster/mpb/v8 v8.4.0/go.mod h1:vjp3hSTuCtR+x98/+2vW3eZ8XzxvGoP8CPseHMhiPyc= github.com/vbauerster/mpb/v8 v8.5.1/go.mod h1:YqKyR4ZR6Gd34yD3cDHPMmQxc+uUQMwjgO/LkxiJQ6I=
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= 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= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=

View File

@ -144,7 +144,13 @@ func (b *Bar) Current() int64 {
// operation for example. // operation for example.
func (b *Bar) SetRefill(amount int64) { func (b *Bar) SetRefill(amount int64) {
select { select {
case b.operateState <- func(s *bState) { s.refill = amount }: case b.operateState <- func(s *bState) {
if amount < s.current {
s.refill = amount
} else {
s.refill = s.current
}
}:
case <-b.done: case <-b.done:
} }
} }
@ -497,48 +503,31 @@ func (s *bState) draw(stat decor.Statistics) (io.Reader, error) {
} }
func (s *bState) drawImpl(stat decor.Statistics) (io.Reader, error) { func (s *bState) drawImpl(stat decor.Statistics) (io.Reader, error) {
decorFiller := func(buf *bytes.Buffer, decorators []decor.Decorator) (res struct { decorFiller := func(buf *bytes.Buffer, decorators []decor.Decorator) (err error) {
width int
truncate bool
err error
}) {
res.width = stat.AvailableWidth
for _, d := range decorators { for _, d := range decorators {
str := d.Decor(stat) // need to call Decor in any case becase of width synchronization
if stat.AvailableWidth > 0 { str, width := d.Decor(stat)
stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str)) if err != nil {
if res.err == nil { continue
_, res.err = buf.WriteString(str) }
if w := stat.AvailableWidth - width; w >= 0 {
_, err = buf.WriteString(str)
stat.AvailableWidth = w
} else if stat.AvailableWidth > 0 {
trunc := runewidth.Truncate(stripansi.Strip(str), stat.AvailableWidth, "…")
_, err = buf.WriteString(trunc)
stat.AvailableWidth = 0
} }
} }
} return err
res.truncate = stat.AvailableWidth < 0
return res
} }
bufP, bufB, bufA := s.buffers[0], s.buffers[1], s.buffers[2] bufP, bufB, bufA := s.buffers[0], s.buffers[1], s.buffers[2]
resP := decorFiller(bufP, s.pDecorators) err := eitherError(decorFiller(bufP, s.pDecorators), decorFiller(bufA, s.aDecorators))
resA := decorFiller(bufA, s.aDecorators)
for _, err := range []error{resP.err, resA.err} {
if err != nil { if err != nil {
return nil, err return nil, err
} }
}
if resP.truncate {
trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufP.String()), resP.width, "…"))
bufP.Reset()
bufA.Reset()
return trunc, nil
}
if resA.truncate {
trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufA.String()), resA.width, "…"))
bufA.Reset()
return io.MultiReader(bufP, trunc), nil
}
if !s.trimSpace && stat.AvailableWidth >= 2 { if !s.trimSpace && stat.AvailableWidth >= 2 {
stat.AvailableWidth -= 2 stat.AvailableWidth -= 2
@ -662,3 +651,12 @@ func unwrap(d decor.Decorator) decor.Decorator {
func writeSpace(buf *bytes.Buffer) error { func writeSpace(buf *bytes.Buffer) error {
return buf.WriteByte(' ') return buf.WriteByte(' ')
} }
func eitherError(errors ...error) error {
for _, err := range errors {
if err != nil {
return err
}
}
return nil
}

View File

@ -29,11 +29,3 @@ type BarFillerFunc func(io.Writer, decor.Statistics) error
func (f BarFillerFunc) Fill(w io.Writer, stat decor.Statistics) error { func (f BarFillerFunc) Fill(w io.Writer, stat decor.Statistics) error {
return f(w, stat) return f(w, stat)
} }
// BarFillerBuilderFunc is function type adapter to convert compatible
// function into BarFillerBuilder interface.
type BarFillerBuilderFunc func() BarFiller
func (f BarFillerBuilderFunc) Build() BarFiller {
return f()
}

View File

@ -3,7 +3,6 @@ package mpb
import ( import (
"io" "io"
"github.com/acarl005/stripansi"
"github.com/mattn/go-runewidth" "github.com/mattn/go-runewidth"
"github.com/vbauerster/mpb/v8/decor" "github.com/vbauerster/mpb/v8/decor"
"github.com/vbauerster/mpb/v8/internal" "github.com/vbauerster/mpb/v8/internal"
@ -12,143 +11,209 @@ import (
const ( const (
iLbound = iota iLbound = iota
iRbound iRbound
iFiller
iRefiller iRefiller
iFiller
iTip
iPadding iPadding
components components
) )
var defaultBarStyle = [components]string{"[", "]", "+", "=", ">", "-"}
// BarStyleComposer interface. // BarStyleComposer interface.
type BarStyleComposer interface { type BarStyleComposer interface {
BarFillerBuilder BarFillerBuilder
Lbound(string) BarStyleComposer Lbound(string) BarStyleComposer
LboundMeta(func(string) string) BarStyleComposer
Rbound(string) BarStyleComposer Rbound(string) BarStyleComposer
RboundMeta(func(string) string) BarStyleComposer
Filler(string) BarStyleComposer Filler(string) BarStyleComposer
FillerMeta(func(string) string) BarStyleComposer
Refiller(string) BarStyleComposer Refiller(string) BarStyleComposer
RefillerMeta(func(string) string) BarStyleComposer
Padding(string) BarStyleComposer Padding(string) BarStyleComposer
TipOnComplete(string) BarStyleComposer PaddingMeta(func(string) string) BarStyleComposer
Tip(frames ...string) BarStyleComposer Tip(frames ...string) BarStyleComposer
TipMeta(func(string) string) BarStyleComposer
TipOnComplete() BarStyleComposer
Reverse() BarStyleComposer Reverse() BarStyleComposer
} }
type bFiller struct {
rev bool
components [components]*component
tip struct {
count uint
frames []*component
onComplete *component
}
}
type component struct { type component struct {
width int width int
bytes []byte bytes []byte
} }
type flushSection struct {
meta func(io.Writer, []byte) error
bytes []byte
}
type bFiller struct {
components [components]component
meta [components]func(io.Writer, []byte) error
flush func(io.Writer, ...flushSection) error
tipOnComplete bool
tip struct {
frames []component
count uint
}
}
type barStyle struct { type barStyle struct {
lbound string style [components]string
rbound string metaFuncs [components]func(io.Writer, []byte) error
filler string
refiller string
padding string
tipOnComplete string
tipFrames []string tipFrames []string
tipOnComplete bool
rev bool rev bool
} }
// BarStyle constructs default bar style which can be altered via // BarStyle constructs default bar style which can be altered via
// BarStyleComposer interface. // BarStyleComposer interface.
func BarStyle() BarStyleComposer { func BarStyle() BarStyleComposer {
return &barStyle{ bs := barStyle{
lbound: "[", style: defaultBarStyle,
rbound: "]", tipFrames: []string{defaultBarStyle[iTip]},
filler: "=",
refiller: "+",
padding: "-",
tipFrames: []string{">"},
} }
for i := range bs.metaFuncs {
bs.metaFuncs[i] = defaultMeta
}
return bs
} }
func (s *barStyle) Lbound(bound string) BarStyleComposer { func (s barStyle) Lbound(bound string) BarStyleComposer {
s.lbound = bound s.style[iLbound] = bound
return s return s
} }
func (s *barStyle) Rbound(bound string) BarStyleComposer { func (s barStyle) LboundMeta(fn func(string) string) BarStyleComposer {
s.rbound = bound s.metaFuncs[iLbound] = makeMetaFunc(fn)
return s return s
} }
func (s *barStyle) Filler(filler string) BarStyleComposer { func (s barStyle) Rbound(bound string) BarStyleComposer {
s.filler = filler s.style[iRbound] = bound
return s return s
} }
func (s *barStyle) Refiller(refiller string) BarStyleComposer { func (s barStyle) RboundMeta(fn func(string) string) BarStyleComposer {
s.refiller = refiller s.metaFuncs[iRbound] = makeMetaFunc(fn)
return s return s
} }
func (s *barStyle) Padding(padding string) BarStyleComposer { func (s barStyle) Filler(filler string) BarStyleComposer {
s.padding = padding s.style[iFiller] = filler
return s return s
} }
func (s *barStyle) TipOnComplete(tip string) BarStyleComposer { func (s barStyle) FillerMeta(fn func(string) string) BarStyleComposer {
s.tipOnComplete = tip s.metaFuncs[iFiller] = makeMetaFunc(fn)
return s return s
} }
func (s *barStyle) Tip(frames ...string) BarStyleComposer { func (s barStyle) Refiller(refiller string) BarStyleComposer {
s.style[iRefiller] = refiller
return s
}
func (s barStyle) RefillerMeta(fn func(string) string) BarStyleComposer {
s.metaFuncs[iRefiller] = makeMetaFunc(fn)
return s
}
func (s barStyle) Padding(padding string) BarStyleComposer {
s.style[iPadding] = padding
return s
}
func (s barStyle) PaddingMeta(fn func(string) string) BarStyleComposer {
s.metaFuncs[iPadding] = makeMetaFunc(fn)
return s
}
func (s barStyle) Tip(frames ...string) BarStyleComposer {
if len(frames) != 0 { if len(frames) != 0 {
s.tipFrames = append(s.tipFrames[:0], frames...) s.tipFrames = frames
} }
return s return s
} }
func (s *barStyle) Reverse() BarStyleComposer { func (s barStyle) TipMeta(fn func(string) string) BarStyleComposer {
s.metaFuncs[iTip] = makeMetaFunc(fn)
return s
}
func (s barStyle) TipOnComplete() BarStyleComposer {
s.tipOnComplete = true
return s
}
func (s barStyle) Reverse() BarStyleComposer {
s.rev = true s.rev = true
return s return s
} }
func (s *barStyle) Build() BarFiller { func (s barStyle) Build() BarFiller {
bf := &bFiller{rev: s.rev} bf := &bFiller{
bf.components[iLbound] = &component{ meta: s.metaFuncs,
width: runewidth.StringWidth(stripansi.Strip(s.lbound)), tipOnComplete: s.tipOnComplete,
bytes: []byte(s.lbound),
} }
bf.components[iRbound] = &component{ bf.components[iLbound] = component{
width: runewidth.StringWidth(stripansi.Strip(s.rbound)), width: runewidth.StringWidth(s.style[iLbound]),
bytes: []byte(s.rbound), bytes: []byte(s.style[iLbound]),
} }
bf.components[iFiller] = &component{ bf.components[iRbound] = component{
width: runewidth.StringWidth(stripansi.Strip(s.filler)), width: runewidth.StringWidth(s.style[iRbound]),
bytes: []byte(s.filler), bytes: []byte(s.style[iRbound]),
} }
bf.components[iRefiller] = &component{ bf.components[iFiller] = component{
width: runewidth.StringWidth(stripansi.Strip(s.refiller)), width: runewidth.StringWidth(s.style[iFiller]),
bytes: []byte(s.refiller), bytes: []byte(s.style[iFiller]),
} }
bf.components[iPadding] = &component{ bf.components[iRefiller] = component{
width: runewidth.StringWidth(stripansi.Strip(s.padding)), width: runewidth.StringWidth(s.style[iRefiller]),
bytes: []byte(s.padding), bytes: []byte(s.style[iRefiller]),
} }
bf.tip.onComplete = &component{ bf.components[iPadding] = component{
width: runewidth.StringWidth(stripansi.Strip(s.tipOnComplete)), width: runewidth.StringWidth(s.style[iPadding]),
bytes: []byte(s.tipOnComplete), bytes: []byte(s.style[iPadding]),
} }
bf.tip.frames = make([]*component, len(s.tipFrames)) bf.tip.frames = make([]component, len(s.tipFrames))
for i, t := range s.tipFrames { for i, t := range s.tipFrames {
bf.tip.frames[i] = &component{ bf.tip.frames[i] = component{
width: runewidth.StringWidth(stripansi.Strip(t)), width: runewidth.StringWidth(t),
bytes: []byte(t), bytes: []byte(t),
} }
} }
if s.rev {
bf.flush = func(w io.Writer, sections ...flushSection) error {
for i := len(sections) - 1; i >= 0; i-- {
if s := sections[i]; len(s.bytes) != 0 {
err := s.meta(w, s.bytes)
if err != nil {
return err
}
}
}
return nil
}
} else {
bf.flush = func(w io.Writer, sections ...flushSection) error {
for _, s := range sections {
if len(s.bytes) != 0 {
err := s.meta(w, s.bytes)
if err != nil {
return err
}
}
}
return nil
}
}
return bf return bf
} }
func (s *bFiller) Fill(w io.Writer, stat decor.Statistics) (err error) { func (s *bFiller) Fill(w io.Writer, stat decor.Statistics) error {
width := internal.CheckRequestedWidth(stat.RequestedWidth, stat.AvailableWidth) width := internal.CheckRequestedWidth(stat.RequestedWidth, stat.AvailableWidth)
// don't count brackets as progress // don't count brackets as progress
width -= (s.components[iLbound].width + s.components[iRbound].width) width -= (s.components[iLbound].width + s.components[iRbound].width)
@ -156,104 +221,71 @@ func (s *bFiller) Fill(w io.Writer, stat decor.Statistics) (err error) {
return nil return nil
} }
_, err = w.Write(s.components[iLbound].bytes) err := s.meta[iLbound](w, s.components[iLbound].bytes)
if err != nil { if err != nil {
return err return err
} }
if width == 0 { if width == 0 {
_, err = w.Write(s.components[iRbound].bytes) return s.meta[iRbound](w, s.components[iRbound].bytes)
return err
} }
var filling [][]byte var tip component
var padding [][]byte var refilling, filling, padding []byte
var tip *component var fillCount int
var filled int
var refWidth int
curWidth := int(internal.PercentageRound(stat.Total, stat.Current, uint(width))) curWidth := int(internal.PercentageRound(stat.Total, stat.Current, uint(width)))
if stat.Completed { if curWidth != 0 {
tip = s.tip.onComplete if !stat.Completed || s.tipOnComplete {
} else {
tip = s.tip.frames[s.tip.count%uint(len(s.tip.frames))] tip = s.tip.frames[s.tip.count%uint(len(s.tip.frames))]
}
if curWidth > 0 {
filling = append(filling, tip.bytes)
filled += tip.width
s.tip.count++ s.tip.count++
fillCount += tip.width
} }
if stat.Refill != 0 {
if stat.Refill > 0 { refWidth := int(internal.PercentageRound(stat.Total, stat.Refill, uint(width)))
refWidth = int(internal.PercentageRound(stat.Total, stat.Refill, uint(width)))
curWidth -= refWidth curWidth -= refWidth
refWidth += curWidth refWidth += curWidth
for w := s.components[iFiller].width; curWidth-fillCount >= w; fillCount += w {
filling = append(filling, s.components[iFiller].bytes...)
} }
for w := s.components[iRefiller].width; refWidth-fillCount >= w; fillCount += w {
for filled < curWidth { refilling = append(refilling, s.components[iRefiller].bytes...)
if curWidth-filled >= s.components[iFiller].width {
filling = append(filling, s.components[iFiller].bytes)
if s.components[iFiller].width == 0 {
break
} }
filled += s.components[iFiller].width
} else { } else {
filling = append(filling, []byte("…")) for w := s.components[iFiller].width; curWidth-fillCount >= w; fillCount += w {
filled++ filling = append(filling, s.components[iFiller].bytes...)
}
} }
} }
for filled < refWidth { for w := s.components[iPadding].width; width-fillCount >= w; fillCount += w {
if refWidth-filled >= s.components[iRefiller].width { padding = append(padding, s.components[iPadding].bytes...)
filling = append(filling, s.components[iRefiller].bytes)
if s.components[iRefiller].width == 0 {
break
}
filled += s.components[iRefiller].width
} else {
filling = append(filling, []byte("…"))
filled++
}
} }
padWidth := width - filled for w := 1; width-fillCount >= w; fillCount += w {
for padWidth > 0 { padding = append(padding, "…"...)
if padWidth >= s.components[iPadding].width {
padding = append(padding, s.components[iPadding].bytes)
if s.components[iPadding].width == 0 {
break
}
padWidth -= s.components[iPadding].width
} else {
padding = append(padding, []byte("…"))
padWidth--
}
} }
if s.rev { err = s.flush(w,
filling, padding = padding, filling flushSection{s.meta[iRefiller], refilling},
} flushSection{s.meta[iFiller], filling},
err = flush(w, filling, padding) flushSection{s.meta[iTip], tip.bytes},
flushSection{s.meta[iPadding], padding},
)
if err != nil { if err != nil {
return err return err
} }
_, err = w.Write(s.components[iRbound].bytes) return s.meta[iRbound](w, s.components[iRbound].bytes)
return err
} }
func flush(w io.Writer, filling, padding [][]byte) error { func makeMetaFunc(fn func(string) string) func(io.Writer, []byte) error {
for i := len(filling) - 1; i >= 0; i-- { return func(w io.Writer, p []byte) (err error) {
_, err := w.Write(filling[i]) _, err = io.WriteString(w, fn(string(p)))
if err != nil {
return err return err
} }
} }
for i := 0; i < len(padding); i++ {
_, err := w.Write(padding[i]) func defaultMeta(w io.Writer, p []byte) (err error) {
if err != nil { _, err = w.Write(p)
return err return err
} }
}
return nil
}

View File

@ -6,9 +6,17 @@ import (
"github.com/vbauerster/mpb/v8/decor" "github.com/vbauerster/mpb/v8/decor"
) )
// barFillerBuilderFunc is function type adapter to convert compatible
// function into BarFillerBuilder interface.
type barFillerBuilderFunc func() BarFiller
func (f barFillerBuilderFunc) Build() BarFiller {
return f()
}
// NopStyle provides BarFillerBuilder which builds NOP BarFiller. // NopStyle provides BarFillerBuilder which builds NOP BarFiller.
func NopStyle() BarFillerBuilder { func NopStyle() BarFillerBuilder {
return BarFillerBuilderFunc(func() BarFiller { return barFillerBuilderFunc(func() BarFiller {
return BarFillerFunc(func(io.Writer, decor.Statistics) error { return BarFillerFunc(func(io.Writer, decor.Statistics) error {
return nil return nil
}) })

View File

@ -1,10 +1,10 @@
package mpb package mpb
import ( import (
"fmt"
"io" "io"
"strings" "strings"
"github.com/acarl005/stripansi"
"github.com/mattn/go-runewidth" "github.com/mattn/go-runewidth"
"github.com/vbauerster/mpb/v8/decor" "github.com/vbauerster/mpb/v8/decor"
"github.com/vbauerster/mpb/v8/internal" "github.com/vbauerster/mpb/v8/internal"
@ -15,74 +15,90 @@ const (
positionRight positionRight
) )
var defaultSpinnerStyle = [...]string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
// SpinnerStyleComposer interface. // SpinnerStyleComposer interface.
type SpinnerStyleComposer interface { type SpinnerStyleComposer interface {
BarFillerBuilder BarFillerBuilder
PositionLeft() SpinnerStyleComposer PositionLeft() SpinnerStyleComposer
PositionRight() SpinnerStyleComposer PositionRight() SpinnerStyleComposer
Meta(func(string) string) SpinnerStyleComposer
} }
type sFiller struct { type sFiller struct {
count uint
position uint
frames []string frames []string
count uint
meta func(string) string
position func(string, int) string
} }
type spinnerStyle struct { type spinnerStyle struct {
position uint position uint
frames []string frames []string
meta func(string) string
} }
// SpinnerStyle constructs default spinner style which can be altered via // SpinnerStyle constructs default spinner style which can be altered via
// SpinnerStyleComposer interface. // SpinnerStyleComposer interface.
func SpinnerStyle(frames ...string) SpinnerStyleComposer { func SpinnerStyle(frames ...string) SpinnerStyleComposer {
ss := new(spinnerStyle) ss := spinnerStyle{
meta: func(s string) string { return s },
}
if len(frames) != 0 { if len(frames) != 0 {
ss.frames = append(ss.frames, frames...) ss.frames = frames
} else { } else {
ss.frames = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"} ss.frames = defaultSpinnerStyle[:]
} }
return ss return ss
} }
func (s *spinnerStyle) PositionLeft() SpinnerStyleComposer { func (s spinnerStyle) PositionLeft() SpinnerStyleComposer {
s.position = positionLeft s.position = positionLeft
return s return s
} }
func (s *spinnerStyle) PositionRight() SpinnerStyleComposer { func (s spinnerStyle) PositionRight() SpinnerStyleComposer {
s.position = positionRight s.position = positionRight
return s return s
} }
func (s *spinnerStyle) Build() BarFiller { func (s spinnerStyle) Meta(fn func(string) string) SpinnerStyleComposer {
s.meta = fn
return s
}
func (s spinnerStyle) Build() BarFiller {
sf := &sFiller{ sf := &sFiller{
position: s.position,
frames: s.frames, frames: s.frames,
meta: s.meta,
}
switch s.position {
case positionLeft:
sf.position = func(frame string, padWidth int) string {
return fmt.Sprint(frame, strings.Repeat(" ", padWidth))
}
case positionRight:
sf.position = func(frame string, padWidth int) string {
return fmt.Sprint(strings.Repeat(" ", padWidth), frame)
}
default:
sf.position = func(frame string, padWidth int) string {
return fmt.Sprint(strings.Repeat(" ", padWidth/2), frame, strings.Repeat(" ", padWidth/2+padWidth%2))
}
} }
return sf return sf
} }
func (s *sFiller) Fill(w io.Writer, stat decor.Statistics) (err error) { func (s *sFiller) Fill(w io.Writer, stat decor.Statistics) error {
width := internal.CheckRequestedWidth(stat.RequestedWidth, stat.AvailableWidth) width := internal.CheckRequestedWidth(stat.RequestedWidth, stat.AvailableWidth)
frame := s.frames[s.count%uint(len(s.frames))] frame := s.frames[s.count%uint(len(s.frames))]
frameWidth := runewidth.StringWidth(stripansi.Strip(frame)) frameWidth := runewidth.StringWidth(frame)
s.count++
if width < frameWidth { if width < frameWidth {
return nil return nil
} }
rest := width - frameWidth _, err := io.WriteString(w, s.position(s.meta(frame), width-frameWidth))
switch s.position {
case positionLeft:
_, err = io.WriteString(w, frame+strings.Repeat(" ", rest))
case positionRight:
_, err = io.WriteString(w, strings.Repeat(" ", rest)+frame)
default:
str := strings.Repeat(" ", rest/2) + frame + strings.Repeat(" ", rest/2+rest%2)
_, err = io.WriteString(w, str)
}
s.count++
return err return err
} }

View File

@ -15,11 +15,6 @@ func inspect(decorators []decor.Decorator) (dest []decor.Decorator) {
if decorator == nil { if decorator == nil {
continue continue
} }
if d, ok := decorator.(interface {
PlaceHolders() []decor.Decorator
}); ok {
dest = append(dest, d.PlaceHolders()...)
}
dest = append(dest, decorator) dest = append(dest, decorator)
} }
return return
@ -93,10 +88,10 @@ func BarFillerOnComplete(message string) BarOption {
// BarFillerMiddleware provides a way to augment the underlying BarFiller. // BarFillerMiddleware provides a way to augment the underlying BarFiller.
func BarFillerMiddleware(middle func(BarFiller) BarFiller) BarOption { func BarFillerMiddleware(middle func(BarFiller) BarFiller) BarOption {
return func(s *bState) {
if middle == nil { if middle == nil {
return return nil
} }
return func(s *bState) {
s.filler = middle(s.filler) s.filler = middle(s.filler)
} }
} }

View File

@ -1,15 +1,14 @@
package decor package decor
var _ Decorator = (*any)(nil) var _ Decorator = any{}
// Any decorator displays text, that can be changed during decorator's // Any decorator.
// lifetime via provided DecorFunc. // Converts DecorFunc into Decorator.
// //
// `fn` DecorFunc callback // `fn` DecorFunc callback
//
// `wcc` optional WC config // `wcc` optional WC config
func Any(fn DecorFunc, wcc ...WC) Decorator { func Any(fn DecorFunc, wcc ...WC) Decorator {
return &any{initWC(wcc...), fn} return any{initWC(wcc...), fn}
} }
type any struct { type any struct {
@ -17,6 +16,6 @@ type any struct {
fn DecorFunc fn DecorFunc
} }
func (d *any) Decor(s Statistics) string { func (d any) Decor(s Statistics) (string, int) {
return d.FormatMsg(d.fn(s)) return d.Format(d.fn(s))
} }

View File

@ -4,12 +4,12 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/acarl005/stripansi"
"github.com/mattn/go-runewidth" "github.com/mattn/go-runewidth"
) )
const ( const (
// DidentRight bit specifies identation direction. // DidentRight bit specifies identation direction.
//
// |foo |b | With DidentRight // |foo |b | With DidentRight
// | foo| b| Without DidentRight // | foo| b| Without DidentRight
DidentRight = 1 << iota DidentRight = 1 << iota
@ -66,13 +66,13 @@ type Statistics struct {
// `DecorFunc` into a `Decorator` interface by using provided // `DecorFunc` into a `Decorator` interface by using provided
// `func Any(DecorFunc, ...WC) Decorator`. // `func Any(DecorFunc, ...WC) Decorator`.
type Decorator interface { type Decorator interface {
Configurator
Synchronizer Synchronizer
Decor(Statistics) string Formatter
Decor(Statistics) (str string, viewWidth int)
} }
// DecorFunc func type. // DecorFunc func type.
// To be used with `func Any`(DecorFunc, ...WC) Decorator`. // To be used with `func Any(DecorFunc, ...WC) Decorator`.
type DecorFunc func(Statistics) string type DecorFunc func(Statistics) string
// Synchronizer interface. // Synchronizer interface.
@ -82,10 +82,12 @@ type Synchronizer interface {
Sync() (chan int, bool) Sync() (chan int, bool)
} }
// Configurator interface. // Formatter interface.
type Configurator interface { // Format method needs to be called from within Decorator.Decor method
GetConf() WC // in order to format string according to decor.WC settings.
SetConf(WC) // No need to implement manually as long as decor.WC is embedded.
type Formatter interface {
Format(string) (str string, viewWidth int)
} }
// Wrapper interface. // Wrapper interface.
@ -135,21 +137,21 @@ type WC struct {
wsync chan int wsync chan int
} }
// FormatMsg formats final message according to WC.W and WC.C. // Format should be called by any Decorator implementation.
// Should be called by any Decorator implementation. // Returns formatted string and its view (visual) width.
func (wc WC) FormatMsg(msg string) string { func (wc WC) Format(str string) (string, int) {
pureWidth := runewidth.StringWidth(msg) viewWidth := runewidth.StringWidth(str)
viewWidth := runewidth.StringWidth(stripansi.Strip(msg)) if wc.W > viewWidth {
max := wc.W viewWidth = wc.W
}
if (wc.C & DSyncWidth) != 0 { if (wc.C & DSyncWidth) != 0 {
viewWidth := viewWidth
if (wc.C & DextraSpace) != 0 { if (wc.C & DextraSpace) != 0 {
viewWidth++ viewWidth++
} }
wc.wsync <- viewWidth wc.wsync <- viewWidth
max = <-wc.wsync viewWidth = <-wc.wsync
} }
return wc.fill(msg, max-viewWidth+pureWidth) return wc.fill(str, viewWidth), viewWidth
} }
// Init initializes width related config. // Init initializes width related config.
@ -175,16 +177,6 @@ func (wc WC) Sync() (chan int, bool) {
return wc.wsync, (wc.C & DSyncWidth) != 0 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 { func initWC(wcc ...WC) WC {
var wc WC var wc WC
for _, nwc := range wcc { for _, nwc := range wcc {

View File

@ -68,13 +68,13 @@ type movingAverageETA struct {
producer func(time.Duration) string producer func(time.Duration) string
} }
func (d *movingAverageETA) Decor(s Statistics) string { func (d *movingAverageETA) Decor(s Statistics) (string, int) {
v := math.Round(d.average.Value()) v := math.Round(d.average.Value())
remaining := time.Duration((s.Total - s.Current) * int64(v)) remaining := time.Duration((s.Total - s.Current) * int64(v))
if d.normalizer != nil { if d.normalizer != nil {
remaining = d.normalizer.Normalize(remaining) remaining = d.normalizer.Normalize(remaining)
} }
return d.FormatMsg(d.producer(remaining)) return d.Format(d.producer(remaining))
} }
func (d *movingAverageETA) EwmaUpdate(n int64, dur time.Duration) { func (d *movingAverageETA) EwmaUpdate(n int64, dur time.Duration) {
@ -120,7 +120,7 @@ type averageETA struct {
producer func(time.Duration) string producer func(time.Duration) string
} }
func (d *averageETA) Decor(s Statistics) string { func (d *averageETA) Decor(s Statistics) (string, int) {
var remaining time.Duration var remaining time.Duration
if s.Current != 0 { if s.Current != 0 {
durPerItem := float64(time.Since(d.startTime)) / float64(s.Current) durPerItem := float64(time.Since(d.startTime)) / float64(s.Current)
@ -130,7 +130,7 @@ func (d *averageETA) Decor(s Statistics) string {
remaining = d.normalizer.Normalize(remaining) remaining = d.normalizer.Normalize(remaining)
} }
} }
return d.FormatMsg(d.producer(remaining)) return d.Format(d.producer(remaining))
} }
func (d *averageETA) AverageAdjust(startTime time.Time) { func (d *averageETA) AverageAdjust(startTime time.Time) {

View File

@ -1,111 +0,0 @@
package decor
import (
"strings"
"github.com/acarl005/stripansi"
"github.com/mattn/go-runewidth"
)
var (
_ Decorator = (*mergeDecorator)(nil)
_ Wrapper = (*mergeDecorator)(nil)
_ Decorator = (*placeHolderDecorator)(nil)
)
// 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 decorator == nil {
return nil
}
if _, ok := decorator.Sync(); !ok || len(placeholders) == 0 {
return decorator
}
md := &mergeDecorator{
Decorator: decorator,
wc: decorator.GetConf(),
placeHolders: make([]Decorator, 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 []Decorator
}
func (d *mergeDecorator) GetConf() WC {
return d.wc
}
func (d *mergeDecorator) SetConf(conf WC) {
d.wc = conf.Init()
}
func (d *mergeDecorator) PlaceHolders() []Decorator {
return d.placeHolders
}
func (d *mergeDecorator) Sync() (chan int, bool) {
return d.wc.Sync()
}
func (d *mergeDecorator) Unwrap() Decorator {
return d.Decorator
}
func (d *mergeDecorator) Decor(s Statistics) string {
msg := d.Decorator.Decor(s)
pureWidth := runewidth.StringWidth(msg)
stripWidth := runewidth.StringWidth(stripansi.Strip(msg))
cellCount := stripWidth
if (d.wc.C & DextraSpace) != 0 {
cellCount++
}
total := runewidth.StringWidth(d.placeHolders[0].GetConf().FormatMsg(""))
pw := (cellCount - total) / len(d.placeHolders)
rem := (cellCount - total) % len(d.placeHolders)
var diff int
for i := 1; i < len(d.placeHolders); i++ {
wc := d.placeHolders[i].GetConf()
width := pw - diff
if (wc.C & DextraSpace) != 0 {
width--
if width < 0 {
width = 0
}
}
max := runewidth.StringWidth(wc.FormatMsg(strings.Repeat(" ", width)))
total += max
diff = max - pw
}
d.wc.wsync <- pw + rem
max := <-d.wc.wsync
return d.wc.fill(msg, max+total+(pureWidth-stripWidth))
}
type placeHolderDecorator struct {
WC
}
func (d *placeHolderDecorator) Decor(Statistics) string {
return ""
}

34
vendor/github.com/vbauerster/mpb/v8/decor/meta.go generated vendored Normal file
View File

@ -0,0 +1,34 @@
package decor
var (
_ Decorator = metaWrapper{}
_ Wrapper = metaWrapper{}
)
// Meta wrap decorator.
// Provided fn is supposed to wrap output of given decorator
// with meta information like ANSI escape codes for example.
// Primary usage intention is to set SGR display attributes.
//
// `decorator` Decorator to wrap
// `fn` func to apply meta information
func Meta(decorator Decorator, fn func(string) string) Decorator {
if decorator == nil {
return nil
}
return metaWrapper{decorator, fn}
}
type metaWrapper struct {
Decorator
fn func(string) string
}
func (d metaWrapper) Decor(s Statistics) (string, int) {
str, width := d.Decorator.Decor(s)
return d.fn(str), width
}
func (d metaWrapper) Unwrap() Decorator {
return d.Decorator
}

View File

@ -1,30 +1,23 @@
package decor package decor
var ( var (
_ Decorator = (*onAbortWrapper)(nil) _ Decorator = onAbortWrapper{}
_ Wrapper = (*onAbortWrapper)(nil) _ Wrapper = onAbortWrapper{}
_ Decorator = onAbortMetaWrapper{}
_ Wrapper = onAbortMetaWrapper{}
) )
// OnAbort returns decorator, which wraps provided decorator with sole // OnAbort wrap decorator.
// purpose to display provided message on abort event. It has no effect // Displays provided message on abort event.
// if bar.Abort(drop bool) is called with true argument. // Has no effect if bar.Abort(true) is called.
// //
// `decorator` Decorator to wrap // `decorator` Decorator to wrap
// // `message` message to display
// `message` message to display on abort event
func OnAbort(decorator Decorator, message string) Decorator { func OnAbort(decorator Decorator, message string) Decorator {
if decorator == nil { if decorator == nil {
return nil return nil
} }
d := &onAbortWrapper{ return onAbortWrapper{decorator, message}
Decorator: decorator,
msg: message,
}
if md, ok := decorator.(*mergeDecorator); ok {
d.Decorator, md.Decorator = md.Decorator, d
return md
}
return d
} }
type onAbortWrapper struct { type onAbortWrapper struct {
@ -32,13 +25,44 @@ type onAbortWrapper struct {
msg string msg string
} }
func (d *onAbortWrapper) Decor(s Statistics) string { func (d onAbortWrapper) Decor(s Statistics) (string, int) {
if s.Aborted { if s.Aborted {
return d.GetConf().FormatMsg(d.msg) return d.Format(d.msg)
} }
return d.Decorator.Decor(s) return d.Decorator.Decor(s)
} }
func (d *onAbortWrapper) Unwrap() Decorator { func (d onAbortWrapper) Unwrap() Decorator {
return d.Decorator
}
// OnAbortMeta wrap decorator.
// Provided fn is supposed to wrap output of given decorator
// with meta information like ANSI escape codes for example.
// Primary usage intention is to set SGR display attributes.
//
// `decorator` Decorator to wrap
// `fn` func to apply meta information
func OnAbortMeta(decorator Decorator, fn func(string) string) Decorator {
if decorator == nil {
return nil
}
return onAbortMetaWrapper{decorator, fn}
}
type onAbortMetaWrapper struct {
Decorator
fn func(string) string
}
func (d onAbortMetaWrapper) Decor(s Statistics) (string, int) {
if s.Completed {
str, width := d.Decorator.Decor(s)
return d.fn(str), width
}
return d.Decorator.Decor(s)
}
func (d onAbortMetaWrapper) Unwrap() Decorator {
return d.Decorator return d.Decorator
} }

View File

@ -1,29 +1,22 @@
package decor package decor
var ( var (
_ Decorator = (*onCompleteWrapper)(nil) _ Decorator = onCompleteWrapper{}
_ Wrapper = (*onCompleteWrapper)(nil) _ Wrapper = onCompleteWrapper{}
_ Decorator = onCompleteMetaWrapper{}
_ Wrapper = onCompleteMetaWrapper{}
) )
// OnComplete returns decorator, which wraps provided decorator with // OnComplete wrap decorator.
// sole purpose to display provided message on complete event. // Displays provided message on complete event.
// //
// `decorator` Decorator to wrap // `decorator` Decorator to wrap
// // `message` message to display
// `message` message to display on complete event
func OnComplete(decorator Decorator, message string) Decorator { func OnComplete(decorator Decorator, message string) Decorator {
if decorator == nil { if decorator == nil {
return nil return nil
} }
d := &onCompleteWrapper{ return onCompleteWrapper{decorator, message}
Decorator: decorator,
msg: message,
}
if md, ok := decorator.(*mergeDecorator); ok {
d.Decorator, md.Decorator = md.Decorator, d
return md
}
return d
} }
type onCompleteWrapper struct { type onCompleteWrapper struct {
@ -31,13 +24,44 @@ type onCompleteWrapper struct {
msg string msg string
} }
func (d *onCompleteWrapper) Decor(s Statistics) string { func (d onCompleteWrapper) Decor(s Statistics) (string, int) {
if s.Completed { if s.Completed {
return d.GetConf().FormatMsg(d.msg) return d.Format(d.msg)
} }
return d.Decorator.Decor(s) return d.Decorator.Decor(s)
} }
func (d *onCompleteWrapper) Unwrap() Decorator { func (d onCompleteWrapper) Unwrap() Decorator {
return d.Decorator
}
// OnCompleteMeta wrap decorator.
// Provided fn is supposed to wrap output of given decorator
// with meta information like ANSI escape codes for example.
// Primary usage intention is to set SGR display attributes.
//
// `decorator` Decorator to wrap
// `fn` func to apply meta information
func OnCompleteMeta(decorator Decorator, fn func(string) string) Decorator {
if decorator == nil {
return nil
}
return onCompleteMetaWrapper{decorator, fn}
}
type onCompleteMetaWrapper struct {
Decorator
fn func(string) string
}
func (d onCompleteMetaWrapper) Decor(s Statistics) (string, int) {
if s.Completed {
str, width := d.Decorator.Decor(s)
return d.fn(str), width
}
return d.Decorator.Decor(s)
}
func (d onCompleteMetaWrapper) Unwrap() Decorator {
return d.Decorator return d.Decorator
} }

View File

@ -82,7 +82,7 @@ type movingAverageSpeed struct {
msg string msg string
} }
func (d *movingAverageSpeed) Decor(s Statistics) string { func (d *movingAverageSpeed) Decor(s Statistics) (string, int) {
if !s.Completed { if !s.Completed {
var speed float64 var speed float64
if v := d.average.Value(); v > 0 { if v := d.average.Value(); v > 0 {
@ -90,7 +90,7 @@ func (d *movingAverageSpeed) Decor(s Statistics) string {
} }
d.msg = d.producer(speed * 1e9) d.msg = d.producer(speed * 1e9)
} }
return d.FormatMsg(d.msg) return d.Format(d.msg)
} }
func (d *movingAverageSpeed) EwmaUpdate(n int64, dur time.Duration) { func (d *movingAverageSpeed) EwmaUpdate(n int64, dur time.Duration) {
@ -140,12 +140,12 @@ type averageSpeed struct {
msg string msg string
} }
func (d *averageSpeed) Decor(s Statistics) string { func (d *averageSpeed) Decor(s Statistics) (string, int) {
if !s.Completed { if !s.Completed {
speed := float64(s.Current) / float64(time.Since(d.startTime)) speed := float64(s.Current) / float64(time.Since(d.startTime))
d.msg = d.producer(speed * 1e9) d.msg = d.producer(speed * 1e9)
} }
return d.FormatMsg(d.msg) return d.Format(d.msg)
} }
func (d *averageSpeed) AverageAdjust(startTime time.Time) { func (d *averageSpeed) AverageAdjust(startTime time.Time) {

View File

@ -1,6 +1,6 @@
package decor package decor
var defaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"} var defaultSpinnerStyle = [...]string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
// Spinner returns spinner decorator. // Spinner returns spinner decorator.
// //
@ -9,7 +9,7 @@ var defaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "
// `wcc` optional WC config // `wcc` optional WC config
func Spinner(frames []string, wcc ...WC) Decorator { func Spinner(frames []string, wcc ...WC) Decorator {
if len(frames) == 0 { if len(frames) == 0 {
frames = defaultSpinnerStyle frames = defaultSpinnerStyle[:]
} }
var count uint var count uint
f := func(s Statistics) string { f := func(s Statistics) string {

2
vendor/modules.txt vendored
View File

@ -978,7 +978,7 @@ github.com/ulikunitz/xz/lzma
github.com/vbatts/tar-split/archive/tar github.com/vbatts/tar-split/archive/tar
github.com/vbatts/tar-split/tar/asm github.com/vbatts/tar-split/tar/asm
github.com/vbatts/tar-split/tar/storage github.com/vbatts/tar-split/tar/storage
# github.com/vbauerster/mpb/v8 v8.4.0 # github.com/vbauerster/mpb/v8 v8.5.1
## explicit; go 1.17 ## explicit; go 1.17
github.com/vbauerster/mpb/v8 github.com/vbauerster/mpb/v8
github.com/vbauerster/mpb/v8/cwriter github.com/vbauerster/mpb/v8/cwriter