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,
term ui.Terminal, args []string) error {
msg := ui.NewProgressPrinter(gopts.JSON, gopts.verbosity, term)
excludePatternFns, err := opts.ExcludePatternOptions.CollectPatterns(msg.E)
var printer restoreui.ProgressPrinter
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 {
return err
}
includePatternFns, err := opts.IncludePatternOptions.CollectPatterns(msg.E)
includePatternFns, err := opts.IncludePatternOptions.CollectPatterns(printer.E)
if err != nil {
return err
}
@ -130,7 +136,7 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
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 {
return err
}
@ -145,7 +151,7 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
return errors.Fatalf("failed to find snapshot: %v", err)
}
bar := ui.NewIndexCounter(msg)
bar := ui.NewIndexCounter(printer)
err = repo.LoadIndex(ctx, bar)
if err != nil {
return err
@ -156,13 +162,6 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
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()))
res := restorer.NewRestorer(repo, sn, restorer.Options{
DryRun: opts.DryRun,
@ -178,13 +177,13 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
return progress.Error(location, err)
}
res.Warn = func(message string) {
msg.E("Warning: %s\n", message)
printer.E("Warning: %s\n", message)
}
res.Info = func(message string) {
if gopts.JSON {
return
}
msg.P("Info: %s\n", message)
printer.P("Info: %s\n", message)
}
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.XattrSelectFilter, err = getXattrSelectFilter(opts, msg)
res.XattrSelectFilter, err = getXattrSelectFilter(opts, printer)
if err != nil {
return err
}
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)
@ -254,11 +253,11 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
if opts.Verify {
if !gopts.JSON {
msg.P("verifying files in %s\n", opts.Target)
printer.P("verifying files in %s\n", opts.Target)
}
var count int
t0 := time.Now()
bar := msg.NewCounterTerminalOnly("files verified")
bar := printer.NewCounterTerminalOnly("files verified")
count, err = res.VerifyFiles(ctx, opts.Target, countRestoredFiles, bar)
if err != nil {
return err
@ -268,7 +267,7 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
}
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))
}
}

View file

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

View file

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

View file

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

View file

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

View file

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