diff --git a/internal/vaultik/restore.go b/internal/vaultik/restore.go index 3b974cf..20f7ba8 100644 --- a/internal/vaultik/restore.go +++ b/internal/vaultik/restore.go @@ -22,6 +22,13 @@ import ( "golang.org/x/term" ) +const ( + // progressBarWidth is the character width of the progress bar display. + progressBarWidth = 40 + // progressBarThrottle is the minimum interval between progress bar redraws. + progressBarThrottle = 100 * time.Millisecond +) + // RestoreOptions contains options for the restore operation type RestoreOptions struct { SnapshotID string @@ -122,22 +129,7 @@ func (v *Vaultik) Restore(opts *RestoreOptions) error { } // Create progress bar if output is a terminal - var bar *progressbar.ProgressBar - if v.isTerminal() { - bar = progressbar.NewOptions64( - totalBytesExpected, - progressbar.OptionSetDescription("Restoring"), - progressbar.OptionSetWriter(v.Stderr), - progressbar.OptionShowBytes(true), - progressbar.OptionShowCount(), - progressbar.OptionSetWidth(40), - progressbar.OptionThrottle(100*time.Millisecond), - progressbar.OptionOnCompletion(func() { - v.printfStderr("\n") - }), - progressbar.OptionSetRenderBlankState(true), - ) - } + bar := v.newProgressBar("Restoring", totalBytesExpected) for i, file := range files { if v.ctx.Err() != nil { @@ -572,22 +564,7 @@ func (v *Vaultik) verifyRestoredFiles( ) // Create progress bar if output is a terminal - var bar *progressbar.ProgressBar - if v.isTerminal() { - bar = progressbar.NewOptions64( - totalBytes, - progressbar.OptionSetDescription("Verifying"), - progressbar.OptionSetWriter(v.Stderr), - progressbar.OptionShowBytes(true), - progressbar.OptionShowCount(), - progressbar.OptionSetWidth(40), - progressbar.OptionThrottle(100*time.Millisecond), - progressbar.OptionOnCompletion(func() { - v.printfStderr("\n") - }), - progressbar.OptionSetRenderBlankState(true), - ) - } + bar := v.newProgressBar("Verifying", totalBytes) // Verify each file for _, file := range regularFiles { @@ -681,6 +658,27 @@ func (v *Vaultik) verifyFile( return bytesVerified, nil } +// newProgressBar creates a terminal-aware progress bar with standard options. +// It returns nil if stdout is not a terminal. +func (v *Vaultik) newProgressBar(description string, total int64) *progressbar.ProgressBar { + if !v.isTerminal() { + return nil + } + return progressbar.NewOptions64( + total, + progressbar.OptionSetDescription(description), + progressbar.OptionSetWriter(v.Stderr), + progressbar.OptionShowBytes(true), + progressbar.OptionShowCount(), + progressbar.OptionSetWidth(progressBarWidth), + progressbar.OptionThrottle(progressBarThrottle), + progressbar.OptionOnCompletion(func() { + v.printfStderr("\n") + }), + progressbar.OptionSetRenderBlankState(true), + ) +} + // isTerminal returns true if stdout is a terminal. // It checks whether v.Stdout implements Fd() (i.e. is an *os.File), // and falls back to false for non-file writers (e.g. in tests).