1package git
2
3import (
4 "fmt"
5 "time"
6
7 "github.com/go-git/go-git/v5/plumbing/object"
8 "tangled.sh/tangled.sh/core/types"
9)
10
11func (g *GitRepo) FileTree(path string) ([]types.NiceTree, error) {
12 c, err := g.r.CommitObject(g.h)
13 if err != nil {
14 return nil, fmt.Errorf("commit object: %w", err)
15 }
16
17 files := []types.NiceTree{}
18 tree, err := c.Tree()
19 if err != nil {
20 return nil, fmt.Errorf("file tree: %w", err)
21 }
22
23 if path == "" {
24 files = g.makeNiceTree(tree, "")
25 } else {
26 o, err := tree.FindEntry(path)
27 if err != nil {
28 return nil, err
29 }
30
31 if !o.Mode.IsFile() {
32 subtree, err := tree.Tree(path)
33 if err != nil {
34 return nil, err
35 }
36
37 files = g.makeNiceTree(subtree, path)
38 }
39 }
40
41 return files, nil
42}
43
44func (g *GitRepo) makeNiceTree(t *object.Tree, parent string) []types.NiceTree {
45 nts := []types.NiceTree{}
46
47 for _, e := range t.Entries {
48 mode, _ := e.Mode.ToOSFileMode()
49 sz, _ := t.Size(e.Name)
50
51 var fpath string
52 if parent != "" {
53 fpath = fmt.Sprintf("%s/%s", parent, e.Name)
54 } else {
55 fpath = e.Name
56 }
57 lastCommit, err := g.LastCommitForPath(fpath)
58 if err != nil {
59 fmt.Println("error getting last commit time:", err)
60 // We don't want to skip the file, so worst case lets just
61 // populate it with "defaults".
62 lastCommit = &types.LastCommitInfo{
63 Hash: g.h,
64 Message: "",
65 When: time.Now(),
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}