#!/usr/bin/env python3 """Refuse a file too long to review, and say so before one gets there. Two numbers, both in lines the way `wc -l` counts them, and both set once at the top of this file. A file over the block limit fails the run: nobody reads one of those end to end, and a change inside it is reviewed by hope. A file over the warning limit is printed and the run still passes: it is the point at which a file has picked up a second subject and the next person to touch it is the one who can still name what those subjects are. Neither number judges the code. A long file of one thing is a long file of one thing, and the warning is a question, not a finding. What the block limit says is that the answer has stopped being anybody's to give. No third-party modules on purpose: this runs on every commit, so it has to start fast and work in a fresh clone. Run by prek over the staged files, or by hand: scripts/check-file-size.py ... """ import sys BLOCK_LINES = 5000 WARN_LINES = 2000 def count_lines(path): """Lines in a file, or None if it cannot be read as one.""" try: with open(path, "rb") as handle: return handle.read().count(b"\n") except OSError: return None def main(paths): blocked = [] for path in paths: lines = count_lines(path) if lines is None: continue if lines > BLOCK_LINES: blocked.append((path, lines)) elif lines > WARN_LINES: print( f"check-file-size: {path} is {lines} lines, over {WARN_LINES}." " Worth splitting while it is still one person's to split." ) for path, lines in blocked: print( f"check-file-size: {path} is {lines} lines, over the" f" {BLOCK_LINES} a commit may carry. Split it first.", file=sys.stderr, ) return 1 if blocked else 0 if __name__ == "__main__": sys.exit(main(sys.argv[1:]))