package task import ( "bufio" "os" "regexp" "strconv" "strings" ) // gitDiffStatRe matches git diff --stat summary lines, e.g.: // // "3 files changed, 50 insertions(+), 10 deletions(-)" // "1 file changed, 5 insertions(+)" // "1 file changed, 3 deletions(-)" var gitDiffStatRe = regexp.MustCompile(`(\d+) files? changed(?:, (\d+) insertions?\(\+\))?(?:, (\d+) deletions?\(-\))?`) // ParseChangestatFromOutput scans text for git diff --stat summary lines and // returns the first match as a Changestats value. Returns nil if no match found. func ParseChangestatFromOutput(output string) *Changestats { scanner := bufio.NewScanner(strings.NewReader(output)) for scanner.Scan() { line := scanner.Text() if m := gitDiffStatRe.FindStringSubmatch(line); m != nil { cs := &Changestats{} cs.FilesChanged, _ = strconv.Atoi(m[1]) if m[2] != "" { cs.LinesAdded, _ = strconv.Atoi(m[2]) } if m[3] != "" { cs.LinesRemoved, _ = strconv.Atoi(m[3]) } return cs } } return nil } // ParseChangestatFromFile reads a log file and extracts the first git diff stat // summary it finds. Returns nil if the file cannot be read or contains no match. func ParseChangestatFromFile(path string) *Changestats { data, err := os.ReadFile(path) if err != nil { return nil } return ParseChangestatFromOutput(string(data)) }