Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions internal/report/report_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ var (
bulletLineRe = regexp.MustCompile(`^\s*-\s+(.+?)\s*$`)
statusSuffixRe = regexp.MustCompile(`\(([^)]+)\)\s*$`)
ticketPrefixRe = regexp.MustCompile(`^\[([^\]]+)\]\s+`)
bareTicketLeadRe = regexp.MustCompile(`^\s*(?:#\s*)?(?:[A-Za-z][A-Za-z0-9_]*-)?([0-9A-Za-z]+)(?:\s*[:,-]\s*|\s+)`)
authorPrefixRe = regexp.MustCompile(`^\*\*(.+?)\*\*\s*-\s*`)
nameAliasParenRe = regexp.MustCompile(`\([^)]*\)|([^)]*)`)
)
Expand Down Expand Up @@ -680,16 +681,41 @@ func stripLeadingTicketPrefixIfSame(description, tickets string) string {
if description == "" || tickets == "" {
return description
}
ticketSet := make(map[string]bool)
for _, t := range strings.Split(tickets, ",") {
t = strings.TrimSpace(t)
if t == "" {
continue
}
ticketSet[strings.ToLower(t)] = true
}

for {
trimmed := false
matches := ticketPrefixRe.FindStringSubmatch(description)
if len(matches) != 2 {
break
if len(matches) == 2 {
leading := canonicalTicketIDs(matches[1])
if leading == tickets {
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent case handling: this comparison is case-sensitive, but the bare ticket comparison on line 712 is case-insensitive (both the ticketSet population on line 690 and the candidate lookup use ToLower). If ticket IDs can contain letters, a description like "[abc123] Implement feature" with TicketIDs "ABC123" would not be stripped here, but "abc123 Implement feature" would be stripped by the bare ticket logic. Consider using case-insensitive comparison here as well for consistency.

Suggested change
if leading == tickets {
if strings.EqualFold(leading, tickets) {

Copilot uses AI. Check for mistakes.
description = strings.TrimSpace(description[len(matches[0]):])
trimmed = true
}
}
leading := canonicalTicketIDs(matches[1])
if leading != tickets {
break
if trimmed {
continue
}

// Handle plain leading ticket mentions like:
// "1234567 Implement ...", "#1234567 Implement ...", "JIRA-1234567 Implement ..."
bare := bareTicketLeadRe.FindStringSubmatchIndex(description)
if len(bare) == 4 {
candidate := strings.ToLower(strings.TrimSpace(description[bare[2]:bare[3]]))
if ticketSet[candidate] {
description = strings.TrimSpace(description[bare[1]:])
continue
}
}
description = strings.TrimSpace(description[len(matches[0]):])

break
}
return description
}
Expand Down
12 changes: 12 additions & 0 deletions internal/report/report_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,18 @@ func TestFormatItemDedupesLeadingTicketPrefix(t *testing.T) {
if gotBoss != wantBoss {
t.Fatalf("unexpected deduped boss item:\nwant: %s\ngot: %s", wantBoss, gotBoss)
}

plainPrefix := TemplateItem{
Author: "Marik Hsiao",
Description: "1259566 added consul gossip encryption support",
TicketIDs: "1259566",
Status: "done",
}
gotPlain := formatTeamItem(plainPrefix)
wantPlain := "**Marik Hsiao** - [1259566] Added consul gossip encryption support (done)"
if gotPlain != wantPlain {
t.Fatalf("unexpected deduped plain-prefix item:\nwant: %s\ngot: %s", wantPlain, gotPlain)
}
}

func TestMergeCategoryHeadingAuthors(t *testing.T) {
Expand Down