1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
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())
|