2
2
mirror of https://github.com/octoleo/restic.git synced 2024-12-24 03:45:27 +00:00

Merge pull request #4694 from restic/update-go-versions

Update go versions
This commit is contained in:
Michael Eischer 2024-02-11 17:10:12 +00:00 committed by GitHub
commit 667a2f5369
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 72 additions and 62 deletions

View File

@ -13,7 +13,7 @@ permissions:
contents: read
env:
latest_go: "1.21.x"
latest_go: "1.22.x"
GO111MODULE: on
jobs:
@ -23,27 +23,32 @@ jobs:
# list of jobs to run:
include:
- job_name: Windows
go: 1.21.x
go: 1.22.x
os: windows-latest
- job_name: macOS
go: 1.21.x
go: 1.22.x
os: macOS-latest
test_fuse: false
- job_name: Linux
go: 1.21.x
go: 1.22.x
os: ubuntu-latest
test_cloud_backends: true
test_fuse: true
check_changelog: true
- job_name: Linux (race)
go: 1.21.x
go: 1.22.x
os: ubuntu-latest
test_fuse: true
test_opts: "-race"
- job_name: Linux
go: 1.21.x
os: ubuntu-latest
test_fuse: true
- job_name: Linux
go: 1.20.x
os: ubuntu-latest
@ -255,7 +260,7 @@ jobs:
uses: golangci/golangci-lint-action@v3
with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
version: v1.55.2
version: v1.56.1
args: --verbose --timeout 5m
# only run golangci-lint for pull requests, otherwise ALL hints get

View File

@ -54,3 +54,8 @@ issues:
# staticcheck: there's no easy way to replace these packages
- "SA1019: \"golang.org/x/crypto/poly1305\" is deprecated"
- "SA1019: \"golang.org/x/crypto/openpgp\" is deprecated"
exclude-rules:
# revive: ignore unused parameters in tests
- path: (_test\.go|testing\.go|backend/.*/tests\.go)
text: "unused-parameter:"

View File

@ -42,7 +42,7 @@ Exit status is 0 if the command was successful.
Exit status is 1 if there was a fatal error (no snapshot created).
Exit status is 3 if some source data could not be read (incomplete snapshot created).
`,
PreRun: func(cmd *cobra.Command, args []string) {
PreRun: func(_ *cobra.Command, _ []string) {
if backupOptions.Host == "" {
hostname, err := os.Hostname()
if err != nil {

View File

@ -28,7 +28,7 @@ EXIT STATUS
Exit status is 0 if the command was successful, and non-zero if there was any error.
`,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
RunE: func(_ *cobra.Command, args []string) error {
return runCache(cacheOptions, globalOptions, args)
},
}

View File

@ -38,7 +38,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
RunE: func(cmd *cobra.Command, args []string) error {
return runCheck(cmd.Context(), checkOptions, globalOptions, args)
},
PreRunE: func(cmd *cobra.Command, args []string) error {
PreRunE: func(_ *cobra.Command, _ []string) error {
return checkFlags(checkOptions)
},
}
@ -345,11 +345,11 @@ func runCheck(ctx context.Context, opts CheckOptions, gopts GlobalOptions, args
if len(salvagePacks) > 0 {
Warnf("\nThe repository contains pack files with damaged blobs. These blobs must be removed to repair the repository. This can be done using the following commands:\n\n")
var strIds []string
var strIDs []string
for _, id := range salvagePacks {
strIds = append(strIds, id.String())
strIDs = append(strIDs, id.String())
}
Warnf("RESTIC_FEATURES=repair-packs-v1 restic repair packs %v\nrestic repair snapshots --forget\n\n", strings.Join(strIds, " "))
Warnf("RESTIC_FEATURES=repair-packs-v1 restic repair packs %v\nrestic repair snapshots --forget\n\n", strings.Join(strIDs, " "))
Warnf("Corrupted blobs are either caused by hardware problems or bugs in restic. Please open an issue at https://github.com/restic/restic/issues/new/choose for further troubleshooting!\n")
}
}

View File

@ -418,7 +418,7 @@ func runDiff(ctx context.Context, opts DiffOptions, gopts GlobalOptions, args []
}
if gopts.Quiet {
c.printChange = func(change *Change) {}
c.printChange = func(_ *Change) {}
}
stats := &DiffStatsContainer{

View File

@ -21,7 +21,7 @@ EXIT STATUS
Exit status is 0 if the command was successful, and non-zero if there was any error.
`,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
RunE: func(_ *cobra.Command, args []string) error {
return runGenerate(genOpts, args)
},
}

View File

@ -69,7 +69,7 @@ func listKeys(ctx context.Context, s *repository.Repository, gopts GlobalOptions
var m sync.Mutex
var keys []keyInfo
err := restic.ParallelList(ctx, s, restic.KeyFile, s.Connections(), func(ctx context.Context, id restic.ID, size int64) error {
err := restic.ParallelList(ctx, s, restic.KeyFile, s.Connections(), func(ctx context.Context, id restic.ID, _ int64) error {
k, err := repository.LoadKey(ctx, s, id)
if err != nil {
Warnf("LoadKey() failed: %v\n", err)

View File

@ -63,7 +63,7 @@ func runList(ctx context.Context, gopts GlobalOptions, args []string) error {
case "locks":
t = restic.LockFile
case "blobs":
return index.ForAllIndexes(ctx, repo, repo, func(id restic.ID, idx *index.Index, oldFormat bool, err error) error {
return index.ForAllIndexes(ctx, repo, repo, func(_ restic.ID, idx *index.Index, _ bool, err error) error {
if err != nil {
return err
}
@ -76,7 +76,7 @@ func runList(ctx context.Context, gopts GlobalOptions, args []string) error {
return errors.Fatal("invalid type")
}
return repo.List(ctx, t, func(id restic.ID, size int64) error {
return repo.List(ctx, t, func(id restic.ID, _ int64) error {
Printf("%s\n", id)
return nil
})

View File

@ -21,7 +21,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
`,
Hidden: true,
DisableAutoGenTag: true,
Run: func(cmd *cobra.Command, args []string) {
Run: func(_ *cobra.Command, _ []string) {
fmt.Printf("All Extended Options:\n")
var maxLen int
for _, opt := range options.List() {

View File

@ -37,7 +37,7 @@ EXIT STATUS
Exit status is 0 if the command was successful, and non-zero if there was any error.
`,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
RunE: func(cmd *cobra.Command, _ []string) error {
return runPrune(cmd.Context(), pruneOptions, globalOptions)
},
}
@ -101,7 +101,7 @@ func verifyPruneOptions(opts *PruneOptions) error {
// parse MaxUnused either as unlimited, a percentage, or an absolute number of bytes
switch {
case maxUnused == "unlimited":
opts.maxUnusedBytes = func(used uint64) uint64 {
opts.maxUnusedBytes = func(_ uint64) uint64 {
return math.MaxUint64
}
@ -130,7 +130,7 @@ func verifyPruneOptions(opts *PruneOptions) error {
return errors.Fatalf("invalid number of bytes %q for --max-unused: %v", opts.MaxUnused, err)
}
opts.maxUnusedBytes = func(used uint64) uint64 {
opts.maxUnusedBytes = func(_ uint64) uint64 {
return uint64(size)
}
}
@ -798,7 +798,7 @@ func rebuildIndexFiles(ctx context.Context, gopts GlobalOptions, repo restic.Rep
DeleteProgress: func() *progress.Counter {
return newProgressMax(!gopts.Quiet, 0, "old indexes deleted")
},
DeleteReport: func(id restic.ID, err error) {
DeleteReport: func(id restic.ID, _ error) {
if gopts.verbosity > 2 {
Verbosef("removed index %v\n", id.String())
}

View File

@ -25,7 +25,7 @@ EXIT STATUS
Exit status is 0 if the command was successful, and non-zero if there was any error.
`,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
RunE: func(cmd *cobra.Command, _ []string) error {
return runRecover(cmd.Context(), globalOptions)
},
}
@ -91,7 +91,7 @@ func runRecover(ctx context.Context, gopts GlobalOptions) error {
bar.Done()
Verbosef("load snapshots\n")
err = restic.ForAllSnapshots(ctx, snapshotLister, repo, nil, func(id restic.ID, sn *restic.Snapshot, err error) error {
err = restic.ForAllSnapshots(ctx, snapshotLister, repo, nil, func(_ restic.ID, sn *restic.Snapshot, _ error) error {
trees[*sn.Tree] = true
return nil
})

View File

@ -24,7 +24,7 @@ EXIT STATUS
Exit status is 0 if the command was successful, and non-zero if there was any error.
`,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
RunE: func(cmd *cobra.Command, _ []string) error {
return runRebuildIndex(cmd.Context(), repairIndexOptions, globalOptions)
},
}
@ -78,7 +78,7 @@ func rebuildIndex(ctx context.Context, opts RepairIndexOptions, gopts GlobalOpti
if opts.ReadAllPacks {
// get list of old index files but start with empty index
err := repo.List(ctx, restic.IndexFile, func(id restic.ID, size int64) error {
err := repo.List(ctx, restic.IndexFile, func(id restic.ID, _ int64) error {
obsoleteIndexes = append(obsoleteIndexes, id)
return nil
})
@ -88,7 +88,7 @@ func rebuildIndex(ctx context.Context, opts RepairIndexOptions, gopts GlobalOpti
} else {
Verbosef("loading indexes...\n")
mi := index.NewMasterIndex()
err := index.ForAllIndexes(ctx, repo, repo, func(id restic.ID, idx *index.Index, oldFormat bool, err error) error {
err := index.ForAllIndexes(ctx, repo, repo, func(id restic.ID, idx *index.Index, _ bool, err error) error {
if err != nil {
Warnf("removing invalid index %v: %v\n", id, err)
obsoleteIndexes = append(obsoleteIndexes, id)

View File

@ -125,7 +125,7 @@ func runRepairSnapshots(ctx context.Context, gopts GlobalOptions, opts RepairOpt
node.Size = newSize
return node
},
RewriteFailedTree: func(nodeID restic.ID, path string, _ error) (restic.ID, error) {
RewriteFailedTree: func(_ restic.ID, path string, _ error) (restic.ID, error) {
if path == "/" {
Verbosef(" dir %q: not readable\n", path)
// remove snapshots with invalid root node

View File

@ -181,7 +181,7 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
excludePatterns := filter.ParsePatterns(opts.Exclude)
insensitiveExcludePatterns := filter.ParsePatterns(opts.InsensitiveExclude)
selectExcludeFilter := func(item string, dstpath string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool) {
selectExcludeFilter := func(item string, _ string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool) {
matched, err := filter.List(excludePatterns, item)
if err != nil {
msg.E("error for exclude pattern: %v", err)
@ -204,7 +204,7 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
includePatterns := filter.ParsePatterns(opts.Include)
insensitiveIncludePatterns := filter.ParsePatterns(opts.InsensitiveInclude)
selectIncludeFilter := func(item string, dstpath string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool) {
selectIncludeFilter := func(item string, _ string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool) {
matched, childMayMatch, err := filter.ListWithChild(includePatterns, item)
if err != nil {
msg.E("error for include pattern: %v", err)

View File

@ -147,7 +147,7 @@ func rewriteSnapshot(ctx context.Context, repo *repository.Repository, sn *resti
return rewriter.RewriteTree(ctx, repo, "/", *sn.Tree)
}
} else {
filter = func(ctx context.Context, sn *restic.Snapshot) (restic.ID, error) {
filter = func(_ context.Context, sn *restic.Snapshot) (restic.ID, error) {
return *sn.Tree, nil
}
}

View File

@ -367,7 +367,7 @@ func statsDebug(ctx context.Context, repo restic.Repository) error {
func statsDebugFileType(ctx context.Context, repo restic.Lister, tpe restic.FileType) (*sizeHistogram, error) {
hist := newSizeHistogram(2 * repository.MaxPackSize)
err := repo.List(ctx, tpe, func(id restic.ID, size int64) error {
err := repo.List(ctx, tpe, func(_ restic.ID, size int64) error {
hist.Add(uint64(size))
return nil
})

View File

@ -19,7 +19,7 @@ EXIT STATUS
Exit status is 0 if the command was successful, and non-zero if there was any error.
`,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
RunE: func(cmd *cobra.Command, _ []string) error {
return runUnlock(cmd.Context(), unlockOptions, globalOptions)
},
}

View File

@ -21,7 +21,7 @@ EXIT STATUS
Exit status is 0 if the command was successful, and non-zero if there was any error.
`,
DisableAutoGenTag: true,
Run: func(cmd *cobra.Command, args []string) {
Run: func(_ *cobra.Command, _ []string) {
if globalOptions.JSON {
type jsonVersion struct {
Version string `json:"version"`

View File

@ -37,7 +37,7 @@ The full documentation can be found at https://restic.readthedocs.io/ .
SilenceUsage: true,
DisableAutoGenTag: true,
PersistentPreRunE: func(c *cobra.Command, args []string) error {
PersistentPreRunE: func(c *cobra.Command, _ []string) error {
// set verbosity, default is one
globalOptions.verbosity = 1
if globalOptions.Quiet && globalOptions.Verbose > 0 {

View File

@ -147,8 +147,8 @@ func (o Options) ApplyDefaults() Options {
func New(repo restic.Repository, fs fs.FS, opts Options) *Archiver {
arch := &Archiver{
Repo: repo,
SelectByName: func(item string) bool { return true },
Select: func(item string, fi os.FileInfo) bool { return true },
SelectByName: func(_ string) bool { return true },
Select: func(_ string, _ os.FileInfo) bool { return true },
FS: fs,
Options: opts.ApplyDefaults(),
@ -762,7 +762,7 @@ func (arch *Archiver) Snapshot(ctx context.Context, targets []string, opts Snaps
arch.runWorkers(wgCtx, wg)
debug.Log("starting snapshot")
fn, nodeCount, err := arch.SaveTree(wgCtx, "/", atree, arch.loadParentTree(wgCtx, opts.ParentSnapshot), func(n *restic.Node, is ItemStats) {
fn, nodeCount, err := arch.SaveTree(wgCtx, "/", atree, arch.loadParentTree(wgCtx, opts.ParentSnapshot), func(_ *restic.Node, is ItemStats) {
arch.CompleteItem("/", nil, nil, is, time.Since(start))
})
if err != nil {

View File

@ -25,10 +25,10 @@ type Scanner struct {
func NewScanner(fs fs.FS) *Scanner {
return &Scanner{
FS: fs,
SelectByName: func(item string) bool { return true },
Select: func(item string, fi os.FileInfo) bool { return true },
Error: func(item string, err error) error { return err },
Result: func(item string, s ScanStats) {},
SelectByName: func(_ string) bool { return true },
Select: func(_ string, _ os.FileInfo) bool { return true },
Error: func(_ string, err error) error { return err },
Result: func(_ string, _ ScanStats) {},
}
}

View File

@ -28,7 +28,7 @@ func NewFactory() location.Factory {
return location.NewHTTPBackendFactory[struct{}, *MemoryBackend](
"mem",
func(s string) (*struct{}, error) {
func(_ string) (*struct{}, error) {
return &struct{}{}, nil
},
location.NoPassword,

View File

@ -183,7 +183,7 @@ func newBackend(ctx context.Context, cfg Config, lim limiter.Limiter) (*Backend,
dialCount := 0
tr := &http2.Transport{
AllowHTTP: true, // this is not really HTTP, just stdin/stdout
DialTLS: func(network, address string, cfg *tls.Config) (net.Conn, error) {
DialTLS: func(network, address string, _ *tls.Config) (net.Conn, error) {
debug.Log("new connection requested, %v %v", network, address)
if dialCount > 0 {
// the connection to the child process is already closed

View File

@ -134,7 +134,7 @@ func (c *Checker) LoadIndex(ctx context.Context, p *progress.Counter) (hints []e
if p != nil {
var numIndexFiles uint64
err := indexList.List(ctx, restic.IndexFile, func(id restic.ID, size int64) error {
err := indexList.List(ctx, restic.IndexFile, func(_ restic.ID, _ int64) error {
numIndexFiles++
return nil
})

View File

@ -41,7 +41,7 @@ type trackFile struct {
func newTrackFile(stack []byte, filename string, file File) *trackFile {
f := &trackFile{file}
runtime.SetFinalizer(f, func(f *trackFile) {
runtime.SetFinalizer(f, func(_ *trackFile) {
fmt.Fprintf(os.Stderr, "file %s not closed\n\nStacktrack:\n%s\n", filename, stack)
panic("file " + filename + " not closed")
})

View File

@ -295,7 +295,7 @@ func (d *SnapshotsDirStructure) updateSnapshots(ctx context.Context) error {
}
var snapshots restic.Snapshots
err := d.root.cfg.Filter.FindAll(ctx, d.root.repo, d.root.repo, nil, func(id string, sn *restic.Snapshot, err error) error {
err := d.root.cfg.Filter.FindAll(ctx, d.root.repo, d.root.repo, nil, func(_ string, sn *restic.Snapshot, _ error) error {
if sn != nil {
snapshots = append(snapshots, sn)
}

View File

@ -19,7 +19,7 @@ func ForAllIndexes(ctx context.Context, lister restic.Lister, repo restic.Lister
workerCount := repo.Connections() + uint(runtime.GOMAXPROCS(0))
var m sync.Mutex
return restic.ParallelList(ctx, lister, restic.IndexFile, workerCount, func(ctx context.Context, id restic.ID, size int64) error {
return restic.ParallelList(ctx, lister, restic.IndexFile, workerCount, func(ctx context.Context, id restic.ID, _ int64) error {
var err error
var idx *Index
oldFormat := false

View File

@ -136,7 +136,7 @@ func SearchKey(ctx context.Context, s *Repository, password string, maxKeys int,
defer cancel()
// try at most maxKeys keys in repo
err = s.List(listCtx, restic.KeyFile, func(id restic.ID, size int64) error {
err = s.List(listCtx, restic.KeyFile, func(id restic.ID, _ int64) error {
checked++
if maxKeys > 0 && checked > maxKeys {
return ErrMaxKeysReached

View File

@ -68,7 +68,7 @@ func RepairPacks(ctx context.Context, repo restic.Repository, ids restic.IDSet,
DeleteProgress: func() *progress.Counter {
return printer.NewCounter("old indexes deleted")
},
DeleteReport: func(id restic.ID, err error) {
DeleteReport: func(id restic.ID, _ error) {
printer.VV("removed index %v", id.String())
},
})

View File

@ -651,7 +651,7 @@ func (r *Repository) LoadIndex(ctx context.Context, p *progress.Counter) error {
if p != nil {
var numIndexFiles uint64
err := indexList.List(ctx, restic.IndexFile, func(id restic.ID, size int64) error {
err := indexList.List(ctx, restic.IndexFile, func(_ restic.ID, _ int64) error {
numIndexFiles++
return nil
})
@ -662,7 +662,7 @@ func (r *Repository) LoadIndex(ctx context.Context, p *progress.Counter) error {
defer p.Done()
}
err = index.ForAllIndexes(ctx, indexList, r, func(id restic.ID, idx *index.Index, oldFormat bool, err error) error {
err = index.ForAllIndexes(ctx, indexList, r, func(_ restic.ID, idx *index.Index, _ bool, err error) error {
if err != nil {
return err
}

View File

@ -30,7 +30,7 @@ func Find(ctx context.Context, be Lister, t FileType, prefix string) (ID, error)
ctx, cancel := context.WithCancel(ctx)
defer cancel()
err := be.List(ctx, t, func(id ID, size int64) error {
err := be.List(ctx, t, func(id ID, _ int64) error {
name := id.String()
if len(name) >= len(prefix) && prefix == name[:len(prefix)] {
if match.IsNull() {

View File

@ -341,7 +341,7 @@ func (l *Lock) checkExistence(ctx context.Context) (bool, error) {
exists := false
err := l.repo.List(ctx, LockFile, func(id ID, size int64) error {
err := l.repo.List(ctx, LockFile, func(id ID, _ int64) error {
if id.Equal(*l.lockID) {
exists = true
}
@ -415,7 +415,7 @@ func RemoveStaleLocks(ctx context.Context, repo Repository) (uint, error) {
// RemoveAllLocks removes all locks forcefully.
func RemoveAllLocks(ctx context.Context, repo Repository) (uint, error) {
var processed uint32
err := ParallelList(ctx, repo, LockFile, repo.Connections(), func(ctx context.Context, id ID, size int64) error {
err := ParallelList(ctx, repo, LockFile, repo.Connections(), func(ctx context.Context, id ID, _ int64) error {
err := repo.Backend().Remove(ctx, backend.Handle{Type: LockFile, Name: id.String()})
if err == nil {
atomic.AddUint32(&processed, 1)

View File

@ -83,7 +83,7 @@ func ForAllSnapshots(ctx context.Context, be Lister, loader LoaderUnpacked, excl
var m sync.Mutex
// For most snapshots decoding is nearly for free, thus just assume were only limited by IO
return ParallelList(ctx, be, SnapshotFile, loader.Connections(), func(ctx context.Context, id ID, size int64) error {
return ParallelList(ctx, be, SnapshotFile, loader.Connections(), func(ctx context.Context, id ID, _ int64) error {
if excludeIDs.Has(id) {
return nil
}

View File

@ -27,7 +27,7 @@ type Restorer struct {
SelectFilter func(item string, dstpath string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool)
}
var restorerAbortOnAllErrors = func(location string, err error) error { return err }
var restorerAbortOnAllErrors = func(_ string, err error) error { return err }
// NewRestorer creates a restorer preloaded with the content from the snapshot id.
func NewRestorer(repo restic.Repository, sn *restic.Snapshot, sparse bool,
@ -239,7 +239,7 @@ func (res *Restorer) RestoreTo(ctx context.Context, dst string) error {
// first tree pass: create directories and collect all files to restore
_, err = res.traverseTree(ctx, dst, string(filepath.Separator), *res.sn.Tree, treeVisitor{
enterDir: func(node *restic.Node, target, location string) error {
enterDir: func(_ *restic.Node, target, location string) error {
debug.Log("first pass, enterDir: mkdir %q, leaveDir should restore metadata", location)
if res.progress != nil {
res.progress.AddFile(0)
@ -366,7 +366,7 @@ func (res *Restorer) VerifyFiles(ctx context.Context, dst string) (int, error) {
defer close(work)
_, err := res.traverseTree(ctx, dst, string(filepath.Separator), *res.sn.Tree, treeVisitor{
visitNode: func(node *restic.Node, target, location string) error {
visitNode: func(node *restic.Node, target, _ string) error {
if node.Type != "file" {
return nil
}

View File

@ -63,7 +63,7 @@ func NewProgress(printer ProgressPrinter, interval time.Duration) *Progress {
printer: printer,
estimator: *newRateEstimator(time.Now()),
}
p.Updater = *progress.NewUpdater(interval, func(runtime time.Duration, final bool) {
p.Updater = *progress.NewUpdater(interval, func(_ time.Duration, final bool) {
if final {
p.printer.Reset()
} else {

View File

@ -39,13 +39,13 @@ func NewTreeRewriter(opts RewriteOpts) *TreeRewriter {
}
// setup default implementations
if rw.opts.RewriteNode == nil {
rw.opts.RewriteNode = func(node *restic.Node, path string) *restic.Node {
rw.opts.RewriteNode = func(node *restic.Node, _ string) *restic.Node {
return node
}
}
if rw.opts.RewriteFailedTree == nil {
// fail with error by default
rw.opts.RewriteFailedTree = func(nodeID restic.ID, path string, err error) (restic.ID, error) {
rw.opts.RewriteFailedTree = func(_ restic.ID, _ string, err error) (restic.ID, error) {
return restic.ID{}, err
}
}