Monorepo for Tangled tangled.org

knotserver: add generic git repo walker interface

Signed-off-by: oppiliappan <me@oppi.li>

authored by oppi.li and committed by Tangled 65ad4406 037bdc4c

Changed files
+79
knotserver
git
+79
knotserver/git/tree.go
··· 2 2 3 3 import ( 4 4 "context" 5 + "errors" 5 6 "fmt" 6 7 "path" 7 8 "time" ··· 78 79 79 80 return nts 80 81 } 82 + 83 + var ( 84 + TerminateWalk error = errors.New("terminate walk") 85 + ) 86 + 87 + type callback = func(node object.TreeEntry, parent *object.Tree, fullPath string) error 88 + 89 + func (g *GitRepo) Walk( 90 + ctx context.Context, 91 + root string, 92 + cb callback, 93 + ) error { 94 + c, err := g.r.CommitObject(g.h) 95 + if err != nil { 96 + return fmt.Errorf("commit object: %w", err) 97 + } 98 + 99 + tree, err := c.Tree() 100 + if err != nil { 101 + return fmt.Errorf("file tree: %w", err) 102 + } 103 + 104 + subtree := tree 105 + if root != "" { 106 + subtree, err = tree.Tree(root) 107 + if err != nil { 108 + return fmt.Errorf("sub tree: %w", err) 109 + } 110 + } 111 + 112 + return g.walkHelper(ctx, root, subtree, cb) 113 + } 114 + 115 + func (g *GitRepo) walkHelper( 116 + ctx context.Context, 117 + root string, 118 + currentTree *object.Tree, 119 + cb callback, 120 + ) error { 121 + for _, e := range currentTree.Entries { 122 + // check if context hits deadline before processing 123 + select { 124 + case <-ctx.Done(): 125 + return ctx.Err() 126 + default: 127 + } 128 + 129 + mode, err := e.Mode.ToOSFileMode() 130 + if err != nil { 131 + // TODO: log this 132 + continue 133 + } 134 + 135 + if e.Mode.IsFile() { 136 + err = cb(e, currentTree, root) 137 + if errors.Is(err, TerminateWalk) { 138 + return err 139 + } 140 + } 141 + 142 + // e is a directory 143 + if mode.IsDir() { 144 + subtree, err := currentTree.Tree(e.Name) 145 + if err != nil { 146 + return fmt.Errorf("sub tree %s: %w", e.Name, err) 147 + } 148 + 149 + fullPath := path.Join(root, e.Name) 150 + 151 + err = g.walkHelper(ctx, fullPath, subtree, cb) 152 + if err != nil { 153 + return err 154 + } 155 + } 156 + } 157 + 158 + return nil 159 + }