diff --git a/README.md b/README.md index 7486aba..7207881 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,11 @@ Attempts to load all json files to verify syntax. #### `check-merge-conflict` Check for files that contain merge conflict strings. +#### `check-number-of-lines-count` +Check if number of lines of a file is greater than a threshold. You can +configure this with the following commandline option: + - `--max-lines N` - maximum number of lines allowed in a file. + #### `check-shebang-scripts-are-executable` Checks that scripts with shebangs are executable. diff --git a/pre_commit_hooks/check_number_of_lines_count.py b/pre_commit_hooks/check_number_of_lines_count.py new file mode 100755 index 0000000..f3443d0 --- /dev/null +++ b/pre_commit_hooks/check_number_of_lines_count.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +import argparse +from typing import Optional +from typing import Sequence + + +def main(argv: Optional[Sequence[str]] = None) -> int: + parser = argparse.ArgumentParser() + parser.add_argument('filenames', nargs='*') + parser.add_argument( + '--max-lines', + default=30, + type=int, + action='store', + help='Maximum allowable number of lines (default: 30)', + ) + args = parser.parse_args(argv) + + retcode = 0 + for filename in args.filenames: + with open(filename) as file: + file_content = file.readlines() + number_of_lines = len(file_content) + if number_of_lines > args.max_lines: + print( + f'{filename} ({number_of_lines} lines) exceeds ' + f'{args.max_lines} lines.', + ) + retcode = 1 + + return retcode + + +if __name__ == '__main__': + exit(main()) diff --git a/setup.cfg b/setup.cfg index a5ad401..b5bf71a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -43,6 +43,7 @@ console_scripts = check-executables-have-shebangs = pre_commit_hooks.check_executables_have_shebangs:main check-json = pre_commit_hooks.check_json:main check-merge-conflict = pre_commit_hooks.check_merge_conflict:main + check-number-of-lines-count = check_number_of_lines_count:main check-shebang-scripts-are-executable = pre_commit_hooks.check_shebang_scripts_are_executable:main check-symlinks = pre_commit_hooks.check_symlinks:main check-toml = pre_commit_hooks.check_toml:main diff --git a/tests/check_number_of_lines_count_test.py b/tests/check_number_of_lines_count_test.py new file mode 100644 index 0000000..06f0a57 --- /dev/null +++ b/tests/check_number_of_lines_count_test.py @@ -0,0 +1,31 @@ +from pre_commit_hooks.check_number_of_lines_count import main + + +def test_number_of_lines_count_bad(tmpdir): + max_lines = 30 + line_contents = [] + filename = tmpdir.join('lines_count_bad') + + for line_number in range(max_lines + 1): + line_contents.append(f'I am the {line_number+1}. line!') + + with open(filename, 'w') as file: + file.write('\n'.join(line_contents)) + + ret = main([str(filename), f'--max-lines={max_lines}']) + assert ret == 1 + + +def test_number_of_lines_count_good(tmpdir): + max_lines = 30 + line_contents = [] + filename = tmpdir.join('lines_count_good') + + for line_number in range(max_lines): + line_contents.append(f'I am the {line_number+1}. line!') + + with open(filename, 'w') as file: + file.write('\n'.join(line_contents)) + + ret = main([str(filename), f'--max-lines={max_lines}']) + assert ret == 0