Files
restic/internal/ui/stats/progress.go
T
2026-06-13 17:00:11 +02:00

95 lines
2.1 KiB
Go

package stats
import (
"fmt"
"sync"
"time"
"github.com/restic/restic/internal/ui"
"github.com/restic/restic/internal/ui/progress"
)
// Progress reports progress for the stats command.
type Progress struct {
progress.Updater
term ui.Terminal
m sync.Mutex
snapshotCount uint64
show bool
processedSnapshotCount uint64
processedFileCount uint64
processedBlobCount uint64
processedSize uint64
}
// NewProgress returns a new stats progress reporter.
func NewProgress(term ui.Terminal, quiet, json bool, snapshotCount uint64) *Progress {
p := newProgress(term, !json, snapshotCount)
p.Updater = *progress.NewUpdater(
progress.CalculateProgressInterval(!quiet, json, term.CanUpdateStatus()),
p.printProgress,
)
return p
}
func newProgress(term ui.Terminal, show bool, snapshotCount uint64) *Progress {
return &Progress{
term: term,
snapshotCount: snapshotCount,
show: show,
}
}
func (p *Progress) printProgress(runtime time.Duration, final bool) {
if !p.show {
return
}
p.m.Lock()
progressBase := p.processedSnapshotCount
if progressBase > 0 && !final {
progressBase--
}
status := fmt.Sprintf("[%s] %s %d / %d snapshots", ui.FormatDuration(runtime), ui.FormatPercent(progressBase, p.snapshotCount), p.processedSnapshotCount, p.snapshotCount)
if p.processedFileCount > 0 {
status += fmt.Sprintf(", %v files", p.processedFileCount)
}
if p.processedBlobCount > 0 {
status += fmt.Sprintf(", %d blobs", p.processedBlobCount)
}
status += fmt.Sprintf(", %s", ui.FormatBytes(p.processedSize))
p.m.Unlock()
if final {
p.term.SetStatus(nil)
p.term.Print(status)
} else {
p.term.SetStatus([]string{status})
}
}
func (p *Progress) Update(fileCount uint64, blobCount uint64, size uint64) {
p.m.Lock()
defer p.m.Unlock()
p.processedFileCount += fileCount
p.processedBlobCount += blobCount
p.processedSize += size
}
func (p *Progress) ProcessSnapshot() {
p.m.Lock()
defer p.m.Unlock()
p.processedSnapshotCount++
p.processedFileCount = 0
p.processedBlobCount = 0
p.processedSize = 0
}