Replace whole-repo grep with four production-only gates so Goose and tests stop looking like writer debt, and so new SQL, path, or event crossings fail immediately. Co-authored-by: Cursor <cursoragent@cursor.com>
83 lines
2.4 KiB
Go
83 lines
2.4 KiB
Go
package archtest
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Evaluation struct {
|
|
Unmatched []Finding
|
|
Excepted []Finding
|
|
BadExceptions []string
|
|
Counts map[string]int
|
|
CountRegressed []string
|
|
}
|
|
|
|
func Evaluate(findings []Finding, b *Boundaries, now time.Time) Evaluation {
|
|
ev := Evaluation{Counts: map[string]int{}}
|
|
used := make([]bool, len(b.Exceptions))
|
|
for i, ex := range b.Exceptions {
|
|
if err := ex.validate(now); err != nil {
|
|
ev.BadExceptions = append(ev.BadExceptions, fmt.Sprintf("exception[%d] %s %s %s: %v", i, ex.Kind, ex.File, ex.Symbol, err))
|
|
}
|
|
}
|
|
for _, f := range findings {
|
|
ev.Counts[f.Kind]++
|
|
matched := false
|
|
for i, ex := range b.Exceptions {
|
|
if !ex.matches(f) {
|
|
continue
|
|
}
|
|
if err := ex.validate(now); err != nil {
|
|
continue
|
|
}
|
|
used[i] = true
|
|
matched = true
|
|
ev.Excepted = append(ev.Excepted, f)
|
|
break
|
|
}
|
|
if !matched {
|
|
ev.Unmatched = append(ev.Unmatched, f)
|
|
}
|
|
}
|
|
sort.Slice(ev.Unmatched, func(i, j int) bool { return ev.Unmatched[i].Key() < ev.Unmatched[j].Key() })
|
|
sort.Slice(ev.Excepted, func(i, j int) bool { return ev.Excepted[i].Key() < ev.Excepted[j].Key() })
|
|
|
|
for kind, baseline := range b.BaselineCounts {
|
|
if ev.Counts[kind] > baseline {
|
|
ev.CountRegressed = append(ev.CountRegressed, fmt.Sprintf("%s: %d > baseline %d", kind, ev.Counts[kind], baseline))
|
|
}
|
|
}
|
|
sort.Strings(ev.CountRegressed)
|
|
return ev
|
|
}
|
|
|
|
func (ev Evaluation) Failed() bool {
|
|
return len(ev.Unmatched) > 0 || len(ev.BadExceptions) > 0 || len(ev.CountRegressed) > 0
|
|
}
|
|
|
|
func (ev Evaluation) Report() string {
|
|
var b strings.Builder
|
|
fmt.Fprintf(&b, "archtest findings=%d excepted=%d unmatched=%d\n",
|
|
ev.Counts[KindImport]+ev.Counts[KindSQLWrite]+ev.Counts[KindPath]+ev.Counts[KindEvent],
|
|
len(ev.Excepted), len(ev.Unmatched))
|
|
for _, kind := range []string{KindImport, KindSQLWrite, KindPath, KindEvent} {
|
|
fmt.Fprintf(&b, " %s=%d\n", kind, ev.Counts[kind])
|
|
}
|
|
for _, msg := range ev.BadExceptions {
|
|
fmt.Fprintf(&b, "BAD_EXCEPTION %s\n", msg)
|
|
}
|
|
for _, msg := range ev.CountRegressed {
|
|
fmt.Fprintf(&b, "REGRESSION %s\n", msg)
|
|
}
|
|
for _, f := range ev.Unmatched {
|
|
fmt.Fprintf(&b, "NEW %s %s %s %s (%s)\n", f.Kind, f.Package, f.File, f.Symbol, f.Detail)
|
|
}
|
|
for _, f := range ev.Excepted {
|
|
fmt.Fprintf(&b, "BASELINE %s %s %s %s (%s)\n", f.Kind, f.Package, f.File, f.Symbol, f.Detail)
|
|
}
|
|
return b.String()
|
|
}
|