0
# Hook System
1
2
Core data structures and management functions for pre-commit hooks. The hook system provides the foundation for defining, configuring, and executing individual hooks within the pre-commit framework.
3
4
## Capabilities
5
6
### Hook Data Structure
7
8
Core data structure representing a configured hook with all its properties and execution parameters.
9
10
```python { .api }
11
class Hook(NamedTuple):
12
"""
13
Immutable data structure representing a configured pre-commit hook.
14
15
All hook properties are defined at initialization and cannot be modified
16
during execution, ensuring consistent behavior across hook runs.
17
"""
18
src: str # Repository source URL or 'local'
19
prefix: Prefix # Installation directory prefix
20
id: str # Unique hook identifier
21
name: str # Display name for output
22
entry: str # Command or script to execute
23
language: str # Programming language (python, node, etc.)
24
alias: str # Alternative name for hook
25
files: str # File pattern regex for inclusion
26
exclude: str # File pattern regex for exclusion
27
types: Sequence[str] # File types to include
28
types_or: Sequence[str] # Alternative file types (OR logic)
29
exclude_types: Sequence[str] # File types to exclude
30
additional_dependencies: Sequence[str] # Extra dependencies to install
31
args: Sequence[str] # Command-line arguments
32
always_run: bool # Run even if no files match
33
fail_fast: bool # Stop execution on first failure
34
pass_filenames: bool # Pass matched filenames to hook
35
description: str # Human-readable description
36
language_version: str # Specific language version
37
log_file: str # Output log file path
38
minimum_pre_commit_version: str # Required pre-commit version
39
require_serial: bool # Require serial execution
40
stages: Sequence[str] # Git hook stages when this runs
41
verbose: bool # Enable verbose output
42
```
43
44
### Prefix System
45
46
Directory management system for hook installations and environments.
47
48
```python { .api }
49
class Prefix(NamedTuple):
50
"""
51
Directory path management for hook installations.
52
53
Provides utilities for constructing paths within hook installation
54
directories and checking for file existence.
55
"""
56
prefix_dir: str # Base installation directory
57
58
def path(self, *parts: str) -> str:
59
"""
60
Construct path within prefix directory.
61
62
Parameters:
63
- parts: Path components to join
64
65
Returns:
66
- str: Complete path within prefix
67
"""
68
69
def exists(self, *parts: str) -> bool:
70
"""
71
Check if path exists within prefix directory.
72
73
Parameters:
74
- parts: Path components to check
75
76
Returns:
77
- bool: True if path exists
78
"""
79
80
def star(self, end: str) -> tuple[str, ...]:
81
"""
82
Glob pattern matching within prefix directory.
83
84
Parameters:
85
- end: Pattern to match
86
87
Returns:
88
- tuple: Matching file paths
89
"""
90
```
91
92
### Hook Management Functions
93
94
Functions for processing and managing collections of hooks.
95
96
```python { .api }
97
def all_hooks(root_config: dict[str, Any], store: Store) -> tuple[Hook, ...]:
98
"""
99
Extract all configured hooks from configuration.
100
101
Processes the configuration file and creates Hook instances for all
102
defined hooks, handling repository cloning and hook resolution.
103
104
Parameters:
105
- root_config: Loaded configuration dictionary
106
- store: Store instance for repository management
107
108
Returns:
109
- tuple: All configured Hook instances
110
"""
111
112
def install_hook_envs(hooks: Sequence[Hook], store: Store) -> None:
113
"""
114
Install environments for all provided hooks.
115
116
Sets up the necessary runtime environments for each hook,
117
including language-specific dependencies and tools.
118
119
Parameters:
120
- hooks: Sequence of hooks to install environments for
121
- store: Store instance for environment management
122
"""
123
```
124
125
### Hook Filtering and Selection
126
127
Functions for filtering hooks based on various criteria.
128
129
```python { .api }
130
def filter_by_include_exclude(
131
hook: Hook,
132
filenames: Sequence[str],
133
include: str = '',
134
exclude: str = ''
135
) -> Sequence[str]:
136
"""
137
Filter filenames based on hook's include/exclude patterns.
138
139
Parameters:
140
- hook: Hook with filtering configuration
141
- filenames: Files to filter
142
- include: Additional include pattern
143
- exclude: Additional exclude pattern
144
145
Returns:
146
- Sequence: Filtered filenames
147
"""
148
149
def classify_by_types(
150
filenames: Sequence[str],
151
types: Sequence[str],
152
types_or: Sequence[str] = (),
153
exclude_types: Sequence[str] = ()
154
) -> Sequence[str]:
155
"""
156
Classify and filter files by type.
157
158
Parameters:
159
- filenames: Files to classify
160
- types: Required file types (AND logic)
161
- types_or: Alternative file types (OR logic)
162
- exclude_types: File types to exclude
163
164
Returns:
165
- Sequence: Files matching type criteria
166
"""
167
```
168
169
## Hook Execution
170
171
### Hook Runner
172
173
Core hook execution functionality with environment management and output handling.
174
175
```python { .api }
176
def run_hook(
177
hook: Hook,
178
file_args: Sequence[str],
179
color: bool = True
180
) -> tuple[int, bytes, int]:
181
"""
182
Execute a single hook with provided file arguments.
183
184
Parameters:
185
- hook: Hook instance to execute
186
- file_args: Files to pass to hook
187
- color: Enable colored output
188
189
Returns:
190
- tuple: (return_code, stdout_bytes, duration_ms)
191
"""
192
```
193
194
### Hook Output Formatting
195
196
Functions for formatting and displaying hook execution results.
197
198
```python { .api }
199
def get_hook_message(
200
hook: Hook,
201
return_code: int,
202
file_count: int,
203
duration_ms: int,
204
color: bool = True
205
) -> str:
206
"""
207
Format hook execution result message.
208
209
Parameters:
210
- hook: Executed hook
211
- return_code: Hook exit code
212
- file_count: Number of files processed
213
- duration_ms: Execution duration
214
- color: Use colored output
215
216
Returns:
217
- str: Formatted status message
218
"""
219
220
def format_hook_output(
221
hook: Hook,
222
output: bytes,
223
use_color: bool = True
224
) -> str:
225
"""
226
Format hook output for display.
227
228
Parameters:
229
- hook: Hook that produced output
230
- output: Raw output bytes
231
- use_color: Enable colored formatting
232
233
Returns:
234
- str: Formatted output string
235
"""
236
```
237
238
## Hook Creation and Processing
239
240
### Hook Factory Functions
241
242
Functions for creating Hook instances from configuration data.
243
244
```python { .api }
245
def _hook_from_config(
246
hook: dict[str, Any],
247
prefix: Prefix,
248
manifest: dict[str, Any],
249
root_config: dict[str, Any]
250
) -> Hook:
251
"""
252
Create Hook instance from configuration and manifest data.
253
254
Parameters:
255
- hook: Hook configuration from .pre-commit-config.yaml
256
- prefix: Installation prefix for hook
257
- manifest: Hook definition from .pre-commit-hooks.yaml
258
- root_config: Root configuration context
259
260
Returns:
261
- Hook: Configured hook instance
262
"""
263
```
264
265
### Local Hook Support
266
267
Support for locally defined hooks without external repositories.
268
269
```python { .api }
270
def local_hook(
271
hook_dict: dict[str, Any],
272
prefix: Prefix
273
) -> Hook:
274
"""
275
Create hook from local configuration.
276
277
Parameters:
278
- hook_dict: Local hook configuration
279
- prefix: Installation prefix
280
281
Returns:
282
- Hook: Local hook instance
283
"""
284
```
285
286
## Hook Stages and Types
287
288
### Supported Hook Stages
289
290
```python { .api }
291
HOOK_TYPES = (
292
'commit-msg', # Commit message validation
293
'post-checkout', # After checkout operations
294
'post-commit', # After successful commit
295
'post-merge', # After merge operations
296
'post-rewrite', # After rewrite operations
297
'pre-commit', # Before commit (default)
298
'pre-merge-commit', # Before merge commits
299
'pre-push', # Before push operations
300
'pre-rebase', # Before rebase operations
301
'prepare-commit-msg' # Commit message preparation
302
)
303
304
STAGES = (*HOOK_TYPES, 'manual') # All types plus manual execution
305
```
306
307
## Usage Examples
308
309
### Working with Hook Instances
310
311
```python
312
from pre_commit.hook import Hook
313
from pre_commit.prefix import Prefix
314
315
# Create a prefix for hook installation
316
prefix = Prefix('/path/to/hook/env')
317
318
# Hook instances are typically created by all_hooks()
319
# but can be constructed directly for testing
320
hook = Hook(
321
src='https://github.com/psf/black',
322
prefix=prefix,
323
id='black',
324
name='black',
325
entry='black',
326
language='python',
327
alias='',
328
files='\.py$',
329
exclude='',
330
types=['python'],
331
types_or=[],
332
exclude_types=[],
333
additional_dependencies=[],
334
args=[],
335
always_run=False,
336
fail_fast=False,
337
pass_filenames=True,
338
description='The uncompromising Python code formatter',
339
language_version='default',
340
log_file='',
341
minimum_pre_commit_version='2.9.2',
342
require_serial=False,
343
stages=['pre-commit'],
344
verbose=False
345
)
346
347
# Check hook properties
348
print(f"Hook: {hook.name} ({hook.language})")
349
print(f"Files pattern: {hook.files}")
350
print(f"Always run: {hook.always_run}")
351
```
352
353
### Loading All Hooks from Configuration
354
355
```python
356
from pre_commit.repository import all_hooks
357
from pre_commit.clientlib import load_config
358
from pre_commit.store import Store
359
360
# Load configuration and create store
361
config = load_config('.pre-commit-config.yaml')
362
store = Store()
363
364
# Get all configured hooks
365
hooks = all_hooks(config, store)
366
367
print(f"Found {len(hooks)} hooks:")
368
for hook in hooks:
369
print(f" {hook.id}: {hook.name} ({hook.language})")
370
```
371
372
### Installing Hook Environments
373
374
```python
375
from pre_commit.repository import install_hook_envs
376
377
# Install environments for all hooks
378
install_hook_envs(hooks, store)
379
print("All hook environments installed")
380
```