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}