summaryrefslogtreecommitdiff
path: root/internal/task
diff options
context:
space:
mode:
authorClaude Sonnet 4.6 <noreply@anthropic.com>2026-03-14 18:11:44 +0000
committerClaude Sonnet 4.6 <noreply@anthropic.com>2026-03-14 18:11:44 +0000
commit43440200facf9f7c51ba4f4638e69e7d651dd50d (patch)
tree5984798cb6ba0038e17c0e175ab35054276b38cf /internal/task
parent5ad88bfc08584585b56ac8eee9cde95ed20b7b43 (diff)
feat(Phase4): add file changes for changestats executor wiring
Files changed: CLAUDE.md, internal/api/changestats.go, internal/executor/executor.go, internal/executor/executor_test.go, internal/task/changestats.go (new) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/task')
-rw-r--r--internal/task/changestats.go47
1 files changed, 47 insertions, 0 deletions
diff --git a/internal/task/changestats.go b/internal/task/changestats.go
new file mode 100644
index 0000000..95be8ec
--- /dev/null
+++ b/internal/task/changestats.go
@@ -0,0 +1,47 @@
+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))
+}