Add a new generic container registry client via a new `container` package. Use this to create a command line utility as well as a new upload target for container registries. The code uses the github.com/containers/* project and packages to interact with container registires that is also used by skopeo, podman et al. One if the dependencies is `proglottis/gpgme` that is using cgo to bind libgpgme, so we have to add the corresponding devel package to the BuildRequires as well as installing it on CI. Checks will follow later via an integration test.
170 lines
4.2 KiB
Go
170 lines
4.2 KiB
Go
package mpb
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
|
|
"github.com/vbauerster/mpb/v7/decor"
|
|
)
|
|
|
|
// BarOption is a func option to alter default behavior of a bar.
|
|
type BarOption func(*bState)
|
|
|
|
func skipNil(decorators []decor.Decorator) (filtered []decor.Decorator) {
|
|
for _, d := range decorators {
|
|
if d != nil {
|
|
filtered = append(filtered, d)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *bState) addDecorators(dest *[]decor.Decorator, decorators ...decor.Decorator) {
|
|
type mergeWrapper interface {
|
|
MergeUnwrap() []decor.Decorator
|
|
}
|
|
for _, decorator := range decorators {
|
|
if mw, ok := decorator.(mergeWrapper); ok {
|
|
*dest = append(*dest, mw.MergeUnwrap()...)
|
|
}
|
|
*dest = append(*dest, decorator)
|
|
}
|
|
}
|
|
|
|
// AppendDecorators let you inject decorators to the bar's right side.
|
|
func AppendDecorators(decorators ...decor.Decorator) BarOption {
|
|
return func(s *bState) {
|
|
s.addDecorators(&s.aDecorators, skipNil(decorators)...)
|
|
}
|
|
}
|
|
|
|
// PrependDecorators let you inject decorators to the bar's left side.
|
|
func PrependDecorators(decorators ...decor.Decorator) BarOption {
|
|
return func(s *bState) {
|
|
s.addDecorators(&s.pDecorators, skipNil(decorators)...)
|
|
}
|
|
}
|
|
|
|
// BarID sets bar id.
|
|
func BarID(id int) BarOption {
|
|
return func(s *bState) {
|
|
s.id = id
|
|
}
|
|
}
|
|
|
|
// BarWidth sets bar width independent of the container.
|
|
func BarWidth(width int) BarOption {
|
|
return func(s *bState) {
|
|
s.reqWidth = width
|
|
}
|
|
}
|
|
|
|
// BarQueueAfter puts this (being constructed) bar into the queue.
|
|
// 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.
|
|
func BarQueueAfter(bar *Bar, sync bool) BarOption {
|
|
if bar == nil {
|
|
return nil
|
|
}
|
|
return func(s *bState) {
|
|
s.afterBar = bar
|
|
s.sync = sync
|
|
}
|
|
}
|
|
|
|
// BarRemoveOnComplete removes both bar's filler and its decorators
|
|
// on complete event.
|
|
func BarRemoveOnComplete() BarOption {
|
|
return func(s *bState) {
|
|
s.dropOnComplete = true
|
|
}
|
|
}
|
|
|
|
// BarFillerClearOnComplete clears bar's filler on complete event.
|
|
// It's shortcut for BarFillerOnComplete("").
|
|
func BarFillerClearOnComplete() BarOption {
|
|
return BarFillerOnComplete("")
|
|
}
|
|
|
|
// BarFillerOnComplete replaces bar's filler with message, on complete event.
|
|
func BarFillerOnComplete(message string) BarOption {
|
|
return BarFillerMiddleware(func(base BarFiller) BarFiller {
|
|
return BarFillerFunc(func(w io.Writer, reqWidth int, st decor.Statistics) {
|
|
if st.Completed {
|
|
_, err := io.WriteString(w, message)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
} else {
|
|
base.Fill(w, reqWidth, st)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
// BarFillerMiddleware provides a way to augment the underlying BarFiller.
|
|
func BarFillerMiddleware(middle func(BarFiller) BarFiller) BarOption {
|
|
return func(s *bState) {
|
|
s.middleware = middle
|
|
}
|
|
}
|
|
|
|
// BarPriority sets bar's priority. Zero is highest priority, i.e. bar
|
|
// will be on top. If `BarReplaceOnComplete` option is supplied, this
|
|
// option is ignored.
|
|
func BarPriority(priority int) BarOption {
|
|
return func(s *bState) {
|
|
s.priority = priority
|
|
}
|
|
}
|
|
|
|
// BarExtender provides a way to extend bar to the next new line.
|
|
func BarExtender(filler BarFiller) BarOption {
|
|
if filler == nil {
|
|
return nil
|
|
}
|
|
return func(s *bState) {
|
|
s.extender = makeExtenderFunc(filler)
|
|
}
|
|
}
|
|
|
|
func makeExtenderFunc(filler BarFiller) 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"))
|
|
}
|
|
}
|
|
|
|
// BarFillerTrim removes leading and trailing space around the underlying BarFiller.
|
|
func BarFillerTrim() BarOption {
|
|
return func(s *bState) {
|
|
s.trimSpace = true
|
|
}
|
|
}
|
|
|
|
// BarNoPop disables bar pop out of container. Effective when
|
|
// PopCompletedMode of container is enabled.
|
|
func BarNoPop() BarOption {
|
|
return func(s *bState) {
|
|
s.noPop = true
|
|
}
|
|
}
|
|
|
|
// BarOptional will invoke provided option only when cond is true.
|
|
func BarOptional(option BarOption, cond bool) BarOption {
|
|
if cond {
|
|
return option
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BarOptOn will invoke provided option only when higher order predicate
|
|
// evaluates to true.
|
|
func BarOptOn(option BarOption, predicate func() bool) BarOption {
|
|
if predicate() {
|
|
return option
|
|
}
|
|
return nil
|
|
}
|