From 81013463553c623904169a80ec97a8eb77391862 Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Thu, 10 Jul 2025 18:23:56 +0100 Subject: [PATCH] knotserver: add generic git repo walker interface Change-Id: olomxxtlststuyvtmptqtvrvqpvmoqqn Signed-off-by: oppiliappan --- knotserver/git/tree.go | 79 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/knotserver/git/tree.go b/knotserver/git/tree.go index 4ea8379..d246920 100644 --- a/knotserver/git/tree.go +++ b/knotserver/git/tree.go @@ -2,6 +2,7 @@ package git import ( "context" + "errors" "fmt" "path" "time" @@ -78,3 +79,81 @@ func (g *GitRepo) makeNiceTree(ctx context.Context, subtree *object.Tree, parent return nts } + +var ( + TerminateWalk error = errors.New("terminate walk") +) + +type callback = func(node object.TreeEntry, parent *object.Tree, fullPath string) error + +func (g *GitRepo) Walk( + ctx context.Context, + root string, + cb callback, +) error { + c, err := g.r.CommitObject(g.h) + if err != nil { + return fmt.Errorf("commit object: %w", err) + } + + tree, err := c.Tree() + if err != nil { + return fmt.Errorf("file tree: %w", err) + } + + subtree := tree + if root != "" { + subtree, err = tree.Tree(root) + if err != nil { + return fmt.Errorf("sub tree: %w", err) + } + } + + return g.walkHelper(ctx, root, subtree, cb) +} + +func (g *GitRepo) walkHelper( + ctx context.Context, + root string, + currentTree *object.Tree, + cb callback, +) error { + for _, e := range currentTree.Entries { + // check if context hits deadline before processing + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + mode, err := e.Mode.ToOSFileMode() + if err != nil { + // TODO: log this + continue + } + + if e.Mode.IsFile() { + err = cb(e, currentTree, root) + if errors.Is(err, TerminateWalk) { + return err + } + } + + // e is a directory + if mode.IsDir() { + subtree, err := currentTree.Tree(e.Name) + if err != nil { + return fmt.Errorf("sub tree %s: %w", e.Name, err) + } + + fullPath := path.Join(root, e.Name) + + err = g.walkHelper(ctx, fullPath, subtree, cb) + if err != nil { + return err + } + } + } + + return nil +} -- 2.43.0