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, ref *Reference, pattern string) (string, string, error) {
12 g := glob.MustCompile(pattern)
13 dir := filepath.Dir(pattern)
14 if ref == nil {
15 head, err := repo.HEAD()
16 if err != nil {
17 return "", "", err
18 }
19 ref = head
20 }
21 t, err := repo.TreePath(ref, dir)
22 if err != nil {
23 return "", "", err
24 }
25 ents, err := t.Entries()
26 if err != nil {
27 return "", "", err
28 }
29 for _, e := range ents {
30 te := e
31 fp := filepath.Join(dir, te.TreeEntry.Name())
32 if te.TreeEntry.IsTree() {
33 continue
34 }
35 if g.Match(fp) {
36 if te.TreeEntry.IsSymlink() {
37 bts, err := te.Contents()
38 if err != nil {
39 return "", "", err
40 }
41 fp = string(bts)
42 te, err = t.TreeEntry(fp)
43 if err != nil {
44 return "", "", err
45 }
46 }
47 bts, err := te.Contents()
48 if err != nil {
49 return "", "", err
50 }
51 return string(bts), fp, nil
52 }
53 }
54 return "", "", ErrFileNotFound
55}
56
57// Returns true if path is a directory containing an `objects` directory and a
58// `HEAD` file.
59func isGitDir(path string) bool {
60 stat, err := os.Stat(filepath.Join(path, "objects"))
61 if err != nil {
62 return false
63 }
64 if !stat.IsDir() {
65 return false
66 }
67
68 stat, err = os.Stat(filepath.Join(path, "HEAD"))
69 if err != nil {
70 return false
71 }
72 if stat.IsDir() {
73 return false
74 }
75
76 return true
77}