2022-05-02 09:06:34 +02:00
|
|
|
// Package barpool provides access to the global
|
|
|
|
// pool of progress bars, so they could be rendered
|
|
|
|
// altogether.
|
|
|
|
package barpool
|
|
|
|
|
2023-06-02 14:57:08 +02:00
|
|
|
import (
|
|
|
|
"fmt"
|
2024-06-10 12:20:52 +02:00
|
|
|
"io"
|
2023-06-02 14:57:08 +02:00
|
|
|
"os"
|
|
|
|
|
|
|
|
"github.com/cheggaaa/pb/v3"
|
2024-06-10 12:20:52 +02:00
|
|
|
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmctl/terminal"
|
2023-06-02 14:57:08 +02:00
|
|
|
)
|
2022-05-02 09:06:34 +02:00
|
|
|
|
2024-06-10 12:20:52 +02:00
|
|
|
var isDisabled bool
|
|
|
|
|
|
|
|
// Disable sets progress bar to be no-op if v==true
|
|
|
|
func Disable(v bool) {
|
|
|
|
isDisabled = v
|
|
|
|
}
|
|
|
|
|
2022-05-02 09:06:34 +02:00
|
|
|
var pool = pb.NewPool()
|
|
|
|
|
2024-06-10 12:20:52 +02:00
|
|
|
// Bar is an interface for progress bar
|
|
|
|
type Bar interface {
|
|
|
|
Add(value int)
|
|
|
|
Increment()
|
|
|
|
Start()
|
|
|
|
Finish()
|
|
|
|
NewProxyReader(r io.Reader) *pb.Reader
|
|
|
|
}
|
|
|
|
|
|
|
|
type progressBar struct {
|
|
|
|
*pb.ProgressBar
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pb *progressBar) Finish() { pb.ProgressBar.Finish() }
|
|
|
|
func (pb *progressBar) Start() { pb.ProgressBar.Start() }
|
|
|
|
func (pb *progressBar) Add(value int) { pb.ProgressBar.Add(value) }
|
|
|
|
func (pb *progressBar) Increment() { pb.ProgressBar.Increment() }
|
|
|
|
func (pb *progressBar) NewProxyReader(r io.Reader) *pb.Reader {
|
|
|
|
return pb.ProgressBar.NewProxyReader(r)
|
|
|
|
}
|
|
|
|
|
|
|
|
type progressBarNoOp struct{}
|
|
|
|
|
|
|
|
func (pbno *progressBarNoOp) Finish() {}
|
|
|
|
func (pbno *progressBarNoOp) Start() {}
|
|
|
|
func (pbno *progressBarNoOp) Add(int) {}
|
|
|
|
func (pbno *progressBarNoOp) Increment() {}
|
|
|
|
func (pbno *progressBarNoOp) NewProxyReader(_ io.Reader) *pb.Reader { return nil }
|
2022-05-02 09:06:34 +02:00
|
|
|
|
|
|
|
// Start starts the global pool
|
|
|
|
// Must be called after all progress bars were added
|
2024-06-10 12:20:52 +02:00
|
|
|
func Start() error {
|
|
|
|
if isDisabled {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return pool.Start()
|
|
|
|
}
|
2022-05-02 09:06:34 +02:00
|
|
|
|
|
|
|
// Stop stops the global pool
|
2024-06-10 12:20:52 +02:00
|
|
|
func Stop() {
|
|
|
|
if isDisabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
_ = pool.Stop()
|
|
|
|
}
|
2022-05-02 09:06:34 +02:00
|
|
|
|
|
|
|
// AddWithTemplate adds bar with the given template
|
|
|
|
// to the global pool
|
2024-06-10 12:20:52 +02:00
|
|
|
func AddWithTemplate(format string, total int) Bar {
|
|
|
|
if isDisabled {
|
|
|
|
return &progressBarNoOp{}
|
|
|
|
}
|
2023-06-02 14:57:08 +02:00
|
|
|
tpl := getTemplate(format)
|
|
|
|
bar := pb.ProgressBarTemplate(tpl).New(total)
|
2024-06-10 12:20:52 +02:00
|
|
|
pool.Add(bar)
|
|
|
|
return &progressBar{bar}
|
2022-05-02 09:06:34 +02:00
|
|
|
}
|
2023-06-02 14:57:08 +02:00
|
|
|
|
|
|
|
// NewSingleProgress returns progress bar with given template
|
2024-06-10 12:20:52 +02:00
|
|
|
func NewSingleProgress(format string, total int) Bar {
|
|
|
|
if isDisabled {
|
|
|
|
return &progressBarNoOp{}
|
|
|
|
}
|
2023-06-02 14:57:08 +02:00
|
|
|
tpl := getTemplate(format)
|
2024-06-10 12:20:52 +02:00
|
|
|
return &progressBar{pb.ProgressBarTemplate(tpl).New(total)}
|
2023-06-02 14:57:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func getTemplate(format string) string {
|
|
|
|
isTerminal := terminal.IsTerminal(int(os.Stdout.Fd()))
|
|
|
|
if !isTerminal {
|
|
|
|
format = fmt.Sprintf("%s\n", format)
|
|
|
|
}
|
|
|
|
return format
|
|
|
|
}
|