You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
3.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
set -euo pipefail
msg_file="${1:-}"
if [[ -z "${msg_file}" || ! -f "${msg_file}" ]]; then
echo "错误未找到提交信息文件commit-msg hook 未收到有效参数)。" >&2
exit 1
fi
# 读取第一条“有效提交信息”(跳过空行与注释行),并兼容 CRLF。
first_line="$(
awk '
{
sub(/\r$/, "")
if ($0 ~ /^[[:space:]]*#/) next
if ($0 ~ /^[[:space:]]*$/) next
print
exit
}
' "${msg_file}"
)"
allowed_types=(
feat fix docs style refactor perf test build ci chore revert
)
allowed_scopes=(
frontend ast sema ir irgen mir backend antlr build test doc dev
)
print_allowed() {
local IFS="|"
echo "允许的 type${allowed_types[*]}" >&2
echo "允许的 scope${allowed_scopes[*]}" >&2
}
fail() {
local reason="$1"
local extra="${2:-}"
echo "错误:提交信息不符合规范:${reason}" >&2
echo "" >&2
echo "当前提交信息:" >&2
echo " ${first_line}" >&2
echo "" >&2
echo "规范格式:" >&2
echo " <type>(<scope>): <subject>" >&2
echo "" >&2
echo "注意:" >&2
echo " 1) 冒号必须是英文 ':'(不是中文 '')。" >&2
echo " 2) 冒号后必须严格跟 1 个空格(': ')。" >&2
echo "" >&2
print_allowed
echo "" >&2
echo "示例:" >&2
echo " feat(irgen): add constant folding" >&2
echo " fix(sema): handle null symbol" >&2
echo " docs(doc): update build instructions" >&2
if [[ -n "${extra}" ]]; then
echo "" >&2
echo "${extra}" >&2
fi
echo "" >&2
echo "参考文档doc/Git Commit Message 规范.md" >&2
exit 1
}
if [[ -z "${first_line}" ]]; then
fail "提交信息为空(第一行不能为空)。"
fi
# 允许 merge 提交信息git merge 默认生成的 message
if [[ "${first_line}" == "Merge "* ]]; then
exit 0
fi
# 允许 fixup!/squash!(用于 rebase --autosquash 等流程)。
if [[ "${first_line}" == "fixup!"* || "${first_line}" == "squash!"* ]]; then
exit 0
fi
# 先做一些常见错误的定向提示。
if [[ "${first_line}" == *""* ]]; then
fail "检测到中文冒号 ''。" "请把中文冒号替换为英文冒号 ':',并确保冒号后有且仅有 1 个空格。"
fi
if [[ "${first_line}" =~ ^[A-Za-z]+\([A-Za-z]+\):[^[:space:]].*$ ]]; then
fail "冒号后缺少空格。" "正确写法应为 ': '(英文冒号 + 1 个空格)。"
fi
if [[ "${first_line}" =~ ^[A-Za-z]+\([A-Za-z]+\):[[:space:]]{2,}.*$ ]]; then
fail "冒号后空格数量不正确(多于 1 个空格)。" "请确保冒号后严格是 1 个空格(': ')。"
fi
type=""
scope=""
subject=""
if [[ "${first_line}" =~ ^([A-Za-z]+)\(([A-Za-z]+)\):\ (.+)$ ]]; then
type="${BASH_REMATCH[1]}"
scope="${BASH_REMATCH[2]}"
subject="${BASH_REMATCH[3]}"
else
fail "格式不正确。" "请按 '<type>(<scope>): <subject>' 格式填写。"
fi
if [[ "${subject}" =~ ^[[:space:]] ]]; then
fail "冒号后的空格数量不正确(多于 1 个空格)。" "请确保冒号后严格是 1 个空格(': ')。"
fi
case "${type}" in
feat | fix | docs | style | refactor | perf | test | build | ci | chore | revert) ;;
*)
fail "type 不合法:${type}" "请使用允许的 type小写。"
;;
esac
case "${scope}" in
frontend | ast | sema | ir | irgen | mir | backend | antlr | build | test | doc | dev) ;;
*)
fail "scope 不合法:${scope}" "请使用允许的 scope严格限制。"
;;
esac
exit 0