推荐pre-commit/pre-push
/ / / 阅读数:3842前言
使用 git 的同学想必都有这样的工作场景 - 保证生产环境的 ci 不挂。也就是检查 python 是否符合 pep8/csslint/jslint/pylint/pyflake8 等. 我在我的 emacs 配置中加入了这一项 py-autopep8 , 就是在保存缓存区的时候把当前缓存区的文本放到一个临时文件,然后执行 autopep8, 再检查 pep8/flake8
但是不能对 css/js/html 做规范检查。而且也不通用。周末看到了 Yelp 的 pre-commit . 感觉是个很有意思的东西,虽然之前也写过类似的 hook. 但是没有它灵活。看完他的源码后,我今天给大家介绍下这个东西
pre-commit
玩过 svn/git 的同学应该都知道他们有各种的 hook. 也就是准备 / 完成什么事件的时候做些额外的工作。一般是 shell 脚本,版本控制工具会判断脚本的退出码,如果不是 0, 就不会继续完成. pre-commit 顾名思义就是在 commit 之前做的准备,也就是每次执行
git commit -m 'xxx'
的时候去做一些检查。启用的插件都放到这个版本库目录的根目录下,名字叫做.pre-commit-config.yaml -> 详细文档请看: http://pre-commit.com/
这里有我的一个配置例子:
- repo: https://github.com/pre-commit/pre-commit-hooks sha: b03733bc86d9e8b2564a5798ade40d64baae3055 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: autopep8-wrapper args: ['-i', '--ignore=E265,E309,E501'] - id: check-docstring-first - id: check-json - id: check-yaml - id: debug-statements - id: name-tests-test - id: requirements-txt-fixer - id: flake8 - repo: https://github.com/pre-commit/pre-commit sha: 86c99c6b870a261d2aff0b4cdb36995764edce1b hooks: - id: validate_config - id: validate_manifest - repo: https://github.com/asottile/reorder_python_imports sha: ea9fa14a757bb210d849de5af8f8ba2c9744027a hooks: - id: reorder-python-imports |
安装使用
pip install pre-commit pre-commit install # PS: 第一次执行commit会比较慢,因为他会clone对应的源, 之后就会用这个缓存的源 # 其他的可选源和用法直接参照[https://github.com/pre-commit](https://github.com/pre-commit)里面的项目或者[http://pre-commit.com/hooks.html](http://pre-commit.com/hooks.html) |
看一个失败的例子 (有颜色效果,不能展示出来)
$git commit -m 'test' Trim Trailing Whitespace.................................................................................................................Passed Fix End of Files.........................................................................................................................Passed autopep8 wrapper.........................................................................................................................Passed Check docstring is first.................................................................................................................Passed Check JSON..........................................................................................................(no files to check) Skipped Check Yaml..........................................................................................................(no files to check) Skipped Debug Statements (Python)................................................................................................................Passed Tests should end in _test.py........................................................................................(no files to check) Skipped Fix requirements.txt................................................................................................(no files to check) Skipped Flake8...................................................................................................................................Failed hookid: flake8 pre_commit/__init__.py:2:1: F401 'os' imported but unused pre_commit/__init__.py:3:1: F401 'sys' imported but unused Validate Pre-Commit Config..........................................................................................(no files to check) Skipped Validate Pre-Commit Manifest........................................................................................(no files to check) Skipped Reorder python imports...................................................................................................................Passed # 因为我的flake8有问题 所以commit失败了 |
pre-commit 的问题
我觉得对每次 commit 做一次审查,第一是需要时间,第二是没有必要,因为经常一个 pr 有多个 commit, 我只保证整体结果是正确的就好了 - 也就是说应该是在 push 的时候。整个过程我可能对 commit 做多次 rebase/--amend 等等。某一次的检查失败其实完全不 影响我做后的结果 - 我是手快党
so. 我基于它修改了一个版本 pre-push , 只是我对 push 做了拦截。并且我会经常和它保持同步
pre-commit install -t pre-commit # 默认安装pre-commit钩子, 每次commit触发 pre-commit install -t pre-push # 默认安装pre-push钩子, 每次push触发 |
其他用法完全一样.
假如 push 的时候想要不检查而强制 push, 可以加上--no-verify
参数
Update from 2015-01-15
我的这个分支已经合并到 pre-commit . pull189
大家可以不要用我的分支了. PS: 这是我见到测试覆盖最高的项目.