diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bf4e63bb7..5a41723bb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ permissions: contents: read env: - latest_go: "1.22.x" + latest_go: "1.23.x" GO111MODULE: on jobs: @@ -23,27 +23,32 @@ jobs: # list of jobs to run: include: - job_name: Windows - go: 1.22.x + go: 1.23.x os: windows-latest - job_name: macOS - go: 1.22.x + go: 1.23.x os: macOS-latest test_fuse: false - job_name: Linux - go: 1.22.x + go: 1.23.x os: ubuntu-latest test_cloud_backends: true test_fuse: true check_changelog: true - job_name: Linux (race) - go: 1.22.x + go: 1.23.x os: ubuntu-latest test_fuse: true test_opts: "-race" + - job_name: Linux + go: 1.22.x + os: ubuntu-latest + test_fuse: true + - job_name: Linux go: 1.21.x os: ubuntu-latest @@ -254,7 +259,7 @@ jobs: uses: golangci/golangci-lint-action@v6 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.57.1 + version: v1.61.0 args: --verbose --timeout 5m # only run golangci-lint for pull requests, otherwise ALL hints get diff --git a/cmd/restic/cmd_backup_integration_test.go b/cmd/restic/cmd_backup_integration_test.go index 71367b236..4278f07ca 100644 --- a/cmd/restic/cmd_backup_integration_test.go +++ b/cmd/restic/cmd_backup_integration_test.go @@ -365,12 +365,7 @@ func TestBackupExclude(t *testing.T) { for _, filename := range backupExcludeFilenames { fp := filepath.Join(datadir, filename) rtest.OK(t, os.MkdirAll(filepath.Dir(fp), 0755)) - - f, err := os.Create(fp) - rtest.OK(t, err) - - fmt.Fprint(f, filename) - rtest.OK(t, f.Close()) + rtest.OK(t, os.WriteFile(fp, []byte(filename), 0o666)) } snapshots := make(map[string]struct{}) diff --git a/cmd/restic/cmd_backup_test.go b/cmd/restic/cmd_backup_test.go index 5cbc42436..44e08ff96 100644 --- a/cmd/restic/cmd_backup_test.go +++ b/cmd/restic/cmd_backup_test.go @@ -39,21 +39,24 @@ func TestCollectTargets(t *testing.T) { f1, err := os.Create(filepath.Join(dir, "fromfile")) rtest.OK(t, err) // Empty lines should be ignored. A line starting with '#' is a comment. - fmt.Fprintf(f1, "\n%s*\n # here's a comment\n", f1.Name()) + _, err = fmt.Fprintf(f1, "\n%s*\n # here's a comment\n", f1.Name()) + rtest.OK(t, err) rtest.OK(t, f1.Close()) f2, err := os.Create(filepath.Join(dir, "fromfile-verbatim")) rtest.OK(t, err) for _, filename := range []string{fooSpace, barStar} { // Empty lines should be ignored. CR+LF is allowed. - fmt.Fprintf(f2, "%s\r\n\n", filepath.Join(dir, filename)) + _, err = fmt.Fprintf(f2, "%s\r\n\n", filepath.Join(dir, filename)) + rtest.OK(t, err) } rtest.OK(t, f2.Close()) f3, err := os.Create(filepath.Join(dir, "fromfile-raw")) rtest.OK(t, err) for _, filename := range []string{"baz", "quux"} { - fmt.Fprintf(f3, "%s\x00", filepath.Join(dir, filename)) + _, err = fmt.Fprintf(f3, "%s\x00", filepath.Join(dir, filename)) + rtest.OK(t, err) } rtest.OK(t, err) rtest.OK(t, f3.Close()) diff --git a/cmd/restic/cmd_ls.go b/cmd/restic/cmd_ls.go index 2213d8e7a..06ae6cc20 100644 --- a/cmd/restic/cmd_ls.go +++ b/cmd/restic/cmd_ls.go @@ -75,17 +75,17 @@ func init() { } type lsPrinter interface { - Snapshot(sn *restic.Snapshot) - Node(path string, node *restic.Node, isPrefixDirectory bool) - LeaveDir(path string) - Close() + Snapshot(sn *restic.Snapshot) error + Node(path string, node *restic.Node, isPrefixDirectory bool) error + LeaveDir(path string) error + Close() error } type jsonLsPrinter struct { enc *json.Encoder } -func (p *jsonLsPrinter) Snapshot(sn *restic.Snapshot) { +func (p *jsonLsPrinter) Snapshot(sn *restic.Snapshot) error { type lsSnapshot struct { *restic.Snapshot ID *restic.ID `json:"id"` @@ -94,27 +94,21 @@ func (p *jsonLsPrinter) Snapshot(sn *restic.Snapshot) { StructType string `json:"struct_type"` // "snapshot", deprecated } - err := p.enc.Encode(lsSnapshot{ + return p.enc.Encode(lsSnapshot{ Snapshot: sn, ID: sn.ID(), ShortID: sn.ID().Str(), MessageType: "snapshot", StructType: "snapshot", }) - if err != nil { - Warnf("JSON encode failed: %v\n", err) - } } // Print node in our custom JSON format, followed by a newline. -func (p *jsonLsPrinter) Node(path string, node *restic.Node, isPrefixDirectory bool) { +func (p *jsonLsPrinter) Node(path string, node *restic.Node, isPrefixDirectory bool) error { if isPrefixDirectory { - return - } - err := lsNodeJSON(p.enc, path, node) - if err != nil { - Warnf("JSON encode failed: %v\n", err) + return nil } + return lsNodeJSON(p.enc, path, node) } func lsNodeJSON(enc *json.Encoder, path string, node *restic.Node) error { @@ -160,8 +154,8 @@ func lsNodeJSON(enc *json.Encoder, path string, node *restic.Node) error { return enc.Encode(n) } -func (p *jsonLsPrinter) LeaveDir(_ string) {} -func (p *jsonLsPrinter) Close() {} +func (p *jsonLsPrinter) LeaveDir(_ string) error { return nil } +func (p *jsonLsPrinter) Close() error { return nil } type ncduLsPrinter struct { out io.Writer @@ -171,16 +165,17 @@ type ncduLsPrinter struct { // lsSnapshotNcdu prints a restic snapshot in Ncdu save format. // It opens the JSON list. Nodes are added with lsNodeNcdu and the list is closed by lsCloseNcdu. // Format documentation: https://dev.yorhel.nl/ncdu/jsonfmt -func (p *ncduLsPrinter) Snapshot(sn *restic.Snapshot) { +func (p *ncduLsPrinter) Snapshot(sn *restic.Snapshot) error { const NcduMajorVer = 1 const NcduMinorVer = 2 snapshotBytes, err := json.Marshal(sn) if err != nil { - Warnf("JSON encode failed: %v\n", err) + return err } p.depth++ - fmt.Fprintf(p.out, "[%d, %d, %s, [{\"name\":\"/\"}", NcduMajorVer, NcduMinorVer, string(snapshotBytes)) + _, err = fmt.Fprintf(p.out, "[%d, %d, %s, [{\"name\":\"/\"}", NcduMajorVer, NcduMinorVer, string(snapshotBytes)) + return err } func lsNcduNode(_ string, node *restic.Node) ([]byte, error) { @@ -232,27 +227,30 @@ func lsNcduNode(_ string, node *restic.Node) ([]byte, error) { return json.Marshal(outNode) } -func (p *ncduLsPrinter) Node(path string, node *restic.Node, _ bool) { +func (p *ncduLsPrinter) Node(path string, node *restic.Node, _ bool) error { out, err := lsNcduNode(path, node) if err != nil { - Warnf("JSON encode failed: %v\n", err) + return err } if node.Type == restic.NodeTypeDir { - fmt.Fprintf(p.out, ",\n%s[\n%s%s", strings.Repeat(" ", p.depth), strings.Repeat(" ", p.depth+1), string(out)) + _, err = fmt.Fprintf(p.out, ",\n%s[\n%s%s", strings.Repeat(" ", p.depth), strings.Repeat(" ", p.depth+1), string(out)) p.depth++ } else { - fmt.Fprintf(p.out, ",\n%s%s", strings.Repeat(" ", p.depth), string(out)) + _, err = fmt.Fprintf(p.out, ",\n%s%s", strings.Repeat(" ", p.depth), string(out)) } + return err } -func (p *ncduLsPrinter) LeaveDir(_ string) { +func (p *ncduLsPrinter) LeaveDir(_ string) error { p.depth-- - fmt.Fprintf(p.out, "\n%s]", strings.Repeat(" ", p.depth)) + _, err := fmt.Fprintf(p.out, "\n%s]", strings.Repeat(" ", p.depth)) + return err } -func (p *ncduLsPrinter) Close() { - fmt.Fprint(p.out, "\n]\n]\n") +func (p *ncduLsPrinter) Close() error { + _, err := fmt.Fprint(p.out, "\n]\n]\n") + return err } type textLsPrinter struct { @@ -261,17 +259,23 @@ type textLsPrinter struct { HumanReadable bool } -func (p *textLsPrinter) Snapshot(sn *restic.Snapshot) { +func (p *textLsPrinter) Snapshot(sn *restic.Snapshot) error { Verbosef("%v filtered by %v:\n", sn, p.dirs) + return nil } -func (p *textLsPrinter) Node(path string, node *restic.Node, isPrefixDirectory bool) { +func (p *textLsPrinter) Node(path string, node *restic.Node, isPrefixDirectory bool) error { if !isPrefixDirectory { Printf("%s\n", formatNode(path, node, p.ListLong, p.HumanReadable)) } + return nil } -func (p *textLsPrinter) LeaveDir(_ string) {} -func (p *textLsPrinter) Close() {} +func (p *textLsPrinter) LeaveDir(_ string) error { + return nil +} +func (p *textLsPrinter) Close() error { + return nil +} func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []string) error { if len(args) == 0 { @@ -374,7 +378,9 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri return err } - printer.Snapshot(sn) + if err := printer.Snapshot(sn); err != nil { + return err + } processNode := func(_ restic.ID, nodepath string, node *restic.Node, err error) error { if err != nil { @@ -387,7 +393,9 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri printedDir := false if withinDir(nodepath) { // if we're within a target path, print the node - printer.Node(nodepath, node, false) + if err := printer.Node(nodepath, node, false); err != nil { + return err + } printedDir = true // if recursive listing is requested, signal the walker that it @@ -402,7 +410,7 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri if approachingMatchingTree(nodepath) { // print node leading up to the target paths if !printedDir { - printer.Node(nodepath, node, true) + return printer.Node(nodepath, node, true) } return nil } @@ -412,7 +420,9 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri if node.Type == restic.NodeTypeDir { // immediately generate leaveDir if the directory is skipped if printedDir { - printer.LeaveDir(nodepath) + if err := printer.LeaveDir(nodepath); err != nil { + return err + } } return walker.ErrSkipNode } @@ -421,11 +431,12 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri err = walker.Walk(ctx, repo, *sn.Tree, walker.WalkVisitor{ ProcessNode: processNode, - LeaveDir: func(path string) { + LeaveDir: func(path string) error { // the root path `/` has no corresponding node and is thus also skipped by processNode if path != "/" { - printer.LeaveDir(path) + return printer.LeaveDir(path) } + return nil }, }) @@ -433,6 +444,5 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri return err } - printer.Close() - return nil + return printer.Close() } diff --git a/cmd/restic/cmd_ls_test.go b/cmd/restic/cmd_ls_test.go index b8b074242..3d4e1dbc7 100644 --- a/cmd/restic/cmd_ls_test.go +++ b/cmd/restic/cmd_ls_test.go @@ -134,29 +134,29 @@ func TestLsNcdu(t *testing.T) { } modTime := time.Date(2020, 1, 2, 3, 4, 5, 0, time.UTC) - printer.Snapshot(&restic.Snapshot{ + rtest.OK(t, printer.Snapshot(&restic.Snapshot{ Hostname: "host", Paths: []string{"/example"}, - }) - printer.Node("/directory", &restic.Node{ + })) + rtest.OK(t, printer.Node("/directory", &restic.Node{ Type: restic.NodeTypeDir, Name: "directory", ModTime: modTime, - }, false) - printer.Node("/directory/data", &restic.Node{ + }, false)) + rtest.OK(t, printer.Node("/directory/data", &restic.Node{ Type: restic.NodeTypeFile, Name: "data", Size: 42, ModTime: modTime, - }, false) - printer.LeaveDir("/directory") - printer.Node("/file", &restic.Node{ + }, false)) + rtest.OK(t, printer.LeaveDir("/directory")) + rtest.OK(t, printer.Node("/file", &restic.Node{ Type: restic.NodeTypeFile, Name: "file", Size: 12345, ModTime: modTime, - }, false) - printer.Close() + }, false)) + rtest.OK(t, printer.Close()) rtest.Equals(t, `[1, 2, {"time":"0001-01-01T00:00:00Z","tree":null,"paths":["/example"],"hostname":"host"}, [{"name":"/"}, [ diff --git a/cmd/restic/cmd_rewrite.go b/cmd/restic/cmd_rewrite.go index a9f664110..b62d1ed95 100644 --- a/cmd/restic/cmd_rewrite.go +++ b/cmd/restic/cmd_rewrite.go @@ -2,7 +2,6 @@ package main import ( "context" - "fmt" "time" "github.com/spf13/cobra" @@ -141,7 +140,7 @@ func rewriteSnapshot(ctx context.Context, repo *repository.Repository, sn *resti if selectByName(path) { return node } - Verbosef(fmt.Sprintf("excluding %s\n", path)) + Verbosef("excluding %s\n", path) return nil } diff --git a/cmd/restic/cmd_snapshots.go b/cmd/restic/cmd_snapshots.go index 466f536e0..f935cec86 100644 --- a/cmd/restic/cmd_snapshots.go +++ b/cmd/restic/cmd_snapshots.go @@ -296,7 +296,9 @@ func PrintSnapshotGroupHeader(stdout io.Writer, groupKeyJSON string) error { } // Info - fmt.Fprintf(stdout, "snapshots") + if _, err := fmt.Fprintf(stdout, "snapshots"); err != nil { + return err + } var infoStrings []string if key.Hostname != "" { infoStrings = append(infoStrings, "host ["+key.Hostname+"]") @@ -308,11 +310,13 @@ func PrintSnapshotGroupHeader(stdout io.Writer, groupKeyJSON string) error { infoStrings = append(infoStrings, "paths ["+strings.Join(key.Paths, ", ")+"]") } if infoStrings != nil { - fmt.Fprintf(stdout, " for (%s)", strings.Join(infoStrings, ", ")) + if _, err := fmt.Fprintf(stdout, " for (%s)", strings.Join(infoStrings, ", ")); err != nil { + return err + } } - fmt.Fprintf(stdout, ":\n") + _, err = fmt.Fprintf(stdout, ":\n") - return nil + return err } // Snapshot helps to print Snapshots as JSON with their ID included. diff --git a/cmd/restic/global.go b/cmd/restic/global.go index fc52882d7..b824b7449 100644 --- a/cmd/restic/global.go +++ b/cmd/restic/global.go @@ -308,7 +308,7 @@ func readPasswordTerminal(ctx context.Context, in *os.File, out *os.File, prompt fd := int(out.Fd()) state, err := term.GetState(fd) if err != nil { - fmt.Fprintf(os.Stderr, "unable to get terminal state: %v\n", err) + _, _ = fmt.Fprintf(os.Stderr, "unable to get terminal state: %v\n", err) return "", err } @@ -317,16 +317,22 @@ func readPasswordTerminal(ctx context.Context, in *os.File, out *os.File, prompt go func() { defer close(done) - fmt.Fprint(out, prompt) + _, err = fmt.Fprint(out, prompt) + if err != nil { + return + } buf, err = term.ReadPassword(int(in.Fd())) - fmt.Fprintln(out) + if err != nil { + return + } + _, err = fmt.Fprintln(out) }() select { case <-ctx.Done(): err := term.Restore(fd, state) if err != nil { - fmt.Fprintf(os.Stderr, "unable to restore terminal state: %v\n", err) + _, _ = fmt.Fprintf(os.Stderr, "unable to restore terminal state: %v\n", err) } return "", ctx.Err() case <-done: diff --git a/cmd/restic/integration_helpers_unix_test.go b/cmd/restic/integration_helpers_unix_test.go index df0c4fe63..30852a753 100644 --- a/cmd/restic/integration_helpers_unix_test.go +++ b/cmd/restic/integration_helpers_unix_test.go @@ -13,17 +13,17 @@ import ( func (e *dirEntry) equals(out io.Writer, other *dirEntry) bool { if e.path != other.path { - fmt.Fprintf(out, "%v: path does not match (%v != %v)\n", e.path, e.path, other.path) + _, _ = fmt.Fprintf(out, "%v: path does not match (%v != %v)\n", e.path, e.path, other.path) return false } if e.fi.Mode() != other.fi.Mode() { - fmt.Fprintf(out, "%v: mode does not match (%v != %v)\n", e.path, e.fi.Mode(), other.fi.Mode()) + _, _ = fmt.Fprintf(out, "%v: mode does not match (%v != %v)\n", e.path, e.fi.Mode(), other.fi.Mode()) return false } if !sameModTime(e.fi, other.fi) { - fmt.Fprintf(out, "%v: ModTime does not match (%v != %v)\n", e.path, e.fi.ModTime(), other.fi.ModTime()) + _, _ = fmt.Fprintf(out, "%v: ModTime does not match (%v != %v)\n", e.path, e.fi.ModTime(), other.fi.ModTime()) return false } @@ -31,17 +31,17 @@ func (e *dirEntry) equals(out io.Writer, other *dirEntry) bool { stat2, _ := other.fi.Sys().(*syscall.Stat_t) if stat.Uid != stat2.Uid { - fmt.Fprintf(out, "%v: UID does not match (%v != %v)\n", e.path, stat.Uid, stat2.Uid) + _, _ = fmt.Fprintf(out, "%v: UID does not match (%v != %v)\n", e.path, stat.Uid, stat2.Uid) return false } if stat.Gid != stat2.Gid { - fmt.Fprintf(out, "%v: GID does not match (%v != %v)\n", e.path, stat.Gid, stat2.Gid) + _, _ = fmt.Fprintf(out, "%v: GID does not match (%v != %v)\n", e.path, stat.Gid, stat2.Gid) return false } if stat.Nlink != stat2.Nlink { - fmt.Fprintf(out, "%v: Number of links do not match (%v != %v)\n", e.path, stat.Nlink, stat2.Nlink) + _, _ = fmt.Fprintf(out, "%v: Number of links do not match (%v != %v)\n", e.path, stat.Nlink, stat2.Nlink) return false } diff --git a/cmd/restic/main.go b/cmd/restic/main.go index 4cb135c48..096c5695c 100644 --- a/cmd/restic/main.go +++ b/cmd/restic/main.go @@ -140,7 +140,7 @@ func printExitError(code int, message string) { return } } else { - fmt.Fprintf(globalOptions.stderr, "%v\n", message) + _, _ = fmt.Fprintf(globalOptions.stderr, "%v\n", message) } } @@ -152,10 +152,10 @@ func main() { log.SetOutput(logBuffer) err := feature.Flag.Apply(os.Getenv("RESTIC_FEATURES"), func(s string) { - fmt.Fprintln(os.Stderr, s) + _, _ = fmt.Fprintln(os.Stderr, s) }) if err != nil { - fmt.Fprintln(os.Stderr, err) + _, _ = fmt.Fprintln(os.Stderr, err) Exit(1) } diff --git a/internal/backend/rest/rest_test.go b/internal/backend/rest/rest_test.go index 891f60a87..50560f66d 100644 --- a/internal/backend/rest/rest_test.go +++ b/internal/backend/rest/rest_test.go @@ -106,7 +106,7 @@ func runRESTServer(ctx context.Context, t testing.TB, dir, reqListenAddr string) matched = true } } - fmt.Fprintln(os.Stdout, line) // print all output to console + _, _ = fmt.Fprintln(os.Stdout, line) // print all output to console } }() diff --git a/internal/debug/debug.go b/internal/debug/debug.go index 7bc3291d1..a09d6e74a 100644 --- a/internal/debug/debug.go +++ b/internal/debug/debug.go @@ -120,7 +120,7 @@ func goroutineNum() int { runtime.Stack(b, false) var num int - fmt.Sscanf(string(b), "goroutine %d ", &num) + _, _ = fmt.Sscanf(string(b), "goroutine %d ", &num) return num } diff --git a/internal/debug/round_tripper.go b/internal/debug/round_tripper.go index 9dced95c6..4afab7298 100644 --- a/internal/debug/round_tripper.go +++ b/internal/debug/round_tripper.go @@ -42,7 +42,7 @@ func (rd *eofDetectReader) Close() error { msg += fmt.Sprintf(", body: %q", buf) } - fmt.Fprintln(os.Stderr, msg) + _, _ = fmt.Fprintln(os.Stderr, msg) Log("%s: %+v", msg, errors.New("Close()")) } return rd.rd.Close() diff --git a/internal/ui/termstatus/status.go b/internal/ui/termstatus/status.go index 39654cc8c..e65330958 100644 --- a/internal/ui/termstatus/status.go +++ b/internal/ui/termstatus/status.go @@ -212,7 +212,7 @@ func (t *Terminal) runWithoutStatus(ctx context.Context) { } if _, err := io.WriteString(dst, msg.line); err != nil { - fmt.Fprintf(os.Stderr, "write failed: %v\n", err) + _, _ = fmt.Fprintf(os.Stderr, "write failed: %v\n", err) } if flush == nil { @@ -220,16 +220,18 @@ func (t *Terminal) runWithoutStatus(ctx context.Context) { } if err := flush(); err != nil { - fmt.Fprintf(os.Stderr, "flush failed: %v\n", err) + _, _ = fmt.Fprintf(os.Stderr, "flush failed: %v\n", err) } case stat := <-t.status: for _, line := range stat.lines { // Ensure that each message ends with exactly one newline. - fmt.Fprintln(t.wr, strings.TrimRight(line, "\n")) + if _, err := fmt.Fprintln(t.wr, strings.TrimRight(line, "\n")); err != nil { + _, _ = fmt.Fprintf(os.Stderr, "write failed: %v\n", err) + } } if err := t.wr.Flush(); err != nil { - fmt.Fprintf(os.Stderr, "flush failed: %v\n", err) + _, _ = fmt.Fprintf(os.Stderr, "flush failed: %v\n", err) } } } diff --git a/internal/walker/walker.go b/internal/walker/walker.go index 8acfed2f2..252bc3530 100644 --- a/internal/walker/walker.go +++ b/internal/walker/walker.go @@ -28,7 +28,7 @@ type WalkVisitor struct { // was returned. This function is mandatory ProcessNode WalkFunc // Optional callback - LeaveDir func(path string) + LeaveDir func(path string) error } // Walk calls walkFn recursively for each node in root. If walkFn returns an @@ -100,7 +100,7 @@ func walk(ctx context.Context, repo restic.BlobLoader, prefix string, parentTree } if visitor.LeaveDir != nil { - visitor.LeaveDir(prefix) + return visitor.LeaveDir(prefix) } return nil diff --git a/internal/walker/walker_test.go b/internal/walker/walker_test.go index fa377bb8f..3614a2397 100644 --- a/internal/walker/walker_test.go +++ b/internal/walker/walker_test.go @@ -93,12 +93,12 @@ func (t TreeMap) Connections() uint { // checkFunc returns a function suitable for walking the tree to check // something, and a function which will check the final result. -type checkFunc func(t testing.TB) (walker WalkFunc, leaveDir func(path string), final func(testing.TB)) +type checkFunc func(t testing.TB) (walker WalkFunc, leaveDir func(path string) error, final func(testing.TB)) // checkItemOrder ensures that the order of the 'path' arguments is the one passed in as 'want'. func checkItemOrder(want []string) checkFunc { pos := 0 - return func(t testing.TB) (walker WalkFunc, leaveDir func(path string), final func(testing.TB)) { + return func(t testing.TB) (walker WalkFunc, leaveDir func(path string) error, final func(testing.TB)) { walker = func(treeID restic.ID, path string, node *restic.Node, err error) error { if err != nil { t.Errorf("error walking %v: %v", path, err) @@ -117,8 +117,8 @@ func checkItemOrder(want []string) checkFunc { return nil } - leaveDir = func(path string) { - _ = walker(restic.ID{}, "leave: "+path, nil, nil) + leaveDir = func(path string) error { + return walker(restic.ID{}, "leave: "+path, nil, nil) } final = func(t testing.TB) { @@ -134,7 +134,7 @@ func checkItemOrder(want []string) checkFunc { // checkParentTreeOrder ensures that the order of the 'parentID' arguments is the one passed in as 'want'. func checkParentTreeOrder(want []string) checkFunc { pos := 0 - return func(t testing.TB) (walker WalkFunc, leaveDir func(path string), final func(testing.TB)) { + return func(t testing.TB) (walker WalkFunc, leaveDir func(path string) error, final func(testing.TB)) { walker = func(treeID restic.ID, path string, node *restic.Node, err error) error { if err != nil { t.Errorf("error walking %v: %v", path, err) @@ -168,7 +168,7 @@ func checkParentTreeOrder(want []string) checkFunc { func checkSkipFor(skipFor map[string]struct{}, wantPaths []string) checkFunc { var pos int - return func(t testing.TB) (walker WalkFunc, leaveDir func(path string), final func(testing.TB)) { + return func(t testing.TB) (walker WalkFunc, leaveDir func(path string) error, final func(testing.TB)) { walker = func(treeID restic.ID, path string, node *restic.Node, err error) error { if err != nil { t.Errorf("error walking %v: %v", path, err) @@ -192,8 +192,8 @@ func checkSkipFor(skipFor map[string]struct{}, wantPaths []string) checkFunc { return nil } - leaveDir = func(path string) { - _ = walker(restic.ID{}, "leave: "+path, nil, nil) + leaveDir = func(path string) error { + return walker(restic.ID{}, "leave: "+path, nil, nil) } final = func(t testing.TB) {