package api import ( "bufio" "os" "regexp" "strconv" "strings" "github.com/thepeterstone/claudomator/internal/task" ) // 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) *task.Changestats { scanner := bufio.NewScanner(strings.NewReader(output)) for scanner.Scan() { line := scanner.Text() if m := gitDiffStatRe.FindStringSubmatch(line); m != nil { cs := &task.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) *task.Changestats { data, err := os.ReadFile(path) if err != nil { return nil } return parseChangestatFromOutput(string(data)) }