Pre-commit 是一个非常有用的工具,它可以用于在提交代码之前运行一些钩子脚本,以确保代码的质量和一致性。在本文中,我们将介绍如何使用 Pre-commit 来管理 Python 项目的代码质量。

1. 安装 Pre-commit

首先,需要在计算机上安装 Pre-commit。使用 pip 安装 Pre-commit:

1
pip install pre-commit

2. 创建配置文件

在项目的根目录下,创建一个名为 .pre-commit-config.yaml 的文件。这个文件将用于配置 Pre-commit 钩子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
hooks:
- id: check-json
# 检查JSON文件的格式是否正确。
- id: check-yaml
# 检查YAML文件的格式是否正确。
- id: check-toml
# 检查TOML文件的格式是否正确。
- id: check-xml
# 检查XML文件的格式是否正确。
- id: check-symlinks
# 检查是否存在死链接(即指向不存在的文件或目录的符号链接)。
- id: check-case-conflict
# 检查文件系统中是否存在大小写冲突的文件名(这在某些文件系统上是问题,如Linux,但在Windows上不是问题)。
- id: check-executables-have-shebangs
# 检查可执行文件是否包含shebang行(#!),这是指定解释器路径的特殊注释行。
- id: check-python-bytecode
# 检查是否意外地添加了Python字节码文件(如.pyc文件),这些文件通常不需要提交到仓库中。
- id: check-ast
# 检查Python文件是否可以被Python抽象语法树(AST)解析器成功解析。
- id: check-docstring-first
# 检查Python文件中的类、函数和模块是否以文档字符串(docstring)开头。
- id: check-python-ast
# 与check-ast类似,但可能具有更具体的检查目标或行为。
- id: check-builtin-literals
# 检查Python文件中是否使用了Python内置的常量(如True、False、None)的字符串表示(如'True'),并建议替换为内置的常量。
- id: check-requirements-txt
# 检查requirements.txt文件的内容是否符合一定的规范,如是否包含重复的包等。
- id: check-added-large-files
# 检查新添加的文件是否过大,防止意外地添加大文件到仓库中。
- id: check-merge-conflict
# 检查文件是否包含合并冲突标记,这些标记通常是由于合并冲突未解决而遗留在文件中的。
- id: debug-statements
# 检查Python文件中是否包含调试语句(如print语句),这些语句在发布版本中通常应该被移除。
- id: end-of-file-fixer
# 确保文件以换行符结尾,这是许多文本编辑器和IDE的期望行为。
- id: trailing-whitespace
# 去除文件末尾的空白字符。
- id: fix-encoding-pragma
# 修正Python文件的编码声明(如果存在的话),使其符合PEP 263的规定。
- id: mixed-line-ending
# 检查并修正文件中混合的行结束符(如CRLF和LF),以确保文件的一致性。
- id: detect-aws-credentials
# 检测文件中是否包含AWS凭证(如访问密钥ID和私有密钥),这些凭证应该被保密,不应提交到仓库中。
- id: detect-private-key
# 检测文件中是否包含私钥,私钥应该被保密,不应提交到仓库中。
- id: detect-secrets
# 使用一种更通用的方法来检测文件中是否包含敏感信息,如密码、密钥等。
- id: detect-svn-secrets
# 检测文件中是否包含SVN(Subversion)相关的敏感信息。

这个配置文件包含了一些常用的钩子,例如检查大文件、检查合并冲突、检查 JSON、YAML、TOML 和 XML 文件等。可以根据需要添加或删除钩子。

3. 安装 Pre-commit 钩子

在创建了配置文件之后,需要安装 Pre-commit 钩子。在项目的根目录下运行以下命令:

1
pre-commit install

这个命令将在 .git/hooks 目录下创建一个名为 pre-commit 的文件,该文件将在您尝试提交代码时自动运行。

4. 测试 Pre-commit

为了确保 Pre-commit 正常工作,可以尝试提交一个包含错误的文件。例如,可以创建一个名为 example.py 的文件,并在其中添加一些错误代码:

1
print("Hello, World!"

然后,尝试提交这个文件:

1
2
git add example.py
git commit -m "Add example.py"

会看到 Pre-commit 运行并报告错误:

1
example.py:1:1: E901 SyntaxError: EOL while scanning string literal

修复错误并重新提交代码:

1
print("Hello, World!")

这次提交应该会成功。

5. 使用 Pre-commit 插件

Pre-commit 支持许多插件,这些插件可以帮助检查代码风格、代码质量等问题。例如,可以使用 flake8 插件来检查 Python 代码的风格和错误。

首先,将 flake8 添加到您的配置文件中:

1
2
3
4
5
repos:
- repo: https://github.com/pre-commit/mirrors-flake8
rev: v4.0.1
hooks:
- id: flake8

然后,安装 Pre-commit 钩子:

1
pre-commit install

现在,尝试提交代码时,flake8 将会检查 Python 代码。

6. 更多 Pre-commit 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pre-commit install  # 默认stage安装,通常为commit 生成.git/hooks/pre-commit文件
pre-commit install --hook-type pre-commit --hook-type pre-push ## 安装commit、push两个stage

# 执行检查
pre-commit run --all-files # 使用所有插件检查项目所有文件
pre-commit run <HOOK_ID> --all-files # 使用特定插件检查项目所有文件
pre-commit run --files <PATH_TO_FILE> # 使用所有插件检查特定文件
pre-commit run <HOOK_ID> --files <PATH_TO_FILE> # 使用特定插件检查特定文件

# 忽略
SKIP=gitleaks git commit -m "skip gitleaks check" # 忽略某个插件
git commit -m <MESSAGE> --no-verify # 不检测

# 升级
pre-commit autoupdate

# 清理
pre-commit gc # 清理.cache/pre-commit目录下无用的插件
pre-commit clean # 清空.cache/pre-commit目录