refactor: 重写 Git hooks 体系,委托已有检查、新增模板与 LFS 校验
pre-commit 代码检查改为委托 _backend-lint / _versionctl-lint / _frontend-check,新增 LFS 指针校验;commit-msg 新增多行空行格式校验和模板注释忽略,移除 CJK/Python 字符集检测;新增 prepare-commit-msg 提交信息模板;hooks-install 增加 source 文件存在性校验;前端 check 补入 tsc -b 类型检查并修复暴露的类型错误
This commit is contained in:
@@ -8,12 +8,33 @@
|
||||
|
||||
### Requirement: pre-commit hook 快速检查
|
||||
|
||||
pre-commit hook SHALL 在 `git commit` 执行前对 staged files 进行快速检查,仅检查本次提交涉及的文件。
|
||||
pre-commit hook SHALL 在 `git commit` 执行前对 staged files 进行快速检查。非代码检查(冲突标记、大文件告警、LFS 指针)SHALL 在 `_hooks-pre-commit` 中直接实现;代码检查(Go 后端、Go versionctl、前端)SHALL 根据 staged 文件类型有条件地委托给已有 Makefile target(`_backend-lint`、`_versionctl-lint`、`_frontend-check`),不再内联独立的 lint 命令。
|
||||
|
||||
#### Scenario: 无 Go 和前端文件变更时跳过
|
||||
#### Scenario: 无 Go 和前端文件变更时跳过代码检查
|
||||
|
||||
- **WHEN** staged files 中既无 `.go` 文件也无 `.ts`/`.tsx`/`.scss` 文件
|
||||
- **THEN** pre-commit hook SHALL 直接通过,不运行任何 linter
|
||||
- **THEN** pre-commit hook SHALL 跳过代码检查委托,仅执行非代码检查
|
||||
|
||||
#### Scenario: Go 文件变更时委托后端 lint
|
||||
|
||||
- **WHEN** staged files 中包含 `backend/*.go` 文件
|
||||
- **THEN** pre-commit hook SHALL 委托 `_backend-lint` target 进行 Go 代码检查
|
||||
- **THEN** `_backend-lint` SHALL 复用 `backend/.golangci.yml` 配置
|
||||
- **THEN** 若 lint 报告任何错误,commit SHALL 被阻止
|
||||
|
||||
#### Scenario: versionctl Go 文件变更时委托 versionctl lint
|
||||
|
||||
- **WHEN** staged files 中包含 `versionctl/*.go` 文件
|
||||
- **THEN** pre-commit hook SHALL 委托 `_versionctl-lint` target 进行 Go 代码检查
|
||||
- **THEN** `_versionctl-lint` SHALL 复用 `versionctl/.golangci.yml` 配置
|
||||
- **THEN** 若 lint 报告任何错误,commit SHALL 被阻止
|
||||
|
||||
#### Scenario: 前端文件变更时委托前端检查
|
||||
|
||||
- **WHEN** staged files 中包含 `.ts`、`.tsx` 或 `.scss` 文件
|
||||
- **THEN** pre-commit hook SHALL 委托 `_frontend-check` target 进行前端代码检查
|
||||
- **THEN** `_frontend-check` SHALL 运行 `bun run check`(包含 `tsc -b` TypeScript 类型检查、ESLint 和 Prettier 格式检查)
|
||||
- **THEN** 若检查报告任何错误,commit SHALL 被阻止
|
||||
|
||||
#### Scenario: 冲突标记检测
|
||||
|
||||
@@ -21,37 +42,26 @@ pre-commit hook SHALL 在 `git commit` 执行前对 staged files 进行快速检
|
||||
- **THEN** pre-commit hook SHALL 报告错误并列出包含冲突的文件名
|
||||
- **THEN** commit SHALL 被阻止
|
||||
|
||||
#### Scenario: Go 文件 lint 检查
|
||||
|
||||
- **WHEN** staged files 中包含 `.go` 文件
|
||||
- **THEN** pre-commit hook SHALL 对 staged `.go` 文件运行 `golangci-lint run`(复用 `backend/.golangci.yml` 配置)
|
||||
- **THEN** 若 lint 报告任何错误,commit SHALL 被阻止
|
||||
|
||||
#### Scenario: 前端文件 lint 检查
|
||||
|
||||
- **WHEN** staged files 中包含 `.ts` 或 `.tsx` 文件
|
||||
- **THEN** pre-commit hook SHALL 对 staged 前端文件运行 ESLint(复用 `frontend/eslint.config.js` 配置)
|
||||
- **THEN** 若 ESLint 报告任何错误,commit SHALL 被阻止
|
||||
|
||||
#### Scenario: 前端文件格式检查
|
||||
|
||||
- **WHEN** staged files 中包含 `.ts`、`.tsx` 或 `.scss` 文件
|
||||
- **THEN** pre-commit hook SHALL 对 staged 前端文件运行 Prettier 格式检查(复用 `frontend/.prettierrc` 配置)
|
||||
- **THEN** 若存在格式不符合规范的文件,commit SHALL 被阻止
|
||||
|
||||
#### Scenario: 大文件告警
|
||||
|
||||
- **WHEN** staged files 中存在超过 500KB 的文本文件
|
||||
- **THEN** pre-commit hook SHALL 输出警告信息(不阻止提交),提示检查是否误提交
|
||||
|
||||
#### Scenario: LFS 指针校验
|
||||
|
||||
- **WHEN** staged files 匹配 `.gitattributes` 中 `filter=lfs` 的路径模式
|
||||
- **THEN** pre-commit hook SHALL 检查 staged 内容是否为 LFS 指针格式(`version https://git-lfs.github.com/spec/v1`)
|
||||
- **THEN** 若内容不是 LFS 指针格式,commit SHALL 被阻止,并提示安装 git-lfs
|
||||
- **THEN** 若 staged files 不匹配任何 `filter=lfs` 路径模式,SHALL 跳过此检查
|
||||
|
||||
#### Scenario: commit 被阻止时显示修复提示
|
||||
|
||||
- **WHEN** pre-commit hook 检查失败
|
||||
- **THEN** hook SHALL 输出明确的修复提示(如 `bun run fix`、手动解决冲突标记等)
|
||||
- **THEN** hook SHALL 输出明确的修复提示(如 `make lint` 修复代码问题、手动解决冲突标记等)
|
||||
|
||||
### Requirement: commit-msg hook 校验提交信息格式
|
||||
|
||||
commit-msg hook SHALL 在 `git commit` 输入提交信息后校验格式,确保符合项目规范。提交描述 SHALL 使用中文;版本号、英文专有名词可与中文描述混用。
|
||||
commit-msg hook SHALL 在 `git commit` 输入提交信息后校验格式,确保首行符合项目规范。提交描述按项目规范应使用中文,但 hook SHALL NOT 通过 Python/CJK 字符集检测强制判断描述语言,以避免引入新的运行时依赖。
|
||||
|
||||
#### Scenario: 合法格式通过
|
||||
|
||||
@@ -63,12 +73,6 @@ commit-msg hook SHALL 在 `git commit` 输入提交信息后校验格式,确
|
||||
- **WHEN** 提交信息首行使用的类型不在允许列表中(如 `update: xxx`)
|
||||
- **THEN** commit-msg hook SHALL 报告错误,显示允许的类型列表,commit SHALL 被阻止
|
||||
|
||||
#### Scenario: 英文描述被拒绝
|
||||
|
||||
- **WHEN** 提交信息首行为 `feat: add auth`
|
||||
- **THEN** commit-msg hook SHALL 报告错误,提示提交描述需使用中文
|
||||
- **THEN** commit SHALL 被阻止
|
||||
|
||||
#### Scenario: 缺少冒号空格被拒绝
|
||||
|
||||
- **WHEN** 提交信息首行为 `feat:xxx`(冒号后无空格)或 `feat xxx`
|
||||
@@ -89,16 +93,35 @@ commit-msg hook SHALL 在 `git commit` 输入提交信息后校验格式,确
|
||||
- **WHEN** commit-msg hook 检查失败
|
||||
- **THEN** hook SHALL 输出包含正确格式示例的错误信息(如 `feat: 添加供应商批量管理功能`)
|
||||
|
||||
#### Scenario: 不执行字符集检测
|
||||
|
||||
- **WHEN** 提交信息首行格式合法且类型合法,但描述部分不包含 CJK 字符(如 `feat: add hook tests`)
|
||||
- **THEN** commit-msg hook SHALL 通过
|
||||
- **THEN** hook SHALL NOT 调用 `python3` 或其他额外运行时做 Unicode/CJK 检测
|
||||
|
||||
#### Scenario: 多行格式校验
|
||||
|
||||
- **WHEN** 提交信息忽略 `#` 注释行后,第三行及之后存在任一非空详细说明行
|
||||
- **THEN** commit-msg hook SHALL 检查第二行是否为空行
|
||||
- **THEN** 若第二行非空行,commit SHALL 被阻止,提示首行后应空行再写详细描述
|
||||
|
||||
#### Scenario: 模板注释不参与校验
|
||||
|
||||
- **WHEN** 提交信息文件中包含 prepare-commit-msg 写入的 `#` 注释模板
|
||||
- **THEN** commit-msg hook SHALL 忽略这些注释行
|
||||
- **THEN** 注释行 SHALL NOT 导致首行格式、多行空行分隔校验失败
|
||||
|
||||
### Requirement: hooks-install 安装命令
|
||||
|
||||
`make hooks-install` SHALL 将 `scripts/git-hooks/` 下的 hook 脚本安装到 `.git/hooks/`,不覆盖 Git LFS 管理的 hook。
|
||||
|
||||
#### Scenario: 安装 pre-commit 和 commit-msg
|
||||
#### Scenario: 安装所有 hook 脚本
|
||||
|
||||
- **WHEN** 执行 `make hooks-install`
|
||||
- **THEN** `scripts/git-hooks/pre-commit` SHALL 被复制到 `.git/hooks/pre-commit`
|
||||
- **THEN** `scripts/git-hooks/commit-msg` SHALL 被复制到 `.git/hooks/commit-msg`
|
||||
- **THEN** 两个文件 SHALL 被设置为可执行(`chmod +x`)
|
||||
- **THEN** `scripts/git-hooks/prepare-commit-msg` SHALL 被复制到 `.git/hooks/prepare-commit-msg`
|
||||
- **THEN** 所有复制文件 SHALL 被设置为可执行(`chmod +x`)
|
||||
|
||||
#### Scenario: 不覆盖 LFS 管理的 hook
|
||||
|
||||
@@ -113,9 +136,15 @@ commit-msg hook SHALL 在 `git commit` 输入提交信息后校验格式,确
|
||||
#### Scenario: hooks-check 验证安装状态
|
||||
|
||||
- **WHEN** 执行 `make hooks-check`
|
||||
- **THEN** 命令 SHALL 检查 `.git/hooks/pre-commit` 和 `.git/hooks/commit-msg` 是否存在且可执行
|
||||
- **THEN** 命令 SHALL 检查 `.git/hooks/pre-commit`、`.git/hooks/commit-msg`、`.git/hooks/prepare-commit-msg` 是否存在且可执行
|
||||
- **THEN** SHALL 输出每个 hook 的安装状态
|
||||
|
||||
#### Scenario: 安装前验证 source 文件存在
|
||||
|
||||
- **WHEN** 执行 `make hooks-install`
|
||||
- **THEN** 命令 SHALL 在复制前验证每个 source 文件(`scripts/git-hooks/<hook-name>`)是否存在
|
||||
- **THEN** 若 source 文件不存在,命令 SHALL 报告错误并返回非零退出码
|
||||
|
||||
### Requirement: hooks-test 回归测试命令
|
||||
|
||||
`make hooks-test` SHALL 运行仓库内 hook 回归测试,覆盖 commit-msg 格式校验和 pre-commit staged-file 检查,不污染真实 git index。
|
||||
@@ -146,19 +175,19 @@ pre-commit 和 commit-msg hook 脚本 SHALL 可在 macOS 和 Windows(Git Bash
|
||||
|
||||
### Requirement: pre-commit 核心逻辑在 Makefile 中复用
|
||||
|
||||
pre-commit hook 的检查逻辑 SHALL 通过 Makefile target 调用项目已有工具链,不重复实现 hook 框架逻辑。commit-msg hook SHALL 在脚本内直接完成格式校验。
|
||||
pre-commit hook 的检查逻辑 SHALL 通过 Makefile target 调用项目已有工具链,不重复实现。非代码检查(冲突标记、大文件、LFS 指针)SHALL 在 `_hooks-pre-commit` 中直接实现;代码检查 SHALL 委托 `_backend-lint`、`_versionctl-lint`、`_frontend-check` target。
|
||||
|
||||
#### Scenario: Go lint 复用后端配置
|
||||
#### Scenario: Go lint 委托后端 lint target
|
||||
|
||||
- **WHEN** pre-commit 需要检查 Go 文件
|
||||
- **THEN** SHALL 调用 Makefile 逻辑,在 `backend/` 目录对 staged `.go` 文件运行 `go tool golangci-lint run`
|
||||
- **THEN** SHALL 复用 `backend/.golangci.yml` 中的 lint 配置
|
||||
- **THEN** SHALL 委托 `_backend-lint` 或 `_versionctl-lint` target(根据文件路径 `backend/` vs `versionctl/`)
|
||||
- **THEN** SHALL NOT 在 `_hooks-pre-commit` 中内联 `golangci-lint` 命令
|
||||
|
||||
#### Scenario: 前端 lint 使用 staged 文件参数
|
||||
#### Scenario: 前端检查委托前端 check target
|
||||
|
||||
- **WHEN** pre-commit 需要检查前端文件
|
||||
- **THEN** SHALL 调用 Makefile 逻辑,在 `frontend/` 目录对 staged 前端文件运行 ESLint 和 Prettier 的文件参数模式
|
||||
- **THEN** SHALL NOT 在 pre-commit 阶段运行全量 `bun run check`
|
||||
- **THEN** SHALL 委托 `_frontend-check` target
|
||||
- **THEN** SHALL NOT 在 `_hooks-pre-commit` 中内联 `eslint` 或 `prettier` 命令
|
||||
|
||||
#### Scenario: 终端直接调试
|
||||
|
||||
|
||||
Reference in New Issue
Block a user