0
# Pre-commit
1
2
A framework for managing and maintaining multi-language pre-commit hooks. Pre-commit enables automatic execution of code quality checks, linting, formatting, and testing before commits are made to version control systems, supporting multiple programming languages and providing a plugin-based architecture for extensibility.
3
4
## Package Information
5
6
- **Package Name**: pre-commit
7
- **Package Type**: pypi
8
- **Language**: Python
9
- **Installation**: `pip install pre-commit`
10
11
## Core Imports
12
13
```python
14
import pre_commit
15
```
16
17
For programmatic API usage:
18
19
```python
20
from pre_commit.main import main
21
from pre_commit.store import Store
22
from pre_commit.hook import Hook
23
from pre_commit.clientlib import load_config, load_manifest, HOOK_TYPES, STAGES
24
from pre_commit import git
25
from pre_commit import constants as C
26
from pre_commit.errors import FatalError, InvalidConfigError, InvalidManifestError
27
from pre_commit.util import cmd_output, CalledProcessError
28
from pre_commit.color import format_color, use_color
29
from pre_commit.output import write_line
30
```
31
32
## Basic Usage
33
34
### Command Line Interface
35
36
```bash
37
# Install git hook scripts
38
pre-commit install
39
40
# Run hooks on all files
41
pre-commit run --all-files
42
43
# Run hooks on staged files only
44
pre-commit run
45
46
# Auto-update hook versions
47
pre-commit autoupdate
48
49
# Validate configuration
50
pre-commit validate-config
51
```
52
53
### Programmatic Usage
54
55
```python
56
from pre_commit.main import main
57
from pre_commit.store import Store
58
from pre_commit.clientlib import load_config, InvalidConfigError
59
from pre_commit.errors import FatalError
60
61
# Run pre-commit programmatically
62
exit_code = main(['run', '--all-files'])
63
64
# Load and validate configuration with error handling
65
try:
66
config = load_config('.pre-commit-config.yaml')
67
print(f"Loaded config with {len(config['repos'])} repositories")
68
except InvalidConfigError as e:
69
print(f"Configuration error: {e}")
70
except FatalError as e:
71
print(f"Fatal error: {e}")
72
73
# Initialize store for hook management
74
store = Store()
75
76
# Example: Clone a repository for hook usage
77
repo_path = store.clone('https://github.com/psf/black', 'main')
78
print(f"Repository cloned to: {repo_path}")
79
```
80
81
## Architecture
82
83
Pre-commit follows a modular architecture built around several key components:
84
85
- **CLI Commands**: Command-line interface providing installation, execution, and management functionality
86
- **Hook System**: Data structures and execution framework for individual hooks
87
- **Language Support**: Plugin-based architecture supporting 22+ programming languages
88
- **Configuration Management**: YAML-based configuration loading and validation
89
- **Git Integration**: Deep integration with Git workflows and repository operations
90
- **Repository Management**: Store system for managing hook repositories and environments
91
92
This design enables pre-commit to serve as a comprehensive framework for maintaining code quality across diverse development environments and language ecosystems.
93
94
## Capabilities
95
96
### CLI Commands
97
98
Complete command-line interface for installing, managing, and executing pre-commit hooks. Includes installation commands, hook execution, configuration management, and utility operations.
99
100
```python { .api }
101
def main(argv: Sequence[str] | None = None) -> int
102
```
103
104
[CLI Commands](./cli-commands.md)
105
106
### Configuration Management
107
108
Configuration loading, validation, and schema definitions for .pre-commit-config.yaml and .pre-commit-hooks.yaml files.
109
110
```python { .api }
111
load_config: functools.partial[dict[str, Any]]
112
# Partial function for loading .pre-commit-config.yaml files
113
# Usage: config = load_config(filename)
114
115
load_manifest: functools.partial[list[dict[str, Any]]]
116
# Partial function for loading .pre-commit-hooks.yaml files
117
# Usage: hooks = load_manifest(filename)
118
```
119
120
[Configuration](./configuration.md)
121
122
### Hook System
123
124
Core data structures and management functions for pre-commit hooks, including hook representation, execution, and environment management.
125
126
```python { .api }
127
class Hook(NamedTuple):
128
src: str
129
prefix: Prefix
130
id: str
131
name: str
132
entry: str
133
language: str
134
alias: str
135
files: str
136
exclude: str
137
types: Sequence[str]
138
types_or: Sequence[str]
139
exclude_types: Sequence[str]
140
additional_dependencies: Sequence[str]
141
args: Sequence[str]
142
always_run: bool
143
fail_fast: bool
144
pass_filenames: bool
145
description: str
146
language_version: str
147
log_file: str
148
minimum_pre_commit_version: str
149
require_serial: bool
150
stages: Sequence[str]
151
verbose: bool
152
```
153
154
[Hooks](./hooks.md)
155
156
### Git Integration
157
158
Git repository utilities and integration functions for working with staged files, repository state, and Git workflow integration.
159
160
```python { .api }
161
def get_root() -> str
162
def get_staged_files(cwd: str | None = None) -> list[str]
163
def get_all_files() -> list[str]
164
```
165
166
[Git Integration](./git-integration.md)
167
168
### Language Support
169
170
Multi-language support system with plugin-based architecture for 22+ programming languages including Python, JavaScript, Go, Rust, and more.
171
172
```python { .api }
173
class Language(Protocol):
174
def get_default_version(self) -> str
175
def install_environment(self, prefix: Prefix, version: str, additional_dependencies: Sequence[str]) -> None
176
def run_hook(self, prefix: Prefix, version: str, cmd: Sequence[str], **kwargs) -> tuple[int, bytes]
177
```
178
179
[Language Support](./language-support.md)
180
181
### Repository Management
182
183
Repository and hook environment management through the Store system, including cloning, caching, and cleanup operations.
184
185
```python { .api }
186
class Store:
187
def clone(self, repo: str, ref: str, deps: Sequence[str] = ()) -> str
188
def make_local(self, deps: Sequence[str]) -> str
189
def select_all_repos(self) -> list[tuple[str, str, str]]
190
```
191
192
[Repository Management](./repository-management.md)
193
194
## Constants and Error Handling
195
196
### Constants
197
198
```python { .api }
199
CONFIG_FILE: str = '.pre-commit-config.yaml'
200
MANIFEST_FILE: str = '.pre-commit-hooks.yaml'
201
LOCAL_REPO_VERSION: str = '1'
202
DEFAULT: str = 'default'
203
VERSION: str # Package version string
204
205
# Hook types and stages
206
HOOK_TYPES: tuple[str, ...] = (
207
'commit-msg', 'post-checkout', 'post-commit', 'post-merge',
208
'post-rewrite', 'pre-commit', 'pre-merge-commit', 'pre-push',
209
'pre-rebase', 'prepare-commit-msg'
210
)
211
STAGES: tuple[str, ...] = (*HOOK_TYPES, 'manual')
212
213
# Repository types
214
LOCAL: str = 'local'
215
META: str = 'meta'
216
217
# Color constants
218
RED: str
219
GREEN: str
220
YELLOW: str
221
TURQUOISE: str
222
SUBTLE: str
223
NORMAL: str
224
COLOR_CHOICES: tuple[str, ...] = ('auto', 'always', 'never')
225
```
226
227
### Exceptions
228
229
```python { .api }
230
class FatalError(RuntimeError):
231
"""Base exception for fatal errors"""
232
233
class InvalidConfigError(FatalError):
234
"""Configuration validation errors"""
235
236
class InvalidManifestError(FatalError):
237
"""Manifest validation errors"""
238
239
class CalledProcessError(RuntimeError):
240
"""Enhanced subprocess error with stdout/stderr capture"""
241
returncode: int
242
cmd: tuple[str, ...]
243
stdout: bytes
244
stderr: bytes | None
245
```
246
247
### Utility Functions
248
249
Core utility functions for process execution, file operations, and resource management.
250
251
```python { .api }
252
def cmd_output(*cmd: str, **kwargs: Any) -> tuple[int, str, str | None]:
253
"""Execute command and return exit code, stdout, stderr as strings"""
254
255
def cmd_output_b(*cmd: str, check: bool = True, **kwargs: Any) -> tuple[int, bytes, bytes | None]:
256
"""Execute command and return exit code, stdout, stderr as bytes"""
257
258
def make_executable(filename: str) -> None:
259
"""Make file executable"""
260
261
def resource_text(filename: str) -> str:
262
"""Read text from package resource file"""
263
264
def clean_path_on_failure(path: str) -> Generator[None, None, None]:
265
"""Context manager that removes path on exception"""
266
```
267
268
### Color Support
269
270
Functions for colored terminal output.
271
272
```python { .api }
273
def format_color(text: str, color: str, use_color_setting: bool) -> str:
274
"""Format text with ANSI color codes"""
275
276
def use_color(setting: str) -> bool:
277
"""Determine if color should be used based on setting"""
278
279
def add_color_option(parser: argparse.ArgumentParser) -> None:
280
"""Add --color argument to argument parser"""
281
```
282
283
### Output Functions
284
285
Terminal output utilities with optional logging support.
286
287
```python { .api }
288
def write(s: str, stream: IO[bytes] = sys.stdout.buffer) -> None:
289
"""Write string to byte stream"""
290
291
def write_line(s: str | None = None, **kwargs: Any) -> None:
292
"""Write line to output with optional logging"""
293
294
def write_line_b(s: bytes | None = None, stream: IO[bytes] = sys.stdout.buffer, logfile_name: str | None = None) -> None:
295
"""Write line as bytes to output with optional logging"""
296
```