1package git
2
3import (
4 "math/rand"
5 "os"
6 "path/filepath"
7 "strconv"
8 "strings"
9 "time"
10)
11
12// Attribute represents a Git attribute.
13type Attribute struct {
14 Name string
15 Value string
16}
17
18// CheckAttributes checks the attributes of the given ref and path.
19func (r *Repository) CheckAttributes(ref *Reference, path string) ([]Attribute, error) {
20 rnd := rand.NewSource(time.Now().UnixNano())
21 fn := "soft-serve-index-" + strconv.Itoa(rand.New(rnd).Int()) //nolint: gosec
22 tmpindex := filepath.Join(os.TempDir(), fn)
23
24 defer os.Remove(tmpindex)
25
26 readTree := NewCommand("read-tree", "--reset", "-i", ref.Name().String()).
27 AddEnvs("GIT_INDEX_FILE=" + tmpindex)
28 if _, err := readTree.RunInDir(r.Path); err != nil {
29 return nil, err
30 }
31
32 checkAttr := NewCommand("check-attr", "--cached", "-a", "--", path).
33 AddEnvs("GIT_INDEX_FILE=" + tmpindex)
34 out, err := checkAttr.RunInDir(r.Path)
35 if err != nil {
36 return nil, err
37 }
38
39 return parseAttributes(path, out), nil
40}
41
42func parseAttributes(path string, buf []byte) []Attribute {
43 attrs := make([]Attribute, 0)
44 for _, line := range strings.Split(string(buf), "\n") {
45 if line == "" {
46 continue
47 }
48
49 line = strings.TrimPrefix(line, path+": ")
50 parts := strings.SplitN(line, ": ", 2)
51 if len(parts) != 2 {
52 continue
53 }
54
55 attrs = append(attrs, Attribute{
56 Name: parts[0],
57 Value: parts[1],
58 })
59 }
60
61 return attrs
62}