utils.go

 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.Name())
32		if te.IsTree() {
33			continue
34		}
35		if g.Match(fp) { //nolint:nestif
36			if te.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}