Files
superwork/tui/internal/webhook/coordinator.go
T
2026-06-23 05:02:15 +08:00

58 lines
1.6 KiB
Go

package webhook
import (
"regexp"
"strconv"
)
var (
closesRe = regexp.MustCompile(`(?i)\b(?:closes|fixes|resolves|close|fix|resolve)\s+#(\d+)`)
branchRe = regexp.MustCompile(`(?:^|[-/])(\d+)(?:[-/]|$)`)
nonceRe = regexp.MustCompile(`(?i)<!--\s*spx:nonce=([0-9a-f-]+)\s*-->`)
reviewRe = regexp.MustCompile(`(?i)<!--\s*spx:review=1\s*-->`)
)
// ResolveIssueNumber resolves the issue number in priority order:
// 1. PR body keyword (Closes/Fixes/Resolves #N)
// 2. Branch name containing a number
// 3. Legacy path number
func ResolveIssueNumber(prBody, branch string, legacyNumber int) (int, bool) {
if m := closesRe.FindStringSubmatch(prBody); m != nil {
n, _ := strconv.Atoi(m[1])
return n, true
}
if branch != "" {
if m := branchRe.FindStringSubmatch(branch); m != nil {
n, _ := strconv.Atoi(m[1])
return n, true
}
}
if legacyNumber > 0 {
return legacyNumber, true
}
return 0, false
}
// ShouldAutoReview returns the effective auto-review flag.
// The per-issue stateJSON "autoReview" bool takes precedence over globalAutoReview.
func ShouldAutoReview(stateJSON map[string]any, globalAutoReview bool) bool {
if v, ok := stateJSON["autoReview"].(bool); ok {
return v
}
return globalAutoReview
}
// ExtractNonce extracts the nonce value from a <!-- spx:nonce=... --> marker.
func ExtractNonce(issueBody string) (string, bool) {
m := nonceRe.FindStringSubmatch(issueBody)
if m == nil || m[1] == "" {
return "", false
}
return m[1], true
}
// IsReviewMarker reports whether commentBody contains <!-- spx:review=1 -->.
func IsReviewMarker(commentBody string) bool {
return reviewRe.MatchString(commentBody)
}