|
| 1 | +[https://blog.csdn.net/irving512/article/details/108701017](https://blog.csdn.net/irving512/article/details/108701017) |
| 2 | + |
| 3 | +## pre-commit |
| 4 | + |
| 5 | +`pre-commit` 是一个 Git 钩子管理工具,它可以在 `git commit` 之前自动运行代码检查、格式化等任务,确保提交的代码符合规范,避免低级错误。它支持 `black`、`flake8`、`isort`、`mypy` 等多种工具。 |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## **1. 安装 **`pre-commit` |
| 10 | + |
| 11 | +```shell |
| 12 | +pip install pre-commit |
| 13 | +``` |
| 14 | + |
| 15 | +或者添加到 `requirements.txt` 里: |
| 16 | + |
| 17 | +```shell |
| 18 | +echo "pre-commit" >> requirements.txt |
| 19 | +``` |
| 20 | + |
| 21 | +--- |
| 22 | + |
| 23 | +## **2. 初始化 **`pre-commit`** 配置** |
| 24 | + |
| 25 | +在项目根目录创建 `.pre-commit-config.yaml`,示例如下: |
| 26 | + |
| 27 | +```yaml |
| 28 | +repos: |
| 29 | + - repo: https://github.com/pre-commit/pre-commit-hooks |
| 30 | + rev: v4.5.0 # 指定版本 |
| 31 | + hooks: |
| 32 | + - id: trailing-whitespace # 删除行尾多余空格 |
| 33 | + - id: end-of-file-fixer # 确保文件以空行结尾 |
| 34 | + - id: check-yaml # 检查 YAML 语法 |
| 35 | + - repo: https://github.com/psf/black |
| 36 | + rev: 24.3.0 |
| 37 | + hooks: |
| 38 | + - id: black # 代码格式化 |
| 39 | + - repo: https://github.com/pycqa/flake8 |
| 40 | + rev: 6.1.0 |
| 41 | + hooks: |
| 42 | + - id: flake8 # 代码规范检查 |
| 43 | + - repo: https://github.com/asottile/pyupgrade |
| 44 | + rev: v3.15.0 |
| 45 | + hooks: |
| 46 | + - id: pyupgrade # 升级 Python 语法 |
| 47 | + args: ["--py38-plus"] |
| 48 | +``` |
| 49 | +
|
| 50 | +这里配置了: |
| 51 | +
|
| 52 | ++ **基本代码清理**(删除多余空格、检查 YAML) |
| 53 | ++ `black`** 代码格式化** |
| 54 | ++ `flake8`** 代码规范检查** |
| 55 | ++ `pyupgrade`** 让代码升级到 Python 3.8+ 语法** |
| 56 | + |
| 57 | +--- |
| 58 | + |
| 59 | +## **3. 安装 **`pre-commit`** 钩子** |
| 60 | + |
| 61 | +运行以下命令,将 `pre-commit` 钩子安装到 Git 仓库: |
| 62 | + |
| 63 | +```shell |
| 64 | +pre-commit install |
| 65 | +``` |
| 66 | + |
| 67 | +之后,每次 `git commit` 时都会自动运行 `.pre-commit-config.yaml` 中的检查。 |
| 68 | + |
| 69 | +--- |
| 70 | + |
| 71 | +## **4. 手动运行 **`pre-commit` |
| 72 | + |
| 73 | +如果你想在提交前手动检查代码,可以运行: |
| 74 | + |
| 75 | +```shell |
| 76 | +pre-commit run --all-files |
| 77 | +``` |
| 78 | + |
| 79 | +如果有多个 hook,可以指定运行某一个: |
| 80 | + |
| 81 | +```shell |
| 82 | +pre-commit run black --all-files |
| 83 | +``` |
| 84 | + |
| 85 | +--- |
| 86 | + |
| 87 | +## **5. 在 CI/CD 中使用** |
| 88 | + |
| 89 | +在 CI/CD(比如 GitHub Actions)中,可以添加: |
| 90 | + |
| 91 | +```yaml |
| 92 | +- name: Run pre-commit checks |
| 93 | + run: | |
| 94 | + pip install pre-commit |
| 95 | + pre-commit run --all-files |
| 96 | +``` |
| 97 | + |
| 98 | +--- |
| 99 | + |
| 100 | +## **6. 如何跳过 **`pre-commit`**?** |
| 101 | + |
| 102 | +如果某次提交不想运行 `pre-commit`,可以使用: |
| 103 | + |
| 104 | +```shell |
| 105 | +git commit -m "skip checks" --no-verify |
| 106 | +``` |
| 107 | + |
| 108 | +--- |
| 109 | + |
| 110 | +## **7. 更新 **`pre-commit`** 钩子** |
| 111 | + |
| 112 | +如果你修改了 `.pre-commit-config.yaml`,需要运行: |
| 113 | + |
| 114 | +```shell |
| 115 | +pre-commit autoupdate # 更新到最新的 hooks 版本 |
| 116 | +``` |
| 117 | + |
| 118 | +--- |
| 119 | + |
| 120 | +### **总结** |
| 121 | + |
| 122 | +1. **安装** `pre-commit` |
| 123 | +2. **创建** `.pre-commit-config.yaml` |
| 124 | +3. **运行 **`pre-commit install` 绑定 Git 钩子 |
| 125 | +4. **提交代码时自动检查**,不符合规范会报错 |
| 126 | +5. **可手动运行 **`pre-commit run --all-files` |
| 127 | +6. **可跳过检查 **`--no-verify` |
| 128 | +7. **定期更新 **`pre-commit autoupdate` |
| 129 | + |
| 130 | +这样,每次提交代码时都能自动检查格式,减少人工 Review 的负担,代码质量也会更高!🚀 |
| 131 | + |
| 132 | +## 文件解读 |
| 133 | + |
| 134 | +```python |
| 135 | +repos: |
| 136 | + - repo: https://github.com/pre-commit/pre-commit-hooks |
| 137 | + rev: v5.0.0 |
| 138 | + hooks: |
| 139 | + - id: check-executables-have-shebangs |
| 140 | + - id: check-toml |
| 141 | + - id: check-yaml |
| 142 | + - id: end-of-file-fixer |
| 143 | + types: [python] |
| 144 | + - id: trailing-whitespace |
| 145 | + - id: requirements-txt-fixer |
| 146 | +
|
| 147 | + - repo: https://github.com/MarcoGorelli/auto-walrus |
| 148 | + rev: 0.3.4 |
| 149 | + hooks: |
| 150 | + - id: auto-walrus |
| 151 | +
|
| 152 | + - repo: https://github.com/astral-sh/ruff-pre-commit |
| 153 | + rev: v0.11.2 |
| 154 | + hooks: |
| 155 | + - id: ruff |
| 156 | + - id: ruff-format |
| 157 | +
|
| 158 | + - repo: https://github.com/codespell-project/codespell |
| 159 | + rev: v2.4.1 |
| 160 | + hooks: |
| 161 | + - id: codespell |
| 162 | + additional_dependencies: |
| 163 | + - tomli |
| 164 | +
|
| 165 | + - repo: https://github.com/tox-dev/pyproject-fmt |
| 166 | + rev: "v2.5.1" |
| 167 | + hooks: |
| 168 | + - id: pyproject-fmt |
| 169 | +
|
| 170 | + - repo: https://github.com/abravalheri/validate-pyproject |
| 171 | + rev: v0.24.1 |
| 172 | + hooks: |
| 173 | + - id: validate-pyproject |
| 174 | +
|
| 175 | + - repo: https://github.com/pre-commit/mirrors-mypy |
| 176 | + rev: v1.15.0 |
| 177 | + hooks: |
| 178 | + - id: mypy |
| 179 | + args: |
| 180 | + - --explicit-package-bases |
| 181 | + - --ignore-missing-imports |
| 182 | + - --install-types # See mirrors-mypy README.md |
| 183 | + - --non-interactive |
| 184 | + additional_dependencies: [types-requests] |
| 185 | +
|
| 186 | + - repo: https://github.com/pre-commit/mirrors-prettier |
| 187 | + rev: "v4.0.0-alpha.8" |
| 188 | + hooks: |
| 189 | + - id: prettier |
| 190 | + types_or: [toml, yaml] |
| 191 | +``` |
| 192 | + |
| 193 | +这个 `.pre-commit-config.yaml` 文件配置了一些代码检查和格式化的 `pre-commit` 钩子,下面我们逐项解读: |
| 194 | + |
| 195 | +--- |
| 196 | + |
| 197 | +## **1. 通用检查 (**`pre-commit-hooks`**)** |
| 198 | + |
| 199 | +```yaml |
| 200 | + - repo: https://github.com/pre-commit/pre-commit-hooks |
| 201 | + rev: v5.0.0 |
| 202 | + hooks: |
| 203 | + - id: check-executables-have-shebangs |
| 204 | + - id: check-toml |
| 205 | + - id: check-yaml |
| 206 | + - id: end-of-file-fixer |
| 207 | + types: [python] |
| 208 | + - id: trailing-whitespace |
| 209 | + - id: requirements-txt-fixer |
| 210 | +``` |
| 211 | + |
| 212 | +**目的**:基本代码质量检查,确保文件格式和语法正确。 |
| 213 | + |
| 214 | +**钩子解析:** |
| 215 | + |
| 216 | ++ `check-executables-have-shebangs` |
| 217 | + - 确保可执行文件以 `#!/usr/bin/env python3` 这样的 shebang 头部开头。 |
| 218 | ++ `check-toml` |
| 219 | + - 检查 `*.toml` 文件的语法是否合法(如 `pyproject.toml`)。 |
| 220 | ++ `check-yaml` |
| 221 | + - 检查 `*.yaml` / `*.yml` 文件的语法是否正确。 |
| 222 | ++ `end-of-file-fixer` |
| 223 | + - 确保 Python 文件以空行结尾(符合 PEP 8 规范)。 |
| 224 | ++ `trailing-whitespace` |
| 225 | + - 移除代码中的多余空格,避免不必要的代码变更。 |
| 226 | ++ `requirements-txt-fixer` |
| 227 | + - 规范化 `requirements.txt`,按字母顺序排序,并删除重复项。 |
| 228 | + |
| 229 | +--- |
| 230 | + |
| 231 | +## **2. **`auto-walrus`**(自动优化 Python 代码)** |
| 232 | + |
| 233 | +```yaml |
| 234 | + - repo: https://github.com/MarcoGorelli/auto-walrus |
| 235 | + rev: 0.3.4 |
| 236 | + hooks: |
| 237 | + - id: auto-walrus |
| 238 | +``` |
| 239 | + |
| 240 | +**目的**:自动转换可以使用海象运算符 `:=`(Python 3.8+)的代码,优化可读性和性能。例如: |
| 241 | + |
| 242 | +```python |
| 243 | +# Before |
| 244 | +match = re.match(r"\d+", text) |
| 245 | +if match: |
| 246 | + print(match.group()) |
| 247 | + |
| 248 | +# After auto-walrus |
| 249 | +if match := re.match(r"\d+", text): |
| 250 | + print(match.group()) |
| 251 | +``` |
| 252 | + |
| 253 | +--- |
| 254 | + |
| 255 | +## **3. **`ruff`**(静态分析 + 代码格式化)** |
| 256 | + |
| 257 | +```yaml |
| 258 | + - repo: https://github.com/astral-sh/ruff-pre-commit |
| 259 | + rev: v0.11.2 |
| 260 | + hooks: |
| 261 | + - id: ruff |
| 262 | + - id: ruff-format |
| 263 | +``` |
| 264 | + |
| 265 | +**目的**:使用 `ruff` 进行 Python 代码检查(替代 `flake8` + `isort` + `pylint`),同时进行代码格式化。 |
| 266 | + |
| 267 | +**钩子解析:** |
| 268 | + |
| 269 | ++ `ruff` |
| 270 | + - 进行静态分析,检查 Python 代码是否有错误(如未使用的变量、未导入的模块)。 |
| 271 | ++ `ruff-format` |
| 272 | + - 自动格式化 Python 代码(类似 `black`)。 |
| 273 | + |
| 274 | +--- |
| 275 | + |
| 276 | +## **4. **`codespell`**(拼写检查)** |
| 277 | + |
| 278 | +```yaml |
| 279 | + - repo: https://github.com/codespell-project/codespell |
| 280 | + rev: v2.4.1 |
| 281 | + hooks: |
| 282 | + - id: codespell |
| 283 | + additional_dependencies: |
| 284 | + - tomli |
| 285 | +``` |
| 286 | + |
| 287 | +**目的**:检测代码和文档中的拼写错误,防止低级拼写错误(如 `recieve -> receive`)。 |
| 288 | + |
| 289 | ++ `additional_dependencies: [tomli]` |
| 290 | + - 这里 `tomli` 用于解析 `pyproject.toml`,确保 `codespell` 能正确处理 TOML 格式。 |
| 291 | + |
| 292 | +--- |
| 293 | + |
| 294 | +## **5. **`pyproject-fmt`**(格式化 **`pyproject.toml`** 文件)** |
| 295 | + |
| 296 | +```yaml |
| 297 | + - repo: https://github.com/tox-dev/pyproject-fmt |
| 298 | + rev: "v2.5.1" |
| 299 | + hooks: |
| 300 | + - id: pyproject-fmt |
| 301 | +``` |
| 302 | + |
| 303 | +**目的**:自动格式化 `pyproject.toml`,确保其结构清晰、可读性强。 |
| 304 | + |
| 305 | +--- |
| 306 | + |
| 307 | +## **6. **`validate-pyproject`**(检查 **`pyproject.toml`** 配置合法性)** |
| 308 | + |
| 309 | +```yaml |
| 310 | + - repo: https://github.com/abravalheri/validate-pyproject |
| 311 | + rev: v0.24.1 |
| 312 | + hooks: |
| 313 | + - id: validate-pyproject |
| 314 | +``` |
| 315 | + |
| 316 | +**目的**:验证 `pyproject.toml` 是否符合规范,避免配置错误导致工具无法正常工作。 |
| 317 | + |
| 318 | +--- |
| 319 | + |
| 320 | +## **7. **`mypy`**(静态类型检查)** |
| 321 | + |
| 322 | +```yaml |
| 323 | + - repo: https://github.com/pre-commit/mirrors-mypy |
| 324 | + rev: v1.15.0 |
| 325 | + hooks: |
| 326 | + - id: mypy |
| 327 | + args: |
| 328 | + - --explicit-package-bases |
| 329 | + - --ignore-missing-imports |
| 330 | + - --install-types # See mirrors-mypy README.md |
| 331 | + - --non-interactive |
| 332 | + additional_dependencies: [types-requests] |
| 333 | +``` |
| 334 | + |
| 335 | +**目的**:使用 `mypy` 进行 Python 代码的静态类型检查,确保类型安全。 |
| 336 | + |
| 337 | +**钩子解析:** |
| 338 | + |
| 339 | ++ `--explicit-package-bases` |
| 340 | + - 需要显式指定包的根目录,防止 `mypy` 误解析。 |
| 341 | ++ `--ignore-missing-imports` |
| 342 | + - 忽略找不到类型信息的外部依赖,否则 `mypy` 可能会报错。 |
| 343 | ++ `--install-types` |
| 344 | + - 自动安装缺失的类型提示包。 |
| 345 | ++ `--non-interactive` |
| 346 | + - 禁止 `mypy` 运行时交互,确保 `pre-commit` 可以自动执行。 |
| 347 | ++ `additional_dependencies: [types-requests]` |
| 348 | + - 安装 `requests` 库的类型提示支持,避免 `mypy` 报错。 |
| 349 | + |
| 350 | +--- |
| 351 | + |
| 352 | +## **8. **`prettier`**(格式化 **`TOML`** / **`YAML`**)** |
| 353 | + |
| 354 | +```yaml |
| 355 | + - repo: https://github.com/pre-commit/mirrors-prettier |
| 356 | + rev: "v4.0.0-alpha.8" |
| 357 | + hooks: |
| 358 | + - id: prettier |
| 359 | + types_or: [toml, yaml] |
| 360 | +``` |
| 361 | + |
| 362 | +**目的**:使用 `prettier` 自动格式化 `toml` 和 `yaml` 文件,确保配置文件格式统一。 |
| 363 | + |
| 364 | +--- |
| 365 | + |
| 366 | +## **总结** |
| 367 | + |
| 368 | +| 钩子 | 作用 | |
| 369 | +| --------------------------------- | ----------------------------- | |
| 370 | +| `check-executables-have-shebangs` | 确保可执行文件有 `#!` 头部 | |
| 371 | +| `check-toml` / `check-yaml` | 确保 TOML / YAML 文件语法正确 | |
| 372 | +| `end-of-file-fixer` | 确保文件结尾有空行 | |
| 373 | +| `trailing-whitespace` | 移除多余空格 | |
| 374 | +| `requirements-txt-fixer` | 规范 `requirements.txt` | |
| 375 | +| `auto-walrus` | 代码优化,使用 `:=` 语法 | |
| 376 | +| `ruff` / `ruff-format` | 静态分析和代码格式化 | |
| 377 | +| `codespell` | 拼写检查 | |
| 378 | +| `pyproject-fmt` | `pyproject.toml` 格式化 | |
| 379 | +| `validate-pyproject` | `pyproject.toml` 语法检查 | |
| 380 | +| `mypy` | 进行 Python 静态类型检查 | |
| 381 | +| `prettier` | 格式化 `toml` 和 `yaml` 文件 | |
| 382 | + |
| 383 | + |
| 384 | +这个 `pre-commit` 配置已经非常全面,涵盖了代码规范、格式化、静态分析、拼写检查等多个方面,可以极大提升代码质量和团队协作效率!🚀 |
| 385 | + |
0 commit comments