import re
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
import ratchet
SUPPRESSION = re.compile(r"#\[(expect|allow)\(([^\]]*)\)\]", re.S)
CLIPPY_LINT = re.compile(r"\bclippy::([a-z_]+)")
def main(argv: list[str]) -> int:
roots = [Path("src")] + sorted(p / "src" for p in Path("crates").glob("*"))
files = sorted(f for root in roots if root.is_dir() for f in root.rglob("*.rs"))
findings: dict[str, int] = {}
occurrences: dict[str, list[str]] = {}
for path in files:
text = path.read_text(encoding="utf-8")
for m in SUPPRESSION.finditer(text):
kind, body = m.group(1), m.group(2)
for lint in CLIPPY_LINT.findall(body):
key = f"{kind}|clippy::{lint}|{path.as_posix()}"
findings[key] = findings.get(key, 0) + 1
line = text.count("\n", 0, m.start()) + 1
occurrences.setdefault(key, []).append(
f"{path.as_posix()}:{line}: #[{kind}(clippy::{lint}, ...)]"
)
return ratchet.ratchet(
"expect_budget", "lint-suppression budget", findings, occurrences, argv
)
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))