1package git
2
3import (
4 "context"
5 "fmt"
6 "path"
7 "time"
8
9 "github.com/go-git/go-git/v5/plumbing/object"
10 "tangled.sh/tangled.sh/core/types"
11)
12
13func (g *GitRepo) FileTree(ctx context.Context, path string) ([]types.NiceTree, error) {
14 c, err := g.r.CommitObject(g.h)
15 if err != nil {
16 return nil, fmt.Errorf("commit object: %w", err)
17 }
18
19 files := []types.NiceTree{}
20 tree, err := c.Tree()
21 if err != nil {
22 return nil, fmt.Errorf("file tree: %w", err)
23 }
24
25 if path == "" {
26 files = g.makeNiceTree(ctx, tree, "")
27 } else {
28 o, err := tree.FindEntry(path)
29 if err != nil {
30 return nil, err
31 }
32
33 if !o.Mode.IsFile() {
34 subtree, err := tree.Tree(path)
35 if err != nil {
36 return nil, err
37 }
38
39 files = g.makeNiceTree(ctx, subtree, path)
40 }
41 }
42
43 return files, nil
44}
45
46func (g *GitRepo) makeNiceTree(ctx context.Context, subtree *object.Tree, parent string) []types.NiceTree {
47 nts := []types.NiceTree{}
48
49 times, err := g.calculateCommitTimeIn(ctx, subtree, parent, 2*time.Second)
50 if err != nil {
51 return nts
52 }
53
54 for _, e := range subtree.Entries {
55 mode, _ := e.Mode.ToOSFileMode()
56 sz, _ := subtree.Size(e.Name)
57
58 fpath := path.Join(parent, e.Name)
59
60 var lastCommit *types.LastCommitInfo
61 if t, ok := times[fpath]; ok {
62 lastCommit = &types.LastCommitInfo{
63 Hash: t.hash,
64 Message: t.message,
65 When: t.when,
66 }
67 }
68
69 nts = append(nts, types.NiceTree{
70 Name: e.Name,
71 Mode: mode.String(),
72 IsFile: e.Mode.IsFile(),
73 Size: sz,
74 LastCommit: lastCommit,
75 })
76
77 }
78
79 return nts
80}