Repository navigation
feat: enforce max lines per file by glob - #29
Merged
Merged
Conversation
* web/ (marketing site, #25) was never added to allowedPaths, so `structlint validate` on this repo and the self-validation tests failed on main Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* new file_size.rules (pattern, maxLines, severity) + exclude; first match wins * lines counted like wc -l; binary, ignored and excluded files skipped * new frozen code file_too_long across text/json/sarif/github outputs * extends: child rules first, same-pattern parent rules dropped * schema, docs, SKILL.md, commented examples in init templates and --infer * dogfood a 500-line limit on non-test Go files Refs #28 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
✅ PR title follows the required formatCurrent title: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #28 (spec 014, approved).
What
Adds
file_size, which sets the maximum number of lines a file may have, matched by glob. It works the same for Go, TypeScript and Python repositories, so it can replace ad-hoccheck-file-size.shscripts. Function- and class-length limits stay in language linters.Before: no size checks; projects relied on shell scripts.
After:
Behavior
**/also matches files at the repo root.wc -l(the number of\ncharacters). A last line without a trailing newline is not counted. CRLF counts once per line. An empty file has 0 lines. I checked these counts against realwc -loutput.ignorelist,excludematches, binary files (a NUL byte in the first 8000 bytes, the heuristic git uses) and non-regular files.--changed-onlyand--stagedare respected.file_too_long(the code count goes from 13 to 14). It shows up in text, json, sarif and github output, and exits non-zero like every other violation.maxLines <= 0, an empty or invalid glob, or an unknown severity. Example message:file_size.rules[0] (*.py): maxLines must be greater than 0, got 0.extends: the child's rules go first, so a child can override a preset's limit for the same pattern.excludeis merged with a dedup append.file_sizeblock, behavior is unchanged. The presets andinit --inferonly ship a commented example, soextends:users see no new violations.Also in this PR
fix(config): allowlistsweb/in the repo's own.structlint.yaml. Self-validation, and the tests that run it, were already failing onmainsince feat: add dedicated marketing site #25..gofiles.Deferred (see spec non-goals)
Max files per directory and max directory depth. Depth can already be limited with
allowedPathsglobs. Files-per-directory has unsettled semantics and no consumer yet.Tests
TDD: I wrote the integration tests first; they build and run the binary. They cover: exactly
maxLinespasses,maxLines+1 fails, an empty file, no trailing newline, CRLF, a lone CR, excluded files, ignored directories, first-match precedence in both orders,**/matching root files, binary files, the invalid-config table, all output formats, warning severity,--staged,extendsoverrides, and that the init/infer examples stay valid once uncommented. Unit tests cover the counter (including multi-chunk reads), the matcher, validation and merge.gofumpt,golangci-lint(0 issues) andgo test -race ./...all pass.Note: the docs use the pragma
>= v0.7.0, assuming this ships as the next minor release. Adjust it if the release tag differs.🤖 Generated with Claude Code