From 1f27d17c0df63713c604978afa5f2efd84ca42c8 Mon Sep 17 00:00:00 2001 From: Mikael Berthe Date: Sat, 14 Jul 2018 18:29:07 +0200 Subject: [PATCH] walker.Walk: Pass parent tree-id to WalkFunc --- cmd/restic/cmd_find.go | 34 ++++++++++++++++++---------------- cmd/restic/cmd_ls.go | 2 +- cmd/restic/cmd_stats.go | 2 +- internal/walker/walker.go | 14 +++++++------- internal/walker/walker_test.go | 6 +++--- 5 files changed, 30 insertions(+), 28 deletions(-) diff --git a/cmd/restic/cmd_find.go b/cmd/restic/cmd_find.go index 3eaa9d849..1f8fc4fb6 100644 --- a/cmd/restic/cmd_find.go +++ b/cmd/restic/cmd_find.go @@ -173,12 +173,13 @@ func (s *statefulOutput) PrintPattern(path string, node *restic.Node) { } } -func (s *statefulOutput) PrintObjectJSON(kind, id, nodepath string, sn *restic.Snapshot) { +func (s *statefulOutput) PrintObjectJSON(kind, id, nodepath, treeID string, sn *restic.Snapshot) { b, err := json.Marshal(struct { // Add these attributes ObjectType string `json:"object_type"` ID string `json:"id"` - Path string `json:"path,omitempty"` + Path string `json:"path"` + ParentTree string `json:"parent_tree,omitempty"` SnapshotID string `json:"snapshot"` Time time.Time `json:"time,omitempty"` }{ @@ -186,6 +187,7 @@ func (s *statefulOutput) PrintObjectJSON(kind, id, nodepath string, sn *restic.S ID: id, Path: nodepath, SnapshotID: sn.ID().String(), + ParentTree: treeID, Time: sn.Time, }) if err != nil { @@ -203,21 +205,22 @@ func (s *statefulOutput) PrintObjectJSON(kind, id, nodepath string, sn *restic.S s.hits++ } -func (s *statefulOutput) PrintObjectNormal(kind, id, nodepath string, sn *restic.Snapshot) { - f := "path" - if kind == "blob" { - f = "in file" - } +func (s *statefulOutput) PrintObjectNormal(kind, id, nodepath, treeID string, sn *restic.Snapshot) { Printf("Found %s %s\n", kind, id) - Printf(" ... %s %s\n", f, nodepath) + if kind == "blob" { + Printf(" ... in file %s\n", nodepath) + Printf(" (tree %s)\n", treeID) + } else { + Printf(" ... path %s\n", nodepath) + } Printf(" ... in snapshot %s (%s)\n", sn.ID().Str(), sn.Time.Format(TimeFormat)) } -func (s *statefulOutput) PrintObject(kind, id, nodepath string, sn *restic.Snapshot) { +func (s *statefulOutput) PrintObject(kind, id, nodepath, treeID string, sn *restic.Snapshot) { if s.JSON { - s.PrintObjectJSON(kind, id, nodepath, sn) + s.PrintObjectJSON(kind, id, nodepath, treeID, sn) } else { - s.PrintObjectNormal(kind, id, nodepath, sn) + s.PrintObjectNormal(kind, id, nodepath, treeID, sn) } } @@ -255,7 +258,7 @@ func (f *Finder) findInSnapshot(ctx context.Context, sn *restic.Snapshot) error } f.out.newsn = sn - return walker.Walk(ctx, f.repo, *sn.Tree, f.ignoreTrees, func(nodepath string, node *restic.Node, err error) (bool, error) { + return walker.Walk(ctx, f.repo, *sn.Tree, f.ignoreTrees, func(nodepath string, node *restic.Node, treeID string, err error) (bool, error) { if err != nil { return false, err } @@ -335,7 +338,7 @@ func (f *Finder) findIDs(ctx context.Context, sn *restic.Snapshot) error { } f.out.newsn = sn - return walker.Walk(ctx, f.repo, *sn.Tree, f.ignoreTrees, func(nodepath string, node *restic.Node, err error) (bool, error) { + return walker.Walk(ctx, f.repo, *sn.Tree, f.ignoreTrees, func(nodepath string, node *restic.Node, treeID string, err error) (bool, error) { if err != nil { return false, err } @@ -353,7 +356,7 @@ func (f *Finder) findIDs(ctx context.Context, sn *restic.Snapshot) error { found = true } if found { - f.out.PrintObject("tree", treeID.String(), nodepath, sn) + f.out.PrintObject("tree", treeID.String(), nodepath, "", sn) f.itemsFound++ // Terminate if we have found all trees (and we are not // looking for blobs) @@ -376,8 +379,7 @@ func (f *Finder) findIDs(ctx context.Context, sn *restic.Snapshot) error { f.blobIDs[idStr] = struct{}{} delete(f.blobIDs, idStr[:shortStr]) } - f.out.PrintObject("blob", idStr, nodepath, sn) - // TODO Printf(" (tree %s)\n", treeID.Str()) + f.out.PrintObject("blob", idStr, nodepath, treeID, sn) break } } diff --git a/cmd/restic/cmd_ls.go b/cmd/restic/cmd_ls.go index d6297be04..7883161ba 100644 --- a/cmd/restic/cmd_ls.go +++ b/cmd/restic/cmd_ls.go @@ -203,7 +203,7 @@ func runLs(opts LsOptions, gopts GlobalOptions, args []string) error { for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, args[:1]) { printSnapshot(sn) - err := walker.Walk(ctx, repo, *sn.Tree, nil, func(nodepath string, node *restic.Node, err error) (bool, error) { + err := walker.Walk(ctx, repo, *sn.Tree, nil, func(nodepath string, node *restic.Node, treeID string, err error) (bool, error) { if err != nil { return false, err } diff --git a/cmd/restic/cmd_stats.go b/cmd/restic/cmd_stats.go index 79ca8e02a..b22bb5a5e 100644 --- a/cmd/restic/cmd_stats.go +++ b/cmd/restic/cmd_stats.go @@ -188,7 +188,7 @@ func statsWalkSnapshot(ctx context.Context, snapshot *restic.Snapshot, repo rest } func statsWalkTree(repo restic.Repository, stats *statsContainer) walker.WalkFunc { - return func(npath string, node *restic.Node, nodeErr error) (bool, error) { + return func(npath string, node *restic.Node, parentTreeID string, nodeErr error) (bool, error) { if nodeErr != nil { return true, nodeErr } diff --git a/internal/walker/walker.go b/internal/walker/walker.go index fd58dfa98..e8c7ae81b 100644 --- a/internal/walker/walker.go +++ b/internal/walker/walker.go @@ -33,14 +33,14 @@ var SkipNode = errors.New("skip this node") // tree have ignore set to true, the current tree will not be visited again. // When err is not nil and different from SkipNode, the value returned for // ignore is ignored. -type WalkFunc func(path string, node *restic.Node, nodeErr error) (ignore bool, err error) +type WalkFunc func(path string, node *restic.Node, parentTreeID string, nodeErr error) (ignore bool, err error) // Walk calls walkFn recursively for each node in root. If walkFn returns an // error, it is passed up the call stack. The trees in ignoreTrees are not // walked. If walkFn ignores trees, these are added to the set. func Walk(ctx context.Context, repo TreeLoader, root restic.ID, ignoreTrees restic.IDSet, walkFn WalkFunc) error { tree, err := repo.LoadTree(ctx, root) - _, err = walkFn("/", nil, err) + _, err = walkFn("/", nil, "", err) if err != nil { if err == SkipNode { @@ -53,14 +53,14 @@ func Walk(ctx context.Context, repo TreeLoader, root restic.ID, ignoreTrees rest ignoreTrees = restic.NewIDSet() } - _, err = walk(ctx, repo, "/", tree, ignoreTrees, walkFn) + _, err = walk(ctx, repo, "/", root.String(), tree, ignoreTrees, walkFn) return err } // walk recursively traverses the tree, ignoring subtrees when the ID of the // subtree is in ignoreTrees. If err is nil and ignore is true, the subtree ID // will be added to ignoreTrees by walk. -func walk(ctx context.Context, repo TreeLoader, prefix string, tree *restic.Tree, ignoreTrees restic.IDSet, walkFn WalkFunc) (ignore bool, err error) { +func walk(ctx context.Context, repo TreeLoader, prefix string, treeID string, tree *restic.Tree, ignoreTrees restic.IDSet, walkFn WalkFunc) (ignore bool, err error) { var allNodesIgnored = true if len(tree.Nodes) == 0 { @@ -79,7 +79,7 @@ func walk(ctx context.Context, repo TreeLoader, prefix string, tree *restic.Tree } if node.Type != "dir" { - ignore, err := walkFn(p, node, nil) + ignore, err := walkFn(p, node, treeID, nil) if err != nil { if err == SkipNode { // skip the remaining entries in this tree @@ -105,7 +105,7 @@ func walk(ctx context.Context, repo TreeLoader, prefix string, tree *restic.Tree } subtree, err := repo.LoadTree(ctx, *node.Subtree) - ignore, err := walkFn(p, node, err) + ignore, err := walkFn(p, node, treeID, err) if err != nil { if err == SkipNode { if ignore { @@ -124,7 +124,7 @@ func walk(ctx context.Context, repo TreeLoader, prefix string, tree *restic.Tree allNodesIgnored = false } - ignore, err = walk(ctx, repo, p, subtree, ignoreTrees, walkFn) + ignore, err = walk(ctx, repo, p, node.Subtree.String(), subtree, ignoreTrees, walkFn) if err != nil { return false, err } diff --git a/internal/walker/walker_test.go b/internal/walker/walker_test.go index 7da3417e5..67c44b8e2 100644 --- a/internal/walker/walker_test.go +++ b/internal/walker/walker_test.go @@ -78,7 +78,7 @@ type checkFunc func(t testing.TB) (walker WalkFunc, final func(testing.TB)) func checkItemOrder(want []string) checkFunc { pos := 0 return func(t testing.TB) (walker WalkFunc, final func(testing.TB)) { - walker = func(path string, node *restic.Node, err error) (bool, error) { + walker = func(path string, node *restic.Node, treeID string, err error) (bool, error) { if err != nil { t.Errorf("error walking %v: %v", path, err) return false, err @@ -112,7 +112,7 @@ func checkSkipFor(skipFor map[string]struct{}, wantPaths []string) checkFunc { var pos int return func(t testing.TB) (walker WalkFunc, final func(testing.TB)) { - walker = func(path string, node *restic.Node, err error) (bool, error) { + walker = func(path string, node *restic.Node, treeID string, err error) (bool, error) { if err != nil { t.Errorf("error walking %v: %v", path, err) return false, err @@ -152,7 +152,7 @@ func checkIgnore(skipFor map[string]struct{}, ignoreFor map[string]bool, wantPat var pos int return func(t testing.TB) (walker WalkFunc, final func(testing.TB)) { - walker = func(path string, node *restic.Node, err error) (bool, error) { + walker = func(path string, node *restic.Node, treeID string, err error) (bool, error) { if err != nil { t.Errorf("error walking %v: %v", path, err) return false, err