restore: embed progress.Printer in restore-specific printer

This commit is contained in:
Michael Eischer 2025-09-14 19:51:08 +02:00
parent 1a76f988ea
commit 1939cff334
6 changed files with 29 additions and 21 deletions

View file

@ -89,13 +89,19 @@ func (opts *RestoreOptions) AddFlags(f *pflag.FlagSet) {
func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions, func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
term ui.Terminal, args []string) error { term ui.Terminal, args []string) error {
msg := ui.NewProgressPrinter(gopts.JSON, gopts.verbosity, term) var printer restoreui.ProgressPrinter
excludePatternFns, err := opts.ExcludePatternOptions.CollectPatterns(msg.E) if gopts.JSON {
printer = restoreui.NewJSONProgress(term, gopts.verbosity)
} else {
printer = restoreui.NewTextProgress(term, gopts.verbosity)
}
excludePatternFns, err := opts.ExcludePatternOptions.CollectPatterns(printer.E)
if err != nil { if err != nil {
return err return err
} }
includePatternFns, err := opts.IncludePatternOptions.CollectPatterns(msg.E) includePatternFns, err := opts.IncludePatternOptions.CollectPatterns(printer.E)
if err != nil { if err != nil {
return err return err
} }
@ -130,7 +136,7 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
debug.Log("restore %v to %v", snapshotIDString, opts.Target) debug.Log("restore %v to %v", snapshotIDString, opts.Target)
ctx, repo, unlock, err := openWithReadLock(ctx, gopts, gopts.NoLock, msg) ctx, repo, unlock, err := openWithReadLock(ctx, gopts, gopts.NoLock, printer)
if err != nil { if err != nil {
return err return err
} }
@ -145,7 +151,7 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
return errors.Fatalf("failed to find snapshot: %v", err) return errors.Fatalf("failed to find snapshot: %v", err)
} }
bar := ui.NewIndexCounter(msg) bar := ui.NewIndexCounter(printer)
err = repo.LoadIndex(ctx, bar) err = repo.LoadIndex(ctx, bar)
if err != nil { if err != nil {
return err return err
@ -156,13 +162,6 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
return err return err
} }
var printer restoreui.ProgressPrinter
if gopts.JSON {
printer = restoreui.NewJSONProgress(term, gopts.verbosity)
} else {
printer = restoreui.NewTextProgress(term, gopts.verbosity)
}
progress := restoreui.NewProgress(printer, ui.CalculateProgressInterval(!gopts.Quiet, gopts.JSON, term.CanUpdateStatus())) progress := restoreui.NewProgress(printer, ui.CalculateProgressInterval(!gopts.Quiet, gopts.JSON, term.CanUpdateStatus()))
res := restorer.NewRestorer(repo, sn, restorer.Options{ res := restorer.NewRestorer(repo, sn, restorer.Options{
DryRun: opts.DryRun, DryRun: opts.DryRun,
@ -178,13 +177,13 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
return progress.Error(location, err) return progress.Error(location, err)
} }
res.Warn = func(message string) { res.Warn = func(message string) {
msg.E("Warning: %s\n", message) printer.E("Warning: %s\n", message)
} }
res.Info = func(message string) { res.Info = func(message string) {
if gopts.JSON { if gopts.JSON {
return return
} }
msg.P("Info: %s\n", message) printer.P("Info: %s\n", message)
} }
selectExcludeFilter := func(item string, isDir bool) (selectedForRestore bool, childMayBeSelected bool) { selectExcludeFilter := func(item string, isDir bool) (selectedForRestore bool, childMayBeSelected bool) {
@ -232,13 +231,13 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
res.SelectFilter = selectIncludeFilter res.SelectFilter = selectIncludeFilter
} }
res.XattrSelectFilter, err = getXattrSelectFilter(opts, msg) res.XattrSelectFilter, err = getXattrSelectFilter(opts, printer)
if err != nil { if err != nil {
return err return err
} }
if !gopts.JSON { if !gopts.JSON {
msg.P("restoring %s to %s\n", res.Snapshot(), opts.Target) printer.P("restoring %s to %s\n", res.Snapshot(), opts.Target)
} }
countRestoredFiles, err := res.RestoreTo(ctx, opts.Target) countRestoredFiles, err := res.RestoreTo(ctx, opts.Target)
@ -254,11 +253,11 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
if opts.Verify { if opts.Verify {
if !gopts.JSON { if !gopts.JSON {
msg.P("verifying files in %s\n", opts.Target) printer.P("verifying files in %s\n", opts.Target)
} }
var count int var count int
t0 := time.Now() t0 := time.Now()
bar := msg.NewCounterTerminalOnly("files verified") bar := printer.NewCounterTerminalOnly("files verified")
count, err = res.VerifyFiles(ctx, opts.Target, countRestoredFiles, bar) count, err = res.VerifyFiles(ctx, opts.Target, countRestoredFiles, bar)
if err != nil { if err != nil {
return err return err
@ -268,7 +267,7 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
} }
if !gopts.JSON { if !gopts.JSON {
msg.P("finished verifying %d files in %s (took %s)\n", count, opts.Target, printer.P("finished verifying %d files in %s (took %s)\n", count, opts.Target,
time.Since(t0).Round(time.Millisecond)) time.Since(t0).Round(time.Millisecond))
} }
} }

View file

@ -999,6 +999,7 @@ func TestRestorerSparseOverwrite(t *testing.T) {
type printerMock struct { type printerMock struct {
s restoreui.State s restoreui.State
progress.NoopPrinter
} }
func (p *printerMock) Update(_ restoreui.State, _ time.Duration) { func (p *printerMock) Update(_ restoreui.State, _ time.Duration) {

View file

@ -4,15 +4,19 @@ import (
"time" "time"
"github.com/restic/restic/internal/ui" "github.com/restic/restic/internal/ui"
"github.com/restic/restic/internal/ui/progress"
) )
type jsonPrinter struct { type jsonPrinter struct {
progress.Printer
terminal ui.Terminal terminal ui.Terminal
verbosity uint verbosity uint
} }
func NewJSONProgress(terminal ui.Terminal, verbosity uint) ProgressPrinter { func NewJSONProgress(terminal ui.Terminal, verbosity uint) ProgressPrinter {
return &jsonPrinter{ return &jsonPrinter{
Printer: ui.NewProgressPrinter(true, verbosity, terminal),
terminal: terminal, terminal: terminal,
verbosity: verbosity, verbosity: verbosity,
} }

View file

@ -38,6 +38,7 @@ type ProgressPrinter interface {
Error(item string, err error) error Error(item string, err error) error
CompleteItem(action ItemAction, item string, size uint64) CompleteItem(action ItemAction, item string, size uint64)
Finish(progress State, duration time.Duration) Finish(progress State, duration time.Duration)
progress.Printer
} }
type ItemAction string type ItemAction string

View file

@ -6,6 +6,7 @@ import (
"github.com/restic/restic/internal/errors" "github.com/restic/restic/internal/errors"
"github.com/restic/restic/internal/test" "github.com/restic/restic/internal/test"
"github.com/restic/restic/internal/ui/progress"
) )
type printerTraceEntry struct { type printerTraceEntry struct {
@ -36,6 +37,7 @@ type mockPrinter struct {
trace printerTrace trace printerTrace
items itemTrace items itemTrace
errors errorTrace errors errorTrace
progress.NoopPrinter
} }
const mockFinishDuration = 42 * time.Second const mockFinishDuration = 42 * time.Second

View file

@ -5,17 +5,18 @@ import (
"time" "time"
"github.com/restic/restic/internal/ui" "github.com/restic/restic/internal/ui"
"github.com/restic/restic/internal/ui/progress"
) )
type textPrinter struct { type textPrinter struct {
*ui.Message progress.Printer
terminal ui.Terminal terminal ui.Terminal
} }
func NewTextProgress(terminal ui.Terminal, verbosity uint) ProgressPrinter { func NewTextProgress(terminal ui.Terminal, verbosity uint) ProgressPrinter {
return &textPrinter{ return &textPrinter{
Message: ui.NewMessage(terminal, verbosity), Printer: ui.NewProgressPrinter(false, verbosity, terminal),
terminal: terminal, terminal: terminal,
} }
} }