package git import ( "math/rand" "os" "path/filepath" "strconv" "strings" "time" ) // Attribute represents a Git attribute. type Attribute struct { Name string Value string } // CheckAttributes checks the attributes of the given ref and path. func (r *Repository) CheckAttributes(ref *Reference, path string) ([]Attribute, error) { rnd := rand.NewSource(time.Now().UnixNano()) fn := "soft-serve-index-" + strconv.Itoa(rand.New(rnd).Int()) //nolint: gosec tmpindex := filepath.Join(os.TempDir(), fn) defer os.Remove(tmpindex) //nolint: errcheck readTree := NewCommand("read-tree", "--reset", "-i", ref.Name().String()). AddEnvs("GIT_INDEX_FILE=" + tmpindex) if _, err := readTree.RunInDir(r.Path); err != nil { return nil, err } checkAttr := NewCommand("check-attr", "--cached", "-a", "--", path). AddEnvs("GIT_INDEX_FILE=" + tmpindex) out, err := checkAttr.RunInDir(r.Path) if err != nil { return nil, err } return parseAttributes(path, out), nil } func parseAttributes(path string, buf []byte) []Attribute { attrs := make([]Attribute, 0) for _, line := range strings.Split(string(buf), "\n") { if line == "" { continue } line = strings.TrimPrefix(line, path+": ") parts := strings.SplitN(line, ": ", 2) if len(parts) != 2 { continue } attrs = append(attrs, Attribute{ Name: parts[0], Value: parts[1], }) } return attrs }