文章目录
0. 前言
- 需求:希望在提交代码(git commit)时,对代码的规范进行排查,不符合要求的不让提交。
- 参考资料:官方文档
1. 基本流程
1.1. 基本流程
- 第一步:安装,即在当前python环境中安装
pip install pre-commit
- 第二步:在项目中编写配置文件
.pre-commit-config.yaml
,具体参考1.2. 配置文件编写
。 - 第三步:通过命令行运行
pre-commit install
,成功安装后一般有以下结果。
$ pre-commit install
pre-commit installed at .git/hooks/pre-commit
- 第四步:之后在执行
git commit
时就会自动调用脚本了
1.2. 配置文件编写
- 本质就是编写一个
.pre-commit-config.yaml
,整体格式如下:- 顶层有一个参数名为
repos
。 repos
中每个元素为repo
,代表一个代码库,一般是github或gitlab链接。- 每个
repo
中有一个或多个hook
,每个hook
代表一个任务。 - 每个任务里可理解为一个命令行指令,例如flake8/yapf/black。
- 顶层有一个参数名为
- 如何编写配置文件:
- 从上面的介绍可以看出,我们的主要任务就是确定要执行哪些任务,即那些hooks。
- 所有支持的hooks可以参考 官方文档
- 本文目标代码检查相关hook就有例如 flake8/yapf/black,可以查看上面的文档。
- 本文附录一提供了一个简单的 yapf/flake8 版的配置文件。
- 从上面的介绍可以看出,我们的主要任务就是确定要执行哪些任务,即那些hooks。
- 顶层参数参考文档
参数名 | 作用 |
---|---|
repos | 指定hook及其对应的repo |
default_language_version | 默认的代码版本,比如设置python3.7 |
default_stages | 指的是git命令中的一些阶段,如commit/push等,更多参考文档 |
files | global include pattern,不知道是什么的include |
exclude | global exclude pattern,不知道什么的exclude |
fail_fast | 如果有failure就结束 |
minimum_pre_commit_version | pre-commit 最低版本限制 |
参数名 | 作用 |
---|---|
repo | 指定源码的位置,一般在github或gitlab中 |
rev | 设置clone下源码后需要切换的tags或reversion |
hooks | 指定该repo下的一些hooks,更多参数参考这里 |
1.3. 预期效果
- 以yapf和flake8为例。
- 如果没有问题,那就直接提交成功。
- 如果yapf不通过
- commit提交失败,出问题的python文件会被yapf修改。
- 之后只要yapf修改后的python文件直接添加 git add 一下就可以继续commit了。
- PS:所谓“不通过”,指的就是如果在用yapf格式化代码也会导致文件内容变化。
- 如果flake8不通过
- 会在命令中指出出错的文件、文件中位置、flake8错误编号。
- 需要手动修改相应的错误重新add后再提交commit。
- 截个图看看效果
1.4. 问题与疑问
- 网速问题,哭了……gitlab/github的速度实在是不敢恭维。
- 解决方案:要么慢慢等,要么clone到gitee上,然后修改repo地址。
- 为什么不能用pip的flake8而要在gitlab上clone下来?
- 猜测是不是做了什么修改。
2. pre-commit 原理
- 具体实现代码检查的还是
flake8
等工具。 - 在
git commit
前进行代码检查的解决方案思路 - pre-commit 的实现原理:上一步中提到,pre-commit 的作用就是生成 git 能够识别的 pre-commit hook 脚本。
- pre-commit 要解决两个问题:
- 问题一:pre-commit 中要执行哪些命令。
- 通过配置文件
.pre-commit-config.yaml
选择要执行的命令。
- 通过配置文件
- 问题二:命令来源是什么。
- 在配置文件
.pre-commit-config.yaml
中有指定各类命令对应的 github/gitlab 库。
- 在配置文件
- 概括来说:
- 配置文件
.pre-commit-config.yaml
中指定了要运行的命令以及命令对应的源码。 - pre-commit 的命令(指的是 flake8/yapf 这些,而不是)不依赖当前python环境,而是会自动从github/gitlab上拉取源码进行对应的操作。
- 配置文件
- 问题一:pre-commit 中要执行哪些命令。
3. Hook 功能摘要
-
浏览了一下 官方文档 - Supported hooks,简单些几个。
-
大文件检查:
pre-commit-hooks / check-added-large-files
-
整理 requirements.txt 文件结构:
pre-commit-hooks / requirements-txt-fixer
-
各类Python的lint和formatting工具:autopep8/yapf/black/pylint/mypy/flake8/pyflakes
-
除了支持Python,也支持其他语言,如js/css/c++/json/yaml等
附录一 最小配置文件举例
- 本配置文件中只包含flake8与yapf。
repos:
- repo: https://gitee.com/irving512/flake8
rev: 3.8.3
hooks:
- id: flake8
- repo: https://gitee.com/irving512/mirrors-yapf
rev: v0.30.0
hooks:
- id: yapf
附录二 mmaction2 的配置文件举例
repos:
- repo: https://gitlab.com/pycqa/flake8
rev: 3.8.3
hooks:
- id: flake8
- repo: https://github.com/asottile/seed-isort-config
rev: v2.2.0
hooks:
- id: seed-isort-config
- repo: https://github.com/timothycrosley/isort
rev: 4.3.21
hooks:
- id: isort
- repo: https://github.com/pre-commit/mirrors-yapf
rev: v0.30.0
hooks:
- id: yapf
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.1.0
hooks:
- id: trailing-whitespace
- id: check-yaml
- id: end-of-file-fixer
- id: requirements-txt-fixer
- id: double-quote-string-fixer
- id: check-merge-conflict
- id: fix-encoding-pragma
args: ["--remove"]
- id: mixed-line-ending
args: ["--fix=lf"]
- repo: https://github.com/myint/docformatter
rev: v1.3.1
hooks:
- id: docformatter
args: ["--in-place", "--wrap-descriptions", "79"]