package guards import ( "bufio" "os" "testing" ) // maxFileLines is AGENTS.md's per-file cap ("Mechanical rules" and the // frontend section both cite 300 lines; this test enforces the Go side). const maxFileLines = 300 // lineCapExempt lists files exempt from the cap, by exact repo-relative // path — never by pattern or directory, so an exemption is a visible, // reviewable decision rather than a rule that silently swallows // whatever lands nearby later. Empty today: nothing vendored or // generated in this repo's .go tree exceeds the cap yet. Add an entry // here, dated and justified, the day one does. var lineCapExempt = map[string]bool{} // TestFileLineCap enforces the 300-line cap per .go file. It is a floor, // not a ratchet: it stops a file from ever crossing 300 lines, but does // not push any file already under the cap any lower. func TestFileLineCap(t *testing.T) { root := repoRoot(t) for _, path := range goFiles(t, root) { rel := relPath(t, root, path) if lineCapExempt[rel] { continue } n, err := countLines(path) if err != nil { t.Fatalf("guards: count lines in %s: %v", rel, err) } if n > maxFileLines { t.Errorf("%s: %d lines exceeds the %d-line cap (AGENTS.md Mechanical rules: 300-line file cap)", rel, n, maxFileLines) } } } // countLines counts lines the way bufio.Scanner's ScanLines does: each // newline-terminated line, plus a final line even if it has no trailing // newline. That is NOT what `wc -l` reports — wc -l counts newline // characters, so a file whose last line lacks a trailing newline gets // one fewer from wc than from this. This function's count is the // stricter of the two (it can only report equal or one higher), and // gofmt already guarantees a trailing newline on every .go file this // test walks, so the difference never shows up here in practice. func countLines(path string) (int, error) { f, err := os.Open(path) if err != nil { return 0, err } defer f.Close() sc := bufio.NewScanner(f) sc.Buffer(make([]byte, 0, 64*1024), 1024*1024) n := 0 for sc.Scan() { n++ } return n, sc.Err() }