返回 DeepSeek-Reasonix
baseline.go
根目录 / tools / repolint / baseline.go
1 package main
2
3 import (
4 "encoding/json"
5 "fmt"
6 "os"
7 )
8
9 // Ratchet snapshot, in weighted units: no file may exceed its budget and no
10 // rule may exceed its repo ceiling. Both are relaxed only by hand, in a diff a
11 // reviewer sees.
12 type Baseline struct {
13 Limits map[string]int `json:"limits"`
14 Files map[string]map[string]int `json:"files"`
15 }
16
17 func loadBaseline(path string) (*Baseline, error) {
18 data, err := os.ReadFile(path)
19 if err != nil {
20 return nil, err
21 }
22 var b Baseline
23 if err := json.Unmarshal(data, &b); err != nil {
24 return nil, fmt.Errorf("%s: %w", path, err)
25 }
26 if b.Limits == nil {
27 b.Limits = map[string]int{}
28 }
29 if b.Files == nil {
30 b.Files = map[string]map[string]int{}
31 }
32 return &b, nil
33 }
34
35 func baselineFrom(findings []Finding) *Baseline {
36 b := &Baseline{Limits: map[string]int{}, Files: map[string]map[string]int{}}
37 for _, rule := range allRules {
38 b.Limits[rule] = 0
39 }
40 for _, f := range findings {
41 b.Limits[f.Rule] += f.Weight
42 if b.Files[f.File] == nil {
43 b.Files[f.File] = map[string]int{}
44 }
45 b.Files[f.File][f.Rule] += f.Weight
46 }
47 return b
48 }
49
50 func (b *Baseline) write(path string) error {
51 data, err := json.MarshalIndent(b, "", " ")
52 if err != nil {
53 return err
54 }
55 return os.WriteFile(path, append(data, '\n'), 0o644)
56 }
57
58 func (b *Baseline) exceeded(findings []Finding) ([]Finding, []string) {
59 counts := map[string]map[string]int{}
60 totals := map[string]int{}
61 for _, f := range findings {
62 if counts[f.File] == nil {
63 counts[f.File] = map[string]int{}
64 }
65 counts[f.File][f.Rule] += f.Weight
66 totals[f.Rule] += f.Weight
67 }
68
69 var msgs []string
70 over := map[string]map[string]bool{}
71 for _, file := range sortedKeys(counts) {
72 for _, rule := range sortedKeys(counts[file]) {
73 allowed := b.Files[file][rule]
74 if got := counts[file][rule]; got > allowed {
75 msgs = append(msgs, fmt.Sprintf("%s: %s is %d over its %d budget", file, rule, got, allowed))
76 if over[file] == nil {
77 over[file] = map[string]bool{}
78 }
79 over[file][rule] = true
80 }
81 }
82 }
83 for _, rule := range sortedKeys(totals) {
84 if totals[rule] > b.Limits[rule] {
85 msgs = append(msgs, fmt.Sprintf("repo total for %s is %d, above the %d ceiling", rule, totals[rule], b.Limits[rule]))
86 }
87 }
88
89 var shown []Finding
90 for _, f := range findings {
91 if over[f.File][f.Rule] {
92 shown = append(shown, f)
93 }
94 }
95 return shown, msgs
96 }
97
97 lines GO