restic: move Printer interface from internal/ui/progress

Move Printer and NewNoopPrinter to internal/restic so repository does
not have to import the ui packages.
This commit is contained in:
Michael Eischer
2026-06-20 17:49:20 +02:00
parent 0f4236cb39
commit d9d54a505e
44 changed files with 165 additions and 173 deletions
+7 -8
View File
@@ -21,7 +21,6 @@ import (
"github.com/restic/restic/internal/repository/index"
"github.com/restic/restic/internal/repository/pack"
"github.com/restic/restic/internal/restic"
"github.com/restic/restic/internal/ui/progress"
)
type packDumpEntry struct {
@@ -46,7 +45,7 @@ func writePackDumpJSON(wr io.Writer, item any) error {
}
// DumpPacks lists each pack file and writes its header blob layout as JSON to wr.
func DumpPacks(ctx context.Context, repo *Repository, wr io.Writer, printer progress.Printer) error {
func DumpPacks(ctx context.Context, repo *Repository, wr io.Writer, printer restic.Printer) error {
var m sync.Mutex
return restic.ParallelList(ctx, repo, restic.PackFile, repo.Connections(), func(ctx context.Context, id restic.ID, size int64) error {
blobs, err := repo.listPack(ctx, id, size)
@@ -75,7 +74,7 @@ func DumpPacks(ctx context.Context, repo *Repository, wr io.Writer, printer prog
}
// DumpIndexes loads each on-disk index file and writes its debug dump to wr.
func DumpIndexes(ctx context.Context, repo restic.ListerLoaderUnpacked, wr io.Writer, printer progress.Printer) error {
func DumpIndexes(ctx context.Context, repo restic.ListerLoaderUnpacked, wr io.Writer, printer restic.Printer) error {
return index.ForAllIndexes(ctx, repo, repo, func(id restic.ID, idx *index.Index, err error) error {
printer.S("index_id: %v", id)
if err != nil {
@@ -95,7 +94,7 @@ type ExaminePackOptions struct {
}
// ExaminePack loads and inspects a pack file and its index entries.
func ExaminePack(ctx context.Context, repo *Repository, id restic.ID, opts ExaminePackOptions, printer progress.Printer) error {
func ExaminePack(ctx context.Context, repo *Repository, id restic.ID, opts ExaminePackOptions, printer restic.Printer) error {
printer.S("examine %v", id)
buf, err := repo.LoadRaw(ctx, restic.PackFile, id)
@@ -146,7 +145,7 @@ func ExaminePack(ctx context.Context, repo *Repository, id restic.ID, opts Exami
return nil
}
func checkPackSize(blobs pack.Blobs, fileSize int, printer progress.Printer) {
func checkPackSize(blobs pack.Blobs, fileSize int, printer restic.Printer) {
// track current size and offset
var size, offset uint64
@@ -169,7 +168,7 @@ func checkPackSize(blobs pack.Blobs, fileSize int, printer progress.Printer) {
}
}
func tryRepairWithBitflip(key *crypto.Key, input []byte, bytewise bool, printer progress.Printer) []byte {
func tryRepairWithBitflip(key *crypto.Key, input []byte, bytewise bool, printer restic.Printer) []byte {
if bytewise {
printer.S(" trying to repair blob by finding a broken byte")
} else {
@@ -284,7 +283,7 @@ func decryptUnsigned(k *crypto.Key, buf []byte) []byte {
return out
}
func loadBlobs(ctx context.Context, opts ExaminePackOptions, repo *Repository, packID restic.ID, list pack.Blobs, printer progress.Printer) error {
func loadBlobs(ctx context.Context, opts ExaminePackOptions, repo *Repository, packID restic.ID, list pack.Blobs, printer restic.Printer) error {
dec, err := zstd.NewReader(nil)
if err != nil {
panic(err)
@@ -366,7 +365,7 @@ func loadBlobs(ctx context.Context, opts ExaminePackOptions, repo *Repository, p
return err
}
func storePlainBlob(id restic.ID, prefix string, plain []byte, printer progress.Printer) error {
func storePlainBlob(id restic.ID, prefix string, plain []byte, printer restic.Printer) error {
filename := fmt.Sprintf("%s%s.bin", prefix, id)
f, err := os.Create(filename)
if err != nil {
+5 -6
View File
@@ -13,7 +13,6 @@ import (
"github.com/restic/restic/internal/repository/index"
"github.com/restic/restic/internal/repository/pack"
"github.com/restic/restic/internal/restic"
"github.com/restic/restic/internal/ui/progress"
)
var ErrIndexIncomplete = errors.Fatal("index is not complete")
@@ -104,7 +103,7 @@ type packInfoWithID struct {
// PlanPrune selects which files to rewrite and which to delete and which blobs to keep.
// Also some summary statistics are returned.
func PlanPrune(ctx context.Context, opts PruneOptions, repo *Repository, getUsedBlobs func(ctx context.Context, repo restic.Repository, usedBlobs restic.FindBlobSet) error, printer progress.Printer) (*PrunePlan, error) {
func PlanPrune(ctx context.Context, opts PruneOptions, repo *Repository, getUsedBlobs func(ctx context.Context, repo restic.Repository, usedBlobs restic.FindBlobSet) error, printer restic.Printer) (*PrunePlan, error) {
stats := PruneStats{MessageType: "summary"}
if opts.UnsafeRecovery {
@@ -176,7 +175,7 @@ func PlanPrune(ctx context.Context, opts PruneOptions, repo *Repository, getUsed
return &plan, nil
}
func packInfoFromIndex(ctx context.Context, idx restic.ListBlobser, usedBlobs *index.AssociatedSet[uint8], stats *PruneStats, printer progress.Printer) (*index.AssociatedSet[uint8], map[restic.ID]packInfo, error) {
func packInfoFromIndex(ctx context.Context, idx restic.ListBlobser, usedBlobs *index.AssociatedSet[uint8], stats *PruneStats, printer restic.Printer) (*index.AssociatedSet[uint8], map[restic.ID]packInfo, error) {
// iterate over all blobs in index to find out which blobs are duplicates
// The counter in usedBlobs describes how many instances of the blob exist in the repository index
// Thus 0 == blob is missing, 1 == blob exists once, >= 2 == duplicates exist
@@ -384,7 +383,7 @@ func calculateTargetPacksize(opts PruneOptions, indexPack map[restic.ID]packInfo
return targetPackSize
}
func decidePackAction(ctx context.Context, opts PruneOptions, repo *Repository, indexPack map[restic.ID]packInfo, stats *PruneStats, printer progress.Printer) (PrunePlan, error) {
func decidePackAction(ctx context.Context, opts PruneOptions, repo *Repository, indexPack map[restic.ID]packInfo, stats *PruneStats, printer restic.Printer) (PrunePlan, error) {
removePacksFirst := restic.NewIDSet()
removePacks := restic.NewIDSet()
repackPacks := restic.NewIDSet()
@@ -592,7 +591,7 @@ func (plan *PrunePlan) Stats() PruneStats {
// - rebuild the index while ignoring all files that will be deleted
// - delete the files
// plan.removePacks and plan.ignorePacks are modified in this function.
func (plan *PrunePlan) Execute(ctx context.Context, printer progress.Printer) error {
func (plan *PrunePlan) Execute(ctx context.Context, printer restic.Printer) error {
if plan.opts.DryRun {
printer.V("Repeated prune dry-runs can report slightly different amounts of data to keep or repack. This is expected behavior.\n\n")
if len(plan.removePacksFirst) > 0 {
@@ -692,7 +691,7 @@ func (plan *PrunePlan) Execute(ctx context.Context, printer progress.Printer) er
// deleteFiles deletes the given fileList of fileType in parallel
// if ignoreError=true, it will print a warning if there was an error, else it will abort.
func deleteFiles(ctx context.Context, ignoreError bool, repo restic.RemoverUnpacked[restic.FileType], fileList restic.IDSet, fileType restic.FileType, printer progress.Printer) error {
func deleteFiles(ctx context.Context, ignoreError bool, repo restic.RemoverUnpacked[restic.FileType], fileList restic.IDSet, fileType restic.FileType, printer restic.Printer) error {
bar := printer.NewCounter("files deleted")
defer bar.Done()
+2 -3
View File
@@ -9,7 +9,6 @@ import (
"github.com/restic/restic/internal/restic"
rtest "github.com/restic/restic/internal/test"
"github.com/restic/restic/internal/ui/progress"
)
// TestPruneMaxUnusedDuplicate checks that MaxUnused correctly accounts for duplicates.
@@ -70,10 +69,10 @@ func TestPruneMaxUnusedDuplicate(t *testing.T) {
usedBlobs.Insert(blob)
}
return nil
}, progress.NewNoopPrinter())
}, restic.NewNoopPrinter())
rtest.OK(t, err)
rtest.OK(t, plan.Execute(context.TODO(), progress.NewNoopPrinter()))
rtest.OK(t, plan.Execute(context.TODO(), restic.NewNoopPrinter()))
rsize := plan.Stats().Size
remainingUnusedSize := rsize.Duplicate + rsize.Unused - rsize.Remove - rsize.Repackrm
+4 -5
View File
@@ -12,7 +12,6 @@ import (
"github.com/restic/restic/internal/repository/pack"
"github.com/restic/restic/internal/restic"
rtest "github.com/restic/restic/internal/test"
"github.com/restic/restic/internal/ui/progress"
)
func testPrune(t *testing.T, opts repository.PruneOptions, errOnUnused bool) {
@@ -41,10 +40,10 @@ func testPrune(t *testing.T, opts repository.PruneOptions, errOnUnused bool) {
usedBlobs.Insert(blob)
}
return nil
}, progress.NewNoopPrinter())
}, restic.NewNoopPrinter())
rtest.OK(t, err)
rtest.OK(t, plan.Execute(context.TODO(), progress.NewNoopPrinter()))
rtest.OK(t, plan.Execute(context.TODO(), restic.NewNoopPrinter()))
repo = repository.TestOpenBackend(t, be)
repository.TestCheckRepo(t, repo)
@@ -165,9 +164,9 @@ func TestPruneSmall(t *testing.T) {
usedBlobs.Insert(blob)
}
return nil
}, progress.NewNoopPrinter())
}, restic.NewNoopPrinter())
rtest.OK(t, err)
rtest.OK(t, plan.Execute(context.TODO(), progress.NewNoopPrinter()))
rtest.OK(t, plan.Execute(context.TODO(), restic.NewNoopPrinter()))
stats := plan.Stats()
rtest.Equals(t, stats.Size.Used/blobSize, uint64(numBlobsCreated), fmt.Sprintf("total size of blobs should be %d but is %d",
+1 -2
View File
@@ -10,7 +10,6 @@ import (
"github.com/restic/restic/internal/repository"
"github.com/restic/restic/internal/restic"
rtest "github.com/restic/restic/internal/test"
"github.com/restic/restic/internal/ui/progress"
)
func randomSize(random *rand.Rand, min, max int) int {
@@ -161,7 +160,7 @@ func repack(t *testing.T, repo *repository.Repository, be backend.Backend, packs
func rebuildAndReloadIndex(t *testing.T, repo *repository.Repository) {
rtest.OK(t, repository.RepairIndex(context.TODO(), repo, repository.RepairIndexOptions{
ReadAllPacks: true,
}, progress.NewNoopPrinter()))
}, restic.NewNoopPrinter()))
rtest.OK(t, repo.LoadIndex(context.TODO(), restic.NoopTerminalCounterFactory))
}
+2 -3
View File
@@ -6,14 +6,13 @@ import (
"github.com/restic/restic/internal/repository/index"
"github.com/restic/restic/internal/repository/pack"
"github.com/restic/restic/internal/restic"
"github.com/restic/restic/internal/ui/progress"
)
type RepairIndexOptions struct {
ReadAllPacks bool
}
func RepairIndex(ctx context.Context, repo *Repository, opts RepairIndexOptions, printer progress.Printer) error {
func RepairIndex(ctx context.Context, repo *Repository, opts RepairIndexOptions, printer restic.Printer) error {
var obsoleteIndexes restic.IDs
packSizeFromList := make(map[restic.ID]int64)
packSizeFromIndex := make(map[restic.ID]int64)
@@ -103,7 +102,7 @@ func RepairIndex(ctx context.Context, repo *Repository, opts RepairIndexOptions,
return nil
}
func rewriteIndexFiles(ctx context.Context, repo *Repository, removePacks restic.IDSet, oldIndexes restic.IDSet, extraObsolete restic.IDs, printer progress.Printer) error {
func rewriteIndexFiles(ctx context.Context, repo *Repository, removePacks restic.IDSet, oldIndexes restic.IDSet, extraObsolete restic.IDs, printer restic.Printer) error {
printer.P("rebuilding index\n")
bar := printer.NewCounter("indexes processed")
+1 -2
View File
@@ -10,7 +10,6 @@ import (
"github.com/restic/restic/internal/repository"
"github.com/restic/restic/internal/restic"
rtest "github.com/restic/restic/internal/test"
"github.com/restic/restic/internal/ui/progress"
)
func listIndex(t *testing.T, repo restic.Lister) restic.IDSet {
@@ -33,7 +32,7 @@ func testRebuildIndex(t *testing.T, readAllPacks bool, damage func(t *testing.T,
repo = repository.TestOpenBackend(t, be)
rtest.OK(t, repository.RepairIndex(context.TODO(), repo, repository.RepairIndexOptions{
ReadAllPacks: readAllPacks,
}, progress.NewNoopPrinter()))
}, restic.NewNoopPrinter()))
repository.TestCheckRepo(t, repo)
}
+2 -3
View File
@@ -8,10 +8,9 @@ import (
"github.com/restic/restic/internal/repository/pack"
"github.com/restic/restic/internal/restic"
"github.com/restic/restic/internal/ui/progress"
)
func RepairPacks(ctx context.Context, repo *Repository, ids restic.IDSet, printer progress.Printer) error {
func RepairPacks(ctx context.Context, repo *Repository, ids restic.IDSet, printer restic.Printer) error {
printer.P("salvaging intact data from specified pack files")
bar := printer.NewCounter("pack files")
bar.SetMax(uint64(len(ids)))
@@ -92,7 +91,7 @@ func resolveBlobsForPacks(ctx context.Context, repo *Repository, ids restic.IDSe
return packToBlobs, nil
}
func reuploadBlobsFromPack(ctx context.Context, repo *Repository, packID restic.ID, blobs pack.Blobs, printer progress.Printer, uploader restic.BlobSaverWithAsync) error {
func reuploadBlobsFromPack(ctx context.Context, repo *Repository, packID restic.ID, blobs pack.Blobs, printer restic.Printer, uploader restic.BlobSaverWithAsync) error {
err := repo.loadBlobsFromPack(ctx, packID, blobs, func(blob restic.BlobHandle, buf []byte, err error) error {
if err != nil {
printer.E("failed to load blob %v: %v", blob.ID, err)
+2 -3
View File
@@ -11,7 +11,6 @@ import (
"github.com/restic/restic/internal/repository"
"github.com/restic/restic/internal/restic"
rtest "github.com/restic/restic/internal/test"
"github.com/restic/restic/internal/ui/progress"
)
func listBlobs(repo restic.Repository) restic.BlobSet {
@@ -105,7 +104,7 @@ func testRepairBrokenPack(t *testing.T, version uint) {
buf, err := backendtest.LoadAll(context.TODO(), be, h)
rtest.OK(t, err)
rtest.OK(t, be.Remove(context.TODO(), h))
rtest.OK(t, repository.RepairIndex(context.TODO(), repo, repository.RepairIndexOptions{}, progress.NewNoopPrinter()))
rtest.OK(t, repository.RepairIndex(context.TODO(), repo, repository.RepairIndexOptions{}, restic.NewNoopPrinter()))
rtest.OK(t, be.Save(context.TODO(), h, backend.NewByteReader(buf, be.Hasher())))
@@ -129,7 +128,7 @@ func testRepairBrokenPack(t *testing.T, version uint) {
toRepair, damagedBlobs := test.damage(t, random, repo, be, packsBefore)
rtest.OK(t, repository.RepairPacks(context.TODO(), repo, toRepair, progress.NewNoopPrinter()))
rtest.OK(t, repository.RepairPacks(context.TODO(), repo, toRepair, restic.NewNoopPrinter()))
// reload index
rtest.OK(t, repo.LoadIndex(context.TODO(), restic.NoopTerminalCounterFactory))