33
44import logging
55import os
6+ import re
67import subprocess
78import sys
89
@@ -36,7 +37,19 @@ def _hook_msg_start(hook, verbose):
3637 )
3738
3839
39- def filter_filenames_by_types (filenames , types , exclude_types ):
40+ def _filter_by_include_exclude (filenames , include , exclude ):
41+ include_re , exclude_re = re .compile (include ), re .compile (exclude )
42+ return {
43+ filename for filename in filenames
44+ if (
45+ include_re .search (filename ) and
46+ not exclude_re .search (filename ) and
47+ os .path .lexists (filename )
48+ )
49+ }
50+
51+
52+ def _filter_by_types (filenames , types , exclude_types ):
4053 types , exclude_types = frozenset (types ), frozenset (exclude_types )
4154 ret = []
4255 for filename in filenames :
@@ -46,34 +59,15 @@ def filter_filenames_by_types(filenames, types, exclude_types):
4659 return tuple (ret )
4760
4861
49- def get_filenames (args , include_expr , exclude_expr ):
50- if args .origin and args .source :
51- getter = git .get_files_matching (
52- lambda : git .get_changed_files (args .origin , args .source ),
53- )
54- elif args .hook_stage == 'commit-msg' :
55- def getter (* _ ):
56- return (args .commit_msg_filename ,)
57- elif args .files :
58- getter = git .get_files_matching (lambda : args .files )
59- elif args .all_files :
60- getter = git .get_all_files_matching
61- elif git .is_in_merge_conflict ():
62- getter = git .get_conflicted_files_matching
63- else :
64- getter = git .get_staged_files_matching
65- return getter (include_expr , exclude_expr )
66-
67-
6862SKIPPED = 'Skipped'
6963NO_FILES = '(no files to check)'
7064
7165
72- def _run_single_hook (hook , repo , args , skips , cols ):
73- filenames = get_filenames ( args , hook ['files' ], hook ['exclude' ])
74- filenames = filter_filenames_by_types (
75- filenames , hook ['types' ], hook ['exclude_types' ],
76- )
66+ def _run_single_hook (filenames , hook , repo , args , skips , cols ):
67+ include , exclude = hook ['files' ], hook ['exclude' ]
68+ filenames = _filter_by_include_exclude ( filenames , include , exclude )
69+ types , exclude_types = hook ['types' ], hook ['exclude_types' ]
70+ filenames = _filter_by_types ( filenames , types , exclude_types )
7771 if hook ['id' ] in skips :
7872 output .write (get_hook_message (
7973 _hook_msg_start (hook , args .verbose ),
@@ -169,13 +163,29 @@ def _compute_cols(hooks, verbose):
169163 return max (cols , 80 )
170164
171165
166+ def _all_filenames (args ):
167+ if args .origin and args .source :
168+ return git .get_changed_files (args .origin , args .source )
169+ elif args .hook_stage == 'commit-msg' :
170+ return (args .commit_msg_filename ,)
171+ elif args .files :
172+ return args .files
173+ elif args .all_files :
174+ return git .get_all_files ()
175+ elif git .is_in_merge_conflict ():
176+ return git .get_conflicted_files ()
177+ else :
178+ return git .get_staged_files ()
179+
180+
172181def _run_hooks (config , repo_hooks , args , environ ):
173182 """Actually run the hooks."""
174183 skips = _get_skips (environ )
175184 cols = _compute_cols ([hook for _ , hook in repo_hooks ], args .verbose )
185+ filenames = _all_filenames (args )
176186 retval = 0
177187 for repo , hook in repo_hooks :
178- retval |= _run_single_hook (hook , repo , args , skips , cols )
188+ retval |= _run_single_hook (filenames , hook , repo , args , skips , cols )
179189 if retval and config ['fail_fast' ]:
180190 break
181191 if (
0 commit comments