跳转至

pre-commit 维护代码风格

参考: 在Git项目中使用pre-commit统一管理hooks

介绍

Git 钩子脚本对于在提交代码审查之前识别简单问题很有用。我们在每次提交时运行hooks(钩子),以自动指出代码中的问题,例如缺少分号、尾随空格和调试语句。通过在代码审查之前指出这些问题,代码审查者可以专注于更改的架构,而不会浪费时间在琐碎的样式挑剔上。

随着我们创建更多的库和项目,我们认识到跨项目共享我们的预提交挂钩是痛苦的。我们将笨拙的 bash 脚本从一个项目复制并粘贴到另一个项目,并且必须手动更改挂钩以适用于不同的项目结构。

我们相信您应该始终使用最好的行业标准 linters。一些最好的 linters 是用你没有在你的项目中使用或安装在你的机器上的语言编写的。例如 scss-lint 是用 Ruby 编写的 SCSS 的 linter。如果您在 node 中编写项目,您应该能够使用 scss-lint 作为预提交挂钩,而无需将 Gemfile 添加到您的项目或了解如何安装 scss-lint。

我们构建了预提交来解决我们的钩子问题。它是一个用于预提交挂钩的多语言包管理器。您指定所需的挂钩列表,并在每次提交之前预提交管理以任何语言编写的任何挂钩的安装和执行。预提交专门设计为不需要 root 访问权限。如果您的开发人员之一没有安装节点但修改了 JavaScript 文件,预提交会自动处理下载和构建节点以在没有 root 的情况下运行 eslint。

安装

在运行挂钩之前,您需要安装pre-commit包管理器。

使用pip:

pip install pre-commit

在一个python项目中,将下面的行添加到你的依赖文件requirements.txt(或requirements-dev.txt)中。

pre-commit

也可以像0依赖的zipapp那样安装:

  • github发布历史中找到并下载.pyz文件
  • 在运行 pre-commit ... 的地方替换为 python pre-commit-#.#.#.pyz ...

使用 homebrew 安装:

brew install pre-commit

使用 conda(又称 conda-forge)安装:

conda install -c conda-forge pre-commit

快速开始

  1. 安装 pre-commit

    • 按照上面的安装说明进行操作
    • pre-commit --version 应该显示出你使用的版本是多少

      $ pre-commit --version
      pre-commit 3.3.1
      
  2. 添加一个 pre-commit 配置

    • 创建一个名称为.pre-commit-config.yaml的文件
    • 你可以使用pre-commit sample-config命令生成一个非常基础的配置文件
    • 下面列出了配置的所有选项
    • 此示例使用 python 代码的格式化程序,但是pre-commit适用于任何编程语言
    • 其他被支持的钩子同样是可用的
    repos:
    -   repo: https://github.com/pre-commit/pre-commit-hooks
        rev: v2.3.0
        hooks:
        -   id: check-yaml
        -   id: end-of-file-fixer
        -   id: trailing-whitespace
    -   repo: https://github.com/psf/black
        rev: 22.10.0
        hooks:
        -   id: black
    
  3. 安装 git hook 脚本

    • 运行 pre-commit install 来设置git hook脚本
    $ pre-commit install
    pre-commit installed at .git/hooks/pre-commit
    
  4. (可选)针对所有文件运行

    • 添加新hook(钩子)时,对所有文件运行hook(钩子)通常是个好主意(通常pre-commit只会在 git hook 存在的期间对更改的文件运行)
    $ pre-commit run --all-files
    [INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
    [INFO] Initializing environment for https://github.com/psf/black.
    [INFO] Installing environment for https://github.com/pre-commit/pre-commit-hooks.
    [INFO] Once installed this environment will be reused.
    [INFO] This may take a few minutes...
    [INFO] Installing environment for https://github.com/psf/black.
    [INFO] Once installed this environment will be reused.
    [INFO] This may take a few minutes...
    Check Yaml...............................................................Passed
    Fix End of Files.........................................................Passed
    Trim Trailing Whitespace.................................................Failed
    - hook id: trailing-whitespace
    - exit code: 1
    
    Files were modified by this hook. Additional output:
    
    Fixing sample.py
    
    black....................................................................Passed
    
    • oops! 看起来一些文件有尾随空格。
    • 也考虑在CI中运行它

为你的项目添加pre-commit插件

一旦安装了pre-commit, 就可以使用.pre-commit-config.yaml配置文件将pre-commit插件添加到项目中。

添加一个名为.pre-commit-config.yaml的根目录下的文件。pre-commit配置文件描述了安装了哪些存储库和hooks(钩子)。

.pre-commit-config.yaml - top level

名称 描述
repos 存储库映射列表
default_install_hook_types (可选的, 默认: [pre-commit]) 运行 pre-commit install 时默认使用的 --hook-type 列表
版本2.18.0中添加
default_language_version (可选的, 默认: {}) 从语言到应该用于该语言的默认值的映射 。参考官网。
default_stages (可选的, 默认: (all stages(所有阶段))) hook 的 stage 属性的配置范围默认值,这只会覆盖钩子中没有设置stages属性的钩子. 例如: default_stages: [pre-commit, pre-push]
files (可选的, 默认: '') 全局文件包含模式
exclude (可选的, 默认: '') 全局文件不包含模式
fail_fast (可选的, 默认: false) 设置为true则表示在pre-commit第一次失败之后不会运行钩子
minimum_pre_commit_version (可选的, 默认: 0) pre-commit 运行时需要的最低版本

一个简单的 顶层配置:

exclude: '^$'
fail_fast: false
repos:
-    ...

.pre-commit-config.yaml - repos

存储库映射告诉pre-commit从哪里获取hook(挂钩)代码。

名称 描述
repo git clone 从那个仓库URL克隆
rev 要克隆的版本或标签。
hooks hook映射列表

一个简单的仓库:

repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v1.2.3
    hooks:
    -   ...

.pre-commit-config.yaml - hooks

hook映射配置使用存储库中的哪个挂钩并允许自定义。所有可选密钥将从存储库的配置中接收默认值。

名称 描述
id 要使用的存储库中的哪个挂钩。
alias (可选)允许在使用 pre-commit run <hookid> 时使用附加 id 引用挂钩
name (可选)覆盖挂钩的名称 - 在挂钩执行期间显示。
language_version (可选)覆盖挂钩的语言版本。参考: 覆盖语言版本
files (可选)覆盖要运行的文件的默认模式。
exclude (可选)文件排除模式。
types (可选)覆盖要运行的默认文件类型 (AND)。请参阅:使用类型过滤文件
types_or (可选)覆盖要运行的默认文件类型(或)。请参阅 使用类型过滤文件。 2.9.0 中的新功能。
exclude_types (可选)要排除的文件类型。
args (可选)要传递给挂钩的附加参数列表。
stages (可选)选择要运行的 git 钩子。请参阅限制挂钩在特定阶段运行
additional_dependencies (可选)将在运行此挂钩的环境中安装的依赖项列表。一个有用的应用程序是为挂钩安装插件,例如eslint.
always_run (可选)如果true,即使没有匹配的文件,这个钩子也会运行。
verbose (可选)如果true,即使挂钩通过,也强制打印挂钩的输出。
log_file (可选)如果存在,则当挂钩失败或详细信息为时,挂钩输出将写入文件或者verbosetrue

一个完整配置的示例:

repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v1.2.3
    hooks:
    -   id: trailing-whitespace

此配置表示下载 pre-commit-hooks 项目并运行其 trailing-whitespace 挂钩。

自动更新hooks

您可以通过运行pre-commit autoupdate自动将hooks(钩子)更新到最新版本。默认情况下,这会将hooks(钩子)带到默认分支上的最新标签。

用法

运行pre-commit install 去安装 pre-commit 到你的git hooks中。 现在 pre-commit 会在你commit时自动运行。 每次你克隆一个项目时,使用 pre-commit 运行 pre-commit install 应该是你首先要做的事。

如果你想手动运行所有的 pre-commit 钩子,使用 pre-commit run --all-files 命令。 要运行个别的钩子,使用 pre-commit run <hook_id> 命令。

第一次在文件上运行pre-commit时,它会自动下载、安装和运行hook(钩子)。 请注意,第一次运行挂钩可能会很慢。 例如:如果机器没有安装node,pre-commit将下载并构建node的副本。

$ pre-commit install
pre-commit installed at /home/asottile/workspace/pytest/.git/hooks/pre-commit
$ git commit -m "Add super awesome feature"
black....................................................................Passed
blacken-docs.........................................(no files to check)Skipped
Trim Trailing Whitespace.................................................Passed
Fix End of Files.........................................................Passed
Check Yaml...........................................(no files to check)Skipped
Debug Statements (Python)................................................Passed
Flake8...................................................................Passed
Reorder python imports...................................................Passed
pyupgrade................................................................Passed
rst ``code`` is two backticks........................(no files to check)Skipped
rst..................................................(no files to check)Skipped
changelog filenames..................................(no files to check)Skipped
[main 146c6c2c] Add super awesome feature
 1 file changed, 1 insertion(+)

创建新的钩子

参考官网: Creating new hooks

命令行界面

参考官网: Command line interface

高级功能

参考官网: Advanced features

贡献

参考官网: Contributing


最后更新: 2024年9月4日
创建日期: 2024年9月4日