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