1818logger = logging .getLogger ('pre_commit' )
1919
2020
21+ class HookExecuter (object ):
22+ def __init__ (self , hook , invoker ):
23+ self .hook = hook
24+ self ._invoker = invoker
25+
26+ def invoke (self , filenames ):
27+ return self ._invoker (self .hook , filenames )
28+
29+
2130def _get_skips (environ ):
2231 skips = environ .get ('SKIP' , '' )
2332 return set (skip .strip () for skip in skips .split (',' ) if skip .strip ())
@@ -55,21 +64,25 @@ def get_changed_files(new, old):
5564 )[1 ].splitlines ()
5665
5766
58- def _run_single_hook ( runner , repository , hook , args , write , skips = set () ):
67+ def get_filenames ( args , include_expr , exclude_expr ):
5968 if args .origin and args .source :
60- get_filenames = git .get_files_matching (
69+ getter = git .get_files_matching (
6170 lambda : get_changed_files (args .origin , args .source ),
6271 )
6372 elif args .files :
64- get_filenames = git .get_files_matching (lambda : args .files )
73+ getter = git .get_files_matching (lambda : args .files )
6574 elif args .all_files :
66- get_filenames = git .get_all_files_matching
75+ getter = git .get_all_files_matching
6776 elif git .is_in_merge_conflict ():
68- get_filenames = git .get_conflicted_files_matching
77+ getter = git .get_conflicted_files_matching
6978 else :
70- get_filenames = git .get_staged_files_matching
79+ getter = git .get_staged_files_matching
80+ return getter (include_expr , exclude_expr )
7181
72- filenames = get_filenames (hook ['files' ], hook ['exclude' ])
82+
83+ def _run_single_hook (hook_executer , args , write , skips = frozenset ()):
84+ hook = hook_executer .hook
85+ filenames = get_filenames (args , hook ['files' ], hook ['exclude' ])
7386 if hook ['id' ] in skips :
7487 _print_user_skipped (hook , write , args )
7588 return 0
@@ -82,7 +95,7 @@ def _run_single_hook(runner, repository, hook, args, write, skips=set()):
8295 write (get_hook_message (_hook_msg_start (hook , args .verbose ), end_len = 6 ))
8396 sys .stdout .flush ()
8497
85- retcode , stdout , stderr = repository . run_hook ( hook , filenames )
98+ retcode , stdout , stderr = hook_executer . invoke ( filenames )
8699
87100 if retcode != hook ['expected_return_value' ]:
88101 retcode = 1
@@ -106,32 +119,19 @@ def _run_single_hook(runner, repository, hook, args, write, skips=set()):
106119 return retcode
107120
108121
109- def _run_hooks (runner , args , write , environ ):
122+ def _run_hooks (hook_executers , args , write , environ ):
110123 """Actually run the hooks."""
111- retval = 0
112-
113124 skips = _get_skips (environ )
114-
115- for repo in runner .repositories :
116- for _ , hook in repo .hooks :
117- retval |= _run_single_hook (
118- runner , repo , hook , args , write , skips = skips ,
119- )
120-
125+ retval = 0
126+ for hook_executer in hook_executers :
127+ retval |= _run_single_hook (hook_executer , args , write , skips )
121128 return retval
122129
123130
124- def _run_hook (runner , args , write ):
125- hook_id = args .hook
131+ def get_hook_executers (runner ):
126132 for repo in runner .repositories :
127- for hook_id_in_repo , hook in repo .hooks :
128- if hook_id == hook_id_in_repo :
129- return _run_single_hook (
130- runner , repo , hook , args , write = write ,
131- )
132- else :
133- write ('No hook with id `{0}`\n ' .format (hook_id ))
134- return 1
133+ for _ , repo_hook in repo .hooks :
134+ yield HookExecuter (repo_hook , repo .run_hook )
135135
136136
137137def _has_unmerged_paths (runner ):
@@ -159,7 +159,11 @@ def run(runner, args, write=sys_stdout_write_wrapper, environ=os.environ):
159159 ctx = staged_files_only (runner .cmd_runner )
160160
161161 with ctx :
162+ hook_executers = list (get_hook_executers (runner ))
162163 if args .hook :
163- return _run_hook (runner , args , write = write )
164- else :
165- return _run_hooks (runner , args , write = write , environ = environ )
164+ hook_executers = [he for he in hook_executers
165+ if he .hook ['id' ] == args .hook ]
166+ if not hook_executers :
167+ write ('No hook with id `{0}`\n ' .format (args .hook ))
168+ return 1
169+ return _run_hooks (hook_executers , args , write , environ )
0 commit comments