mirror of
https://github.com/restic/restic.git
synced 2026-06-17 22:24:17 +00:00
109 lines
2.7 KiB
Go
109 lines
2.7 KiB
Go
package progress
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/restic/restic/internal/ui"
|
|
)
|
|
|
|
// CalculateProgressInterval returns the interval configured via RESTIC_PROGRESS_FPS
|
|
// or if unset returns an interval for 60fps on interactive terminals and 0 (=disabled)
|
|
// for non-interactive terminals or when run using the --quiet flag
|
|
func CalculateProgressInterval(show bool, json bool, canUpdateStatus bool) time.Duration {
|
|
interval := time.Second / 10
|
|
fps, err := strconv.ParseFloat(os.Getenv("RESTIC_PROGRESS_FPS"), 64)
|
|
if err == nil && fps > 0 {
|
|
if fps > 60 {
|
|
fps = 60
|
|
}
|
|
interval = time.Duration(float64(time.Second) / fps)
|
|
} else if !json && !canUpdateStatus || !show {
|
|
interval = 0
|
|
}
|
|
return interval
|
|
}
|
|
|
|
// newProgressMax returns a progress.Counter that prints to terminal if provided.
|
|
func newProgressMax(show bool, max uint64, description string, term ui.Terminal) *Counter {
|
|
if !show {
|
|
return nil
|
|
}
|
|
interval := CalculateProgressInterval(show, false, term.CanUpdateStatus())
|
|
|
|
return NewCounter(interval, max, func(v uint64, max uint64, d time.Duration, final bool) {
|
|
var status string
|
|
if max == 0 {
|
|
status = fmt.Sprintf("[%s] %d %s",
|
|
ui.FormatDuration(d), v, description)
|
|
} else {
|
|
status = fmt.Sprintf("[%s] %s %d / %d %s",
|
|
ui.FormatDuration(d), ui.FormatPercent(v, max), v, max, description)
|
|
}
|
|
|
|
if final {
|
|
term.SetStatus(nil)
|
|
term.Print(status)
|
|
} else {
|
|
term.SetStatus([]string{status})
|
|
}
|
|
})
|
|
}
|
|
|
|
type terminalPrinter struct {
|
|
term ui.Terminal
|
|
v uint
|
|
}
|
|
|
|
func (t *terminalPrinter) NewCounter(description string) *Counter {
|
|
return newProgressMax(t.v > 0, 0, description, t.term)
|
|
}
|
|
|
|
func (t *terminalPrinter) NewCounterTerminalOnly(description string) *Counter {
|
|
return newProgressMax(t.v > 0 && t.term.OutputIsTerminal(), 0, description, t.term)
|
|
}
|
|
|
|
func (t *terminalPrinter) E(msg string, args ...interface{}) {
|
|
t.term.Error(fmt.Sprintf(msg, args...))
|
|
}
|
|
|
|
func (t *terminalPrinter) S(msg string, args ...interface{}) {
|
|
t.term.Print(fmt.Sprintf(msg, args...))
|
|
}
|
|
|
|
func (t *terminalPrinter) PT(msg string, args ...interface{}) {
|
|
if t.term.OutputIsTerminal() && t.v >= 1 {
|
|
t.term.Print(fmt.Sprintf(msg, args...))
|
|
}
|
|
}
|
|
|
|
func (t *terminalPrinter) P(msg string, args ...interface{}) {
|
|
if t.v >= 1 {
|
|
t.term.Print(fmt.Sprintf(msg, args...))
|
|
}
|
|
}
|
|
|
|
func (t *terminalPrinter) V(msg string, args ...interface{}) {
|
|
if t.v >= 2 {
|
|
t.term.Print(fmt.Sprintf(msg, args...))
|
|
}
|
|
}
|
|
|
|
func (t *terminalPrinter) VV(msg string, args ...interface{}) {
|
|
if t.v >= 3 {
|
|
t.term.Print(fmt.Sprintf(msg, args...))
|
|
}
|
|
}
|
|
|
|
func NewTerminalPrinter(json bool, verbosity uint, term ui.Terminal) Printer {
|
|
if json {
|
|
verbosity = 0
|
|
}
|
|
return &terminalPrinter{
|
|
term: term,
|
|
v: verbosity,
|
|
}
|
|
}
|