pre-commit-hooks

面向 openUBMC 的 pre-commit 钩子集合。本仓库提供 openUBMC 专属 钩子(commit-msg 校验、.sr 文件校验)以及与 openUBMC 流水线对齐的 Lua 格式化/静态检查 钩子(stylua-format / luacheck)、Python 格式化/静态检查 钩子(black / isort / flake8)、C/C++ 格式化 钩子(clang-format)、TypeScript / Vue 代码质量检查与格式化 钩子(eslint / prettier);通用的代码卫生类钩子请直接引用官方仓库镜像(见下文「推荐的官方 hooks」)。

openUBMC 专属钩子(conventional-commit / add-signoff-and-change-id / check-sr)仅依赖 Python 标准库,零网络依赖、首次克隆后完全离线运行,采用 language: script 直接执行脚本,无需为钩子创建虚拟环境。Lua 钩子(stylua-format / luacheck)采用 language: system,需本地预安装 stylua 和 luacheck。black / isort / flake8 / clang-format 采用 language: python + additional_dependencies,eslint / prettier 采用 language: node + additional_dependencies,首次运行时由 pre-commit 在隔离环境中安装指定版本,之后离线。

特性

  • 专属钩子零依赖:commit-msg / check-sr 仅使用 Python 标准库,无需安装任何第三方包
  • 专属钩子离线运行:首次克隆源码到本地缓存后,执行钩子不再联网
  • 专属钩子轻量快速language: script 直接执行,不构建虚拟环境
  • Python 工具自包含:black / isort / flake8 由 pre-commit 自动管理版本,无需手动 pip install
  • Node 工具自包含:eslint / prettier 由 pre-commit 自动管理版本,无需手动 npm install
  • Lua 工具需本地安装:stylua-format / luacheck 采用 language: system,需在宿主机预安装 stylua 和 luacheck,并在组件仓根目录提供 .stylua.toml.luacheckrc 配置文件
  • 跨平台:纯 Python 实现,Windows / macOS / Linux 均可运行

提供的钩子

ID 作用 阶段 自动修复
conventional-commit 校验提交信息符合 Conventional Commits 规范 commit-msg
add-signoff-and-change-id 在 commit message 末尾追加 Signed-off-by 和 Change-Id commit-msg
check-sr 校验 .sr 文件语法(支持 C 风格注释) pre-commit
check-json JSON 语法检查(标准库) pre-commit
check-yaml YAML 语法检查(pyyaml) pre-commit
black Python 代码格式化检查(line-length=120) pre-commit
isort Python import 排序检查(profile=black) pre-commit
flake8 Python 代码风格检查(忽略 E203/W503) pre-commit
stylua-format Lua 代码格式化(需本地安装 stylua) pre-commit
luacheck Lua 静态分析(需本地安装 luacheck) pre-commit
clang-format C/C++ 格式化(-style=file) pre-commit
eslint TypeScript / Vue 代码质量检查与自动修复 pre-commit
prettier TypeScript / Vue / CSS / JSON 代码格式化 pre-commit

快速开始

1. 安装 pre-commit

pip3 install --user pre-commit

2. 在仓库根目录创建 .pre-commit-config.yaml

repos:
  - repo: https://gitcode.com/openUBMC/pre-commit-hooks
    rev: 0.1.0                        # 按需锁定到具体版本
    hooks:
      - id: conventional-commit
      - id: add-signoff-and-change-id

完整的推荐组合(openUBMC 专属 + JSON/YAML 校验 + black/isort/flake8 + clang-format,全部自本仓库提供)见仓库根目录的 .pre-commit-config.yaml 示例文件。

3. 安装 git 钩子

本仓库的两个钩子都在 commit-msg 阶段运行:

pre-commit install --hook-type commit-msg

如同时启用通用代码卫生类钩子(pre-commit 阶段),还需执行 pre-commit install

4. 验证

pre-commit run --all-files
pre-commit run --hook-stage commit-msg --commit-msg-filename .git/COMMIT_EDITMSG

钩子详解

conventional-commit

强制提交信息遵循 Conventional Commits 规范。格式:

type(scope)!: 简短描述
  • type(必填):feat / fix / docs / style / refactor / perf / test / build / ci / chore / revert
  • scope(可选):影响范围
  • !(可选):表示不兼容变更
  • 允许 GitCode MR 编号前缀,如 !123 feat: xxx

可通过参数限定允许的 type:

- id: conventional-commit
  args: [feat, fix, docs, refactor]

add-signoff-and-change-id

在 commit message 末尾自动追加两个 trailer(幂等,已存在则跳过):

  1. Signed-off-by: <name> <email> — 取自 git config user.name / user.email
    • 若两者任一为空,打印警告并跳过此 trailer(不阻断提交)。
    • 若最后非空行已是 trailer(Co-Authored-By / Signed-off-by / Change-Id / Reviewed-by / Tested-by / Acked-by),直接紧随其后;否则在正文与 trailer 之间插入一个空行分隔符。
  2. Change-Id: I<40 位十六进制> — 取 20 字节随机数据的 SHA-1,前缀 I

执行后效果示例:

feat(parser): 支持 CSR-058 字段

补全解析器对 CSR-058 的处理,覆盖读写两条路径。

Signed-off-by: Alice <alice@example.com>
Change-Id: Ia1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0

check-sr

校验 .sr 文件(openUBMC CSR 组件自描述 / PSR 产品自描述记录)的语法。.sr 的实质是 JSONC:标准 JSON + C 风格注释。参考 CSR 文档

工作流程:

  1. utf-8-sig 读取(自动剥除 BOM)。
  2. 用 6 状态有限状态机剥离 // 行注释与 /* */ 块注释,正确跳过字符串字面量内部的注释标记(例如 {"url": "https://example.com"} 中的 // 不会被误删)。
  3. 用标准库 json.loads 解析。

特性与约束:

  • 纯标准库实现,无 json5 / jsonc 等第三方依赖,执行环境无关。
  • 严格模式:仅容忍注释。剥离注释后必须是标准 JSON,不支持尾逗号、单引号字符串、裸 key、十六进制数字。
  • 失败时打印 <filepath>: <json 错误消息>(自带行列号),不做位置重映射。
  • pre-commit 通过 files: '\.sr$' 过滤,仅把暂存的 .sr 文件传给本钩子。

stylua-format

Lua 代码格式化,使用 StyLua。覆盖 G.FMT.02~06/08 规则(缩进、行宽、引号风格等)。

  • language: system,需本地安装 stylua(推荐 cargo install stylua 或下载官方 release)
  • 读取组件仓根目录的 .stylua.toml 配置文件(--config-path .stylua.toml
  • --verify 参数确保格式化结果可正确解析,防止格式化引入语法错误
  • 自动修复模式:原地改写 .lua 文件

luacheck

Lua 静态分析,使用 Luacheck。覆盖 G.CHK.02/05、G.VAR.02、G.MOD.02 规则。

  • language: system,需本地安装 luacheck(推荐 luarocks install luacheck
  • 读取组件仓根目录的 .luacheckrc 配置文件(--config .luacheckrc
  • --codes 显示警告代码,--no-color 无颜色输出,--ranges 显示问题范围
  • 仅检查不修复

注意:stylua-format 和 luacheck 的配置文件(.stylua.toml / .luacheckrc)需放在组件仓根目录,pre-commit 在组件仓工作目录中运行时会自动读取。本仓库不提供模板文件,各组件仓应自行维护。

推荐的官方 hooks

本仓库 manifest 不引用任何外部仓库。下列 5 个通用代码卫生钩子需要独立脚本实现(自动修复或非平凡检测逻辑),本仓库为保持 hooks/ 精简不复刻,已在示例 .pre-commit-config.yaml 中通过官方国内镜像默认启用

钩子 id 作用 是否自动修复
trailing-whitespace 行尾空白符
end-of-file-fixer 文件末尾换行符
check-merge-conflict 合并冲突标记
check-added-large-files 大文件(默认 --maxkb 1024
check-case-conflict 文件名大小写冲突

镜像源:https://gitcode.com/gh_mirrors/pr/pre-commit-hooks(推荐 rev v6.0.0)。如需 detect-private-key 等其它钩子,按需在示例配置中追加对应 - id: 即可。JSON / YAML 语法检查、C/C++ 格式化(clang-format)、Python 格式化与静态检查(black / isort / flake8)已由本仓库直接提供,无需额外引用。

新开发机一次性配置(推荐)

pre-commit install 需要每个仓库单独执行。如果同时维护多个仓库、不想每次 clone 后都手动安装,可以配置 git 模板目录,让此后所有新 clone / init 的仓库自动带上钩子:

# 1. 指定 git 模板目录
git config --global init.templateDir ~/.git-template

# 2. 把 pre-commit 钩子写入模板目录
pre-commit init-templatedir ~/.git-template
pre-commit init-templatedir --hook-type commit-msg ~/.git-template

完成后再 git clone 任何 openUBMC 仓库,钩子会自动生效,无需再手动 pre-commit install

说明:

  • 对没有 .pre-commit-config.yaml 的仓库(如非 openUBMC 项目),pre-commit 会自动跳过、不报错,不影响正常提交。
  • 仅对此后新 clone / init 的仓库生效;此前已存在的仓库仍需手动 pre-commit install
  • pre-commit 工具本身仍需先 pip3 install --user pre-commit 安装。

团队协作

.pre-commit-config.yaml 随仓库分发后,新成员只需:

pip3 install --user pre-commit
pre-commit install
pre-commit install --hook-type commit-msg

上游钩子更新

本仓库以及官方镜像会持续迭代(修 bug、升 black/isort/flake8 版本、调整校验规则)。.pre-commit-config.yaml 里的 rev: 锁定了具体版本,上游更新后不会自动生效,需要用户在本地执行命令拉取新版本:

# 1. 把所有 repo 的 rev 刷新到最新 tag(会改写 .pre-commit-config.yaml)
pre-commit autoupdate

# 2. 提交 .pre-commit-config.yaml 的 rev 变更
git add .pre-commit-config.yaml && git commit -m "chore: bump pre-commit hooks"

# 3. 如钩子脚本是 language: script(本仓库三个 openUBMC 专属钩子),
#    autoupdate 会重新克隆源码到本地缓存;如遇缓存异常可强制重装:
pre-commit install-hooks --force

说明:

  • pre-commit autoupdate 仅更新 rev,不会改动本仓库的 hook 定义。
  • black / isort / flake8 的 additional_dependencies 版本升级同样通过 autoupdate 触发,pre-commit 会重建隔离虚拟环境。
  • 升级后建议执行 pre-commit run --all-files 确认现有代码仍通过。

环境要求

  • pre-commit >= 3.0.0
  • Python >= 3.9