mirror of
https://github.com/restic/restic.git
synced 2025-03-13 15:40:52 +00:00
walker.Walk: Pass parent tree-id to WalkFunc
This commit is contained in:
parent
8af918a1e4
commit
1f27d17c0d
@ -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 {
|
b, err := json.Marshal(struct {
|
||||||
// Add these attributes
|
// Add these attributes
|
||||||
ObjectType string `json:"object_type"`
|
ObjectType string `json:"object_type"`
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path"`
|
||||||
|
ParentTree string `json:"parent_tree,omitempty"`
|
||||||
SnapshotID string `json:"snapshot"`
|
SnapshotID string `json:"snapshot"`
|
||||||
Time time.Time `json:"time,omitempty"`
|
Time time.Time `json:"time,omitempty"`
|
||||||
}{
|
}{
|
||||||
@ -186,6 +187,7 @@ func (s *statefulOutput) PrintObjectJSON(kind, id, nodepath string, sn *restic.S
|
|||||||
ID: id,
|
ID: id,
|
||||||
Path: nodepath,
|
Path: nodepath,
|
||||||
SnapshotID: sn.ID().String(),
|
SnapshotID: sn.ID().String(),
|
||||||
|
ParentTree: treeID,
|
||||||
Time: sn.Time,
|
Time: sn.Time,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -203,21 +205,22 @@ func (s *statefulOutput) PrintObjectJSON(kind, id, nodepath string, sn *restic.S
|
|||||||
s.hits++
|
s.hits++
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *statefulOutput) PrintObjectNormal(kind, id, nodepath string, sn *restic.Snapshot) {
|
func (s *statefulOutput) PrintObjectNormal(kind, id, nodepath, treeID string, sn *restic.Snapshot) {
|
||||||
f := "path"
|
|
||||||
if kind == "blob" {
|
|
||||||
f = "in file"
|
|
||||||
}
|
|
||||||
Printf("Found %s %s\n", kind, id)
|
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))
|
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 {
|
if s.JSON {
|
||||||
s.PrintObjectJSON(kind, id, nodepath, sn)
|
s.PrintObjectJSON(kind, id, nodepath, treeID, sn)
|
||||||
} else {
|
} 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
|
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 {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -335,7 +338,7 @@ func (f *Finder) findIDs(ctx context.Context, sn *restic.Snapshot) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
f.out.newsn = sn
|
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 {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -353,7 +356,7 @@ func (f *Finder) findIDs(ctx context.Context, sn *restic.Snapshot) error {
|
|||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
if found {
|
if found {
|
||||||
f.out.PrintObject("tree", treeID.String(), nodepath, sn)
|
f.out.PrintObject("tree", treeID.String(), nodepath, "", sn)
|
||||||
f.itemsFound++
|
f.itemsFound++
|
||||||
// Terminate if we have found all trees (and we are not
|
// Terminate if we have found all trees (and we are not
|
||||||
// looking for blobs)
|
// looking for blobs)
|
||||||
@ -376,8 +379,7 @@ func (f *Finder) findIDs(ctx context.Context, sn *restic.Snapshot) error {
|
|||||||
f.blobIDs[idStr] = struct{}{}
|
f.blobIDs[idStr] = struct{}{}
|
||||||
delete(f.blobIDs, idStr[:shortStr])
|
delete(f.blobIDs, idStr[:shortStr])
|
||||||
}
|
}
|
||||||
f.out.PrintObject("blob", idStr, nodepath, sn)
|
f.out.PrintObject("blob", idStr, nodepath, treeID, sn)
|
||||||
// TODO Printf(" (tree %s)\n", treeID.Str())
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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]) {
|
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, args[:1]) {
|
||||||
printSnapshot(sn)
|
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 {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ func statsWalkSnapshot(ctx context.Context, snapshot *restic.Snapshot, repo rest
|
|||||||
}
|
}
|
||||||
|
|
||||||
func statsWalkTree(repo restic.Repository, stats *statsContainer) walker.WalkFunc {
|
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 {
|
if nodeErr != nil {
|
||||||
return true, nodeErr
|
return true, nodeErr
|
||||||
}
|
}
|
||||||
|
@ -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.
|
// 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
|
// When err is not nil and different from SkipNode, the value returned for
|
||||||
// ignore is ignored.
|
// 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
|
// 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
|
// 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.
|
// 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 {
|
func Walk(ctx context.Context, repo TreeLoader, root restic.ID, ignoreTrees restic.IDSet, walkFn WalkFunc) error {
|
||||||
tree, err := repo.LoadTree(ctx, root)
|
tree, err := repo.LoadTree(ctx, root)
|
||||||
_, err = walkFn("/", nil, err)
|
_, err = walkFn("/", nil, "", err)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == SkipNode {
|
if err == SkipNode {
|
||||||
@ -53,14 +53,14 @@ func Walk(ctx context.Context, repo TreeLoader, root restic.ID, ignoreTrees rest
|
|||||||
ignoreTrees = restic.NewIDSet()
|
ignoreTrees = restic.NewIDSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = walk(ctx, repo, "/", tree, ignoreTrees, walkFn)
|
_, err = walk(ctx, repo, "/", root.String(), tree, ignoreTrees, walkFn)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// walk recursively traverses the tree, ignoring subtrees when the ID of the
|
// 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
|
// subtree is in ignoreTrees. If err is nil and ignore is true, the subtree ID
|
||||||
// will be added to ignoreTrees by walk.
|
// 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
|
var allNodesIgnored = true
|
||||||
|
|
||||||
if len(tree.Nodes) == 0 {
|
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" {
|
if node.Type != "dir" {
|
||||||
ignore, err := walkFn(p, node, nil)
|
ignore, err := walkFn(p, node, treeID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == SkipNode {
|
if err == SkipNode {
|
||||||
// skip the remaining entries in this tree
|
// 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)
|
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 != nil {
|
||||||
if err == SkipNode {
|
if err == SkipNode {
|
||||||
if ignore {
|
if ignore {
|
||||||
@ -124,7 +124,7 @@ func walk(ctx context.Context, repo TreeLoader, prefix string, tree *restic.Tree
|
|||||||
allNodesIgnored = false
|
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 {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ type checkFunc func(t testing.TB) (walker WalkFunc, final func(testing.TB))
|
|||||||
func checkItemOrder(want []string) checkFunc {
|
func checkItemOrder(want []string) checkFunc {
|
||||||
pos := 0
|
pos := 0
|
||||||
return func(t testing.TB) (walker WalkFunc, final func(testing.TB)) {
|
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 {
|
if err != nil {
|
||||||
t.Errorf("error walking %v: %v", path, err)
|
t.Errorf("error walking %v: %v", path, err)
|
||||||
return false, err
|
return false, err
|
||||||
@ -112,7 +112,7 @@ func checkSkipFor(skipFor map[string]struct{}, wantPaths []string) checkFunc {
|
|||||||
var pos int
|
var pos int
|
||||||
|
|
||||||
return func(t testing.TB) (walker WalkFunc, final func(testing.TB)) {
|
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 {
|
if err != nil {
|
||||||
t.Errorf("error walking %v: %v", path, err)
|
t.Errorf("error walking %v: %v", path, err)
|
||||||
return false, err
|
return false, err
|
||||||
@ -152,7 +152,7 @@ func checkIgnore(skipFor map[string]struct{}, ignoreFor map[string]bool, wantPat
|
|||||||
var pos int
|
var pos int
|
||||||
|
|
||||||
return func(t testing.TB) (walker WalkFunc, final func(testing.TB)) {
|
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 {
|
if err != nil {
|
||||||
t.Errorf("error walking %v: %v", path, err)
|
t.Errorf("error walking %v: %v", path, err)
|
||||||
return false, err
|
return false, err
|
||||||
|
Loading…
x
Reference in New Issue
Block a user