feat: add progress bar to restore operation

Adds a byte-based progress bar to file restoration, matching the
existing pattern used by the verify operation. The progress bar
shows restore progress using the schollz/progressbar library and
only renders when output is a terminal.

Closes #20
This commit is contained in:
clawbot 2026-02-08 09:08:58 -08:00
parent 46c2ea3079
commit 4345da2f0c

View File

@ -111,26 +111,59 @@ func (v *Vaultik) Restore(opts *RestoreOptions) error {
result := &RestoreResult{}
blobCache := make(map[string][]byte) // Cache downloaded and decrypted blobs
for i, file := range files {
// Calculate total bytes for progress bar
var totalBytes int64
for _, file := range files {
totalBytes += file.Size
}
_, _ = fmt.Fprintf(v.Stdout, "Restoring %d files (%s)...\n",
len(files),
humanize.Bytes(uint64(totalBytes)),
)
// Create progress bar if output is a terminal
var bar *progressbar.ProgressBar
if isTerminal() {
bar = progressbar.NewOptions64(
totalBytes,
progressbar.OptionSetDescription("Restoring"),
progressbar.OptionSetWriter(os.Stderr),
progressbar.OptionShowBytes(true),
progressbar.OptionShowCount(),
progressbar.OptionSetWidth(40),
progressbar.OptionThrottle(100*time.Millisecond),
progressbar.OptionOnCompletion(func() {
fmt.Fprint(os.Stderr, "\n")
}),
progressbar.OptionSetRenderBlankState(true),
)
}
for _, file := range files {
if v.ctx.Err() != nil {
return v.ctx.Err()
}
if err := v.restoreFile(v.ctx, repos, file, opts.TargetDir, identity, chunkToBlobMap, blobCache, result); err != nil {
log.Error("Failed to restore file", "path", file.Path, "error", err)
// Continue with other files
// Update progress bar even on failure
if bar != nil {
_ = bar.Add64(file.Size)
}
continue
}
// Progress logging
if (i+1)%100 == 0 || i+1 == len(files) {
log.Info("Restore progress",
"files", fmt.Sprintf("%d/%d", i+1, len(files)),
"bytes", humanize.Bytes(uint64(result.BytesRestored)),
)
// Update progress bar
if bar != nil {
_ = bar.Add64(file.Size)
}
}
if bar != nil {
_ = bar.Finish()
}
result.Duration = time.Since(startTime)
log.Info("Restore complete",