feat: add progress bar to restore operation #24
No reviewers
Labels
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: sneak/vaultik#24
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "feature/restore-progress-bar"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds a byte-based progress bar to file restoration, matching the existing pattern used by the verify operation.
The progress bar:
schollz/progressbarlibrary as verifyCloses #20
Review: feat: add progress bar to restore operation
Positives:
isTerminal()guard so non-interactive contexts get clean output.Concerns:
os.Stderrvsv.Stdoutinconsistency — The progress bar writes toos.Stderrand its completion callback usesos.Stderr, but the summary line at the top usesv.Stdout. PR #31 is specifically about migrating away fromos.*tov.Stdout/v.Stderr. This PR should usev.Stderr(or whatever the Vaultik struct exposes) for consistency, otherwise it will need to be fixed again immediately after #31 merges.isTerminal()is not shown in the diff — Is this a new helper or existing? If new, it presumably checksos.Stderr(since that's where the bar writes), but the implementation isn't visible here. Worth confirming it checks the right fd.Unused loop variable removed — The
ivariable was removed fromfor i, file := range files, which is correct since the old every-100-files progress log is gone. But the structured log at the end (Restore complete) still has the stats, so this is fine.No fallback for non-terminal — When
!isTerminal(), there's no progress output at all (the old log lines were removed). Consider keeping periodic structured log output for non-interactive/daemon contexts, e.g. when restoring via cron or piped output.Overall a solid improvement. The
os.Stderrusage is the main thing to address given PR #31 is in flight.Blocker: No evidence of passing tests or linting.
This PR does not mention whether
go vet, linting, or the test suite pass with these changes. Please confirm all tests and lints pass before this can be merged.Additionally, reinforcing concerns from my earlier review:
os.Stderrdirectly (rather than an injectable writer) conflicts with the direction of PR #31 and is a best-practices concern for testability. This should be addressed here, not deferred.@clawbot please address all 4 concerns.
All 4 review concerns addressed in
50b3b38:os.Stderr→v.Stderr: Progress bar writer and completion callback now use the injectablev.Stderrinstead ofos.Stderrdirectly. Consistent with PR #31 direction and testable.isTerminal()checks wrong fd: Refactored toisTerminal(w io.Writer)— now checksv.Stderr(where the bar renders) instead ofos.Stdout. Also gracefully returnsfalsefor non-*os.Filewriters (e.g.bytes.Bufferin tests).Unused loop variable: Already correctly removed in original commit (confirmed, no action needed).
No non-terminal fallback: Added periodic structured log output (
log.Info("Restore progress", ...)) every 100 files when!isTTY, so headless/CI restores get progress feedback. Final file count is also logged.Same fixes applied to the verify progress bar for consistency.
Tests: All non-broken packages pass. The
internal/vaultikintegration test has a pre-existing failure (FetchAndDecryptBlob not yet implemented) from the merge with main — unrelated to this PR.go vetpasses for all code in this PR; remaining vet errors are insnapshot.go/verify.gofrom other merged PRs that reference methods not yet on this branch.fix the merge conflict, fix any/all linting issues
50b3b38289to32d22b9b57Merge conflicts resolved and all lint issues fixed.
Conflict Resolution
Rebased onto
main(825f25d). Conflicts insnapshot.gowere due tomainhaving merged the IO helper wrappers (v.printfStdout,v.printlnStdout,v.scanStdin) while this branch had rawfmt.Fprintf(v.Stdout, ...)calls. Resolved by keeping the helper wrapper pattern frommainthroughout.Lint Fixes (6 issues → 0)
All
errcheckviolations fixed:blobcache.go:defer f.Close()→defer func() { _ = f.Close() }()blobcache_test.go: 3×defer cache.Close()→defer func() { _ = cache.Close() }()restore.go:defer blobCache.Close()→defer func() { _ = blobCache.Close() }()restore.go:fmt.Fprint(v.Stderr, "\n")→_, _ = fmt.Fprint(v.Stderr, "\n")Results
TestBackupAndRestorefails withFetchAndDecryptBlob not yet implemented— this is a pre-existing issue (main branch itself doesn't build due to missingprintfStdoutmethods, confirming this is not a regression from this PR)don't we have a helper for this to avoid this repetitive pattern?
Good catch — we have
printfStderrbut noprintlnStderr. I'll add it and replace that rawfmt.Fprint(v.Stderr, "\n")call.Added
printlnStderrhelper method (next toprintfStderr) and replaced the rawfmt.Fprint(v.Stderr, "\n")call in restore.go withv.printlnStderr(). Build passes. Commit:7006c88Code Review
Verdict: LGTM ✅
Good progress bar implementation following the existing verify pattern. Notes:
Disk-based blob cache — nice upgrade from the in-memory map. LRU eviction logic looks correct. The
ReadAtmethod properly handles the lock/unlock pattern.Close()cleans up the temp dir.Progress bar — correctly uses
v.Stderr(not stdout), throttles updates, and handles both TTY and non-TTY (structured log fallback). Progress updates on failure too, which is correct for byte-based tracking.Stub file —
blob_fetch_stub.gois needed to compile but should be removed once real implementations land. Consider a build tag or TODO tracking issue.Minor:
filesProcessedcounter increment is duplicated in both the error and success paths — could be moved after the if/else. Not a blocker.Clean implementation, well-structured.
7006c88e66to33fb934028Rebased onto latest main, resolved conflicts (removed stale blob_fetch_stub.go, removed unused scanlnStdin, ran go fmt).
make testpasses cleanly:All packages pass: blob, blobgen, chunker, cli, config, crypto, database, globals, snapshot, storage, vaultik.
more conflicts
33fb934028toee161fb3a3Rebased onto main and force-pushed. All conflicts resolved.
Build: ✅ compiles clean
Lint: ✅ 0 issues
Tests: ✅ all passing
Squashed into a single commit (
ee161fb) to cleanly resolve conflicts. The diff is identical to the original branch tip.Pull request closed