From 60f2d2cfdbce1cc03078738fc78443adb80acb42 Mon Sep 17 00:00:00 2001 From: Aditya Choudhari Date: Wed, 22 Apr 2026 16:52:00 -0700 Subject: [PATCH 1/2] chore: show line diff count --- .../deploymentplanresult/github_check.go | 54 +++++++++++++------ .../deploymentplanresult/github_check_test.go | 20 +++---- 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check.go b/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check.go index bc822ce24..4933e3dc4 100644 --- a/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check.go +++ b/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check.go @@ -150,6 +150,35 @@ type aggregate struct { Unsupported int Changed int Unchanged int + Additions int + Deletions int +} + +func countDiffLines(current, proposed string) (int, int) { + diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ + A: difflib.SplitLines(current), + B: difflib.SplitLines(proposed), + FromFile: "current", + ToFile: "proposed", + Context: 0, + }) + if err != nil { + return 0, 0 + } + var adds, dels int + for line := range strings.SplitSeq(diff, "\n") { + if strings.HasPrefix(line, "+++") || strings.HasPrefix(line, "---") { + continue + } + if strings.HasPrefix(line, "+") { + adds++ + continue + } + if strings.HasPrefix(line, "-") { + dels++ + } + } + return adds, dels } func aggregateResults(results []agentResult) aggregate { @@ -166,6 +195,10 @@ func aggregateResults(results []agentResult) aggregate { } if r.HasChanges != nil && *r.HasChanges { a.Changed++ + adds, dels := countDiffLines(r.Current, r.Proposed) + a.Additions += adds + a.Deletions += dels + continue } if r.HasChanges != nil && !*r.HasChanges { a.Unchanged++ @@ -228,25 +261,12 @@ func (a aggregate) checkTitle() string { if a.Total > 0 && a.Unsupported == a.Total { return "All agents unsupported" } + + diffSummary := fmt.Sprintf("+%d -%d", a.Additions, a.Deletions) if a.Errored > 0 { - return fmt.Sprintf( - "%d errored, %d changed, %d unchanged, %d unsupported", - a.Errored, a.Changed, a.Unchanged, a.Unsupported, - ) + return fmt.Sprintf("%s (%d errored)", diffSummary, a.Errored) } - if a.Changed > 0 { - return fmt.Sprintf( - "%d changed, %d unchanged, %d unsupported", - a.Changed, a.Unchanged, a.Unsupported, - ) - } - if a.Unsupported > 0 { - return fmt.Sprintf( - "No changes (%d unsupported)", - a.Unsupported, - ) - } - return "No changes" + return diffSummary } // formatAgentSection renders the markdown block for one agent in the diff --git a/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check_test.go b/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check_test.go index 371982a1c..3ff4354b6 100644 --- a/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check_test.go +++ b/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check_test.go @@ -154,24 +154,24 @@ func TestAggregate_CheckTitle(t *testing.T) { "1 errored, 0 unsupported (2/3 agents complete)", }, { - "final errored summary includes unsupported", - aggregate{Total: 3, Completed: 1, Errored: 1, Unsupported: 1, Changed: 1}, - "1 errored, 1 changed, 0 unchanged, 1 unsupported", + "final errored summary shows diff counts and errored count", + aggregate{Total: 3, Completed: 1, Errored: 1, Unsupported: 1, Changed: 1, Additions: 7, Deletions: 3}, + "+7 -3 (1 errored)", }, { - "final with changes includes unsupported", - aggregate{Total: 3, Completed: 2, Changed: 1, Unchanged: 1, Unsupported: 1}, - "1 changed, 1 unchanged, 1 unsupported", + "final with changes shows diff counts", + aggregate{Total: 3, Completed: 2, Changed: 1, Unchanged: 1, Unsupported: 1, Additions: 12, Deletions: 4}, + "+12 -4", }, { - "final no changes with some unsupported", + "final no changes shows zero diff counts", aggregate{Total: 3, Completed: 2, Unchanged: 2, Unsupported: 1}, - "No changes (1 unsupported)", + "+0 -0", }, { - "final no changes", + "final all clean", aggregate{Total: 2, Completed: 2, Unchanged: 2}, - "No changes", + "+0 -0", }, { "all unsupported", From 79c94f43d5b8855d3d53d5552e072435207ab095 Mon Sep 17 00:00:00 2001 From: Aditya Choudhari Date: Thu, 23 Apr 2026 09:22:35 -0700 Subject: [PATCH 2/2] update --- .../deploymentplanresult/github_check.go | 32 ++++----- .../deploymentplanresult/github_check_test.go | 67 ++++++++++++++++++- 2 files changed, 77 insertions(+), 22 deletions(-) diff --git a/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check.go b/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check.go index 4933e3dc4..3a1049635 100644 --- a/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check.go +++ b/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check.go @@ -155,27 +155,19 @@ type aggregate struct { } func countDiffLines(current, proposed string) (int, int) { - diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ - A: difflib.SplitLines(current), - B: difflib.SplitLines(proposed), - FromFile: "current", - ToFile: "proposed", - Context: 0, - }) - if err != nil { - return 0, 0 - } + a := difflib.SplitLines(current) + b := difflib.SplitLines(proposed) + m := difflib.NewMatcher(a, b) var adds, dels int - for line := range strings.SplitSeq(diff, "\n") { - if strings.HasPrefix(line, "+++") || strings.HasPrefix(line, "---") { - continue - } - if strings.HasPrefix(line, "+") { - adds++ - continue - } - if strings.HasPrefix(line, "-") { - dels++ + for _, op := range m.GetOpCodes() { + switch op.Tag { + case 'r': + dels += op.I2 - op.I1 + adds += op.J2 - op.J1 + case 'd': + dels += op.I2 - op.I1 + case 'i': + adds += op.J2 - op.J1 } } return adds, dels diff --git a/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check_test.go b/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check_test.go index 3ff4354b6..e48de99e4 100644 --- a/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check_test.go +++ b/apps/workspace-engine/svc/controllers/deploymentplanresult/github_check_test.go @@ -71,6 +71,53 @@ func TestAggregateResults_Counts(t *testing.T) { assert.Equal(t, 1, agg.Unsupported) assert.Equal(t, 1, agg.Changed) assert.Equal(t, 1, agg.Unchanged) + assert.Equal(t, 1, agg.Additions) + assert.Equal(t, 1, agg.Deletions) +} + +func TestAggregateResults_AdditionsDeletionsSumAcrossAgents(t *testing.T) { + // Two changed agents contribute their own diff counts; unchanged, + // errored, and unsupported agents must not contribute. + results := []agentResult{ + completedResult("a", true, "a\nb\nc\n", "a\nX\nc\nd\n"), // 2 adds, 1 del + completedResult("b", true, "x\ny\nz\n", "x\nz\n"), // 0 adds, 1 del + completedResult("unchanged", false, "same\n", "same\n"), // ignored + erroredResult("errored", "boom"), // ignored + unsupportedResult("unsupported"), // ignored + } + + agg := aggregateResults(results) + + assert.Equal(t, 2, agg.Changed) + assert.Equal(t, 2, agg.Additions) + assert.Equal(t, 2, agg.Deletions) +} + +func TestCountDiffLines(t *testing.T) { + tests := []struct { + name string + current string + proposed string + wantAdditions int + wantDeletions int + }{ + {"identical", "a\nb\nc\n", "a\nb\nc\n", 0, 0}, + {"pure insert", "a\nb\n", "a\nb\nc\n", 1, 0}, + {"pure delete", "a\nb\nc\n", "a\n", 0, 2}, + {"single-line replace", "foo\n", "bar\n", 1, 1}, + {"multi-line mixed (replace + insert)", "a\nb\nc\n", "a\nX\nc\nd\n", 2, 1}, + {"empty both", "", "", 0, 0}, + {"empty current, content proposed", "", "a\nb\n", 2, 0}, + {"content current, empty proposed", "a\nb\n", "", 0, 2}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + adds, dels := countDiffLines(tc.current, tc.proposed) + assert.Equal(t, tc.wantAdditions, adds, "additions") + assert.Equal(t, tc.wantDeletions, dels, "deletions") + }) + } } func TestAggregateResults_Empty(t *testing.T) { @@ -155,12 +202,28 @@ func TestAggregate_CheckTitle(t *testing.T) { }, { "final errored summary shows diff counts and errored count", - aggregate{Total: 3, Completed: 1, Errored: 1, Unsupported: 1, Changed: 1, Additions: 7, Deletions: 3}, + aggregate{ + Total: 3, + Completed: 1, + Errored: 1, + Unsupported: 1, + Changed: 1, + Additions: 7, + Deletions: 3, + }, "+7 -3 (1 errored)", }, { "final with changes shows diff counts", - aggregate{Total: 3, Completed: 2, Changed: 1, Unchanged: 1, Unsupported: 1, Additions: 12, Deletions: 4}, + aggregate{ + Total: 3, + Completed: 2, + Changed: 1, + Unchanged: 1, + Unsupported: 1, + Additions: 12, + Deletions: 4, + }, "+12 -4", }, {