1package git
2
3import (
4 "os"
5 "path/filepath"
6
7 "github.com/gobwas/glob"
8)
9
10// LatestFile returns the contents of the first file at the specified path pattern in the repository and its file path.
11func LatestFile(repo *Repository, pattern string) (string, string, error) {
12 g := glob.MustCompile(pattern)
13 dir := filepath.Dir(pattern)
14 head, err := repo.HEAD()
15 if err != nil {
16 return "", "", err
17 }
18 t, err := repo.TreePath(head, dir)
19 if err != nil {
20 return "", "", err
21 }
22 ents, err := t.Entries()
23 if err != nil {
24 return "", "", err
25 }
26 for _, e := range ents {
27 te := e
28 fp := filepath.Join(dir, te.Name())
29 if te.IsTree() {
30 continue
31 }
32 if g.Match(fp) {
33 if te.IsSymlink() {
34 bts, err := te.Contents()
35 if err != nil {
36 return "", "", err
37 }
38 fp = string(bts)
39 te, err = t.TreeEntry(fp)
40 if err != nil {
41 return "", "", err
42 }
43 }
44 bts, err := te.Contents()
45 if err != nil {
46 return "", "", err
47 }
48 return string(bts), fp, nil
49 }
50 }
51 return "", "", ErrFileNotFound
52}
53
54// Returns true if path is a directory containing an `objects` directory and a
55// `HEAD` file.
56func isGitDir(path string) bool {
57 stat, err := os.Stat(filepath.Join(path, "objects"))
58 if err != nil {
59 return false
60 }
61 if !stat.IsDir() {
62 return false
63 }
64
65 stat, err = os.Stat(filepath.Join(path, "HEAD"))
66 if err != nil {
67 return false
68 }
69 if stat.IsDir() {
70 return false
71 }
72
73 return true
74}