| from __future__ import annotations |
| |
| import argparse |
| import math |
| import os |
| import subprocess |
| from typing import Sequence |
| |
| from pre_commit_hooks.util import added_files |
| from pre_commit_hooks.util import zsplit |
| |
| |
| def filter_lfs_files(filenames: set[str]) -> None: # pragma: no cover (lfs) |
| """Remove files tracked by git-lfs from the set.""" |
| if not filenames: |
| return |
| |
| check_attr = subprocess.run( |
| ('git', 'check-attr', 'filter', '-z', '--stdin'), |
| stdout=subprocess.PIPE, |
| stderr=subprocess.DEVNULL, |
| encoding='utf-8', |
| check=True, |
| input='\0'.join(filenames), |
| ) |
| stdout = zsplit(check_attr.stdout) |
| for i in range(0, len(stdout), 3): |
| filename, filter_tag = stdout[i], stdout[i + 2] |
| if filter_tag == 'lfs': |
| filenames.remove(filename) |
| |
| |
| def find_large_added_files( |
| filenames: Sequence[str], |
| maxkb: int, |
| *, |
| enforce_all: bool = False, |
| ) -> int: |
| # Find all added files that are also in the list of files pre-commit tells |
| # us about |
| retv = 0 |
| filenames_filtered = set(filenames) |
| filter_lfs_files(filenames_filtered) |
| |
| if not enforce_all: |
| filenames_filtered &= added_files() |
| |
| for filename in filenames_filtered: |
| kb = math.ceil(os.stat(filename).st_size / 1024) |
| if kb > maxkb: |
| print(f'{filename} ({kb} KB) exceeds {maxkb} KB.') |
| retv = 1 |
| |
| return retv |
| |
| |
| def main(argv: Sequence[str] | None = None) -> int: |
| parser = argparse.ArgumentParser() |
| parser.add_argument( |
| 'filenames', nargs='*', |
| help='Filenames pre-commit believes are changed.', |
| ) |
| parser.add_argument( |
| '--enforce-all', action='store_true', |
| help='Enforce all files are checked, not just staged files.', |
| ) |
| parser.add_argument( |
| '--maxkb', type=int, default=500, |
| help='Maximum allowable KB for added files', |
| ) |
| args = parser.parse_args(argv) |
| |
| return find_large_added_files( |
| args.filenames, |
| args.maxkb, |
| enforce_all=args.enforce_all, |
| ) |
| |
| |
| if __name__ == '__main__': |
| raise SystemExit(main()) |