update-changelog-prepare.sh 3.59 KB
#!/bin/bash

# ============================================
# CHANGELOG 自动更新脚本(Prepare-commit-msg 版本)
# ============================================
#
# 功能:在 prepare-commit-msg 阶段更新 CHANGELOG.md,加入暂存区
# 配合 post-commit 的 amend --no-verify 完成流程
#
# 作者:Claude Code
# 日期:2026-02-28
# ============================================

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 参数
COMMIT_MSG_FILE=$1
CHANGELOG_FILE="CHANGELOG.md"

# 检查文件是否存在
if [ ! -f "$CHANGELOG_FILE" ]; then
    echo "  ${YELLOW}⚠️  CHANGELOG.md 不存在,跳过自动更新${NC}"
    exit 0
fi

# 读取 commit message
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")

# 解析 commit message
# 格式: type(scope): subject
if ! echo "$COMMIT_MSG" | grep -qE "^([a-z]+)\(([a-z-]+)\): .{1,50}"; then
    # 格式不匹配,跳过
    exit 0
fi

# 提取信息
COMMIT_TYPE=$(echo "$COMMIT_MSG" | head -n 1 | sed -E 's/^([a-z]+)\(.*/\1/')
COMMIT_SCOPE=$(echo "$COMMIT_MSG" | head -n 1 | sed -E 's/^[a-z]+\(([a-z-]+)\).*/\1/')
COMMIT_SUBJECT=$(echo "$COMMIT_MSG" | head -n 1 | sed -E 's/^[a-z]+\([a-z-]+\): (.*)$/\1/')

# 类型映射到中文
case "$COMMIT_TYPE" in
    feat)
        CHANGE_TYPE="新增"
        ;;
    fix)
        CHANGE_TYPE="修复"
        ;;
    docs)
        CHANGE_TYPE="文档"
        ;;
    style)
        CHANGE_TYPE="样式"
        ;;
    refactor)
        CHANGE_TYPE="优化"
        ;;
    perf)
        CHANGE_TYPE="性能"
        ;;
    test)
        CHANGE_TYPE="测试"
        ;;
    chore)
        CHANGE_TYPE="配置"
        ;;
    revert)
        CHANGE_TYPE="回滚"
        ;;
    *)
        CHANGE_TYPE="其他"
        ;;
esac

# 获取当前日期和时间
TODAY=$(date +%Y-%m-%d)
NOW_TIME=$(date +%H:%M:%S)

# 获取暂存的变更文件(使用 git diff --cached)
CHANGED_FILES=$(git diff --cached --name-only | tr '\n' '\n' | sed 's/^/- \`/;s/$/`/' | sed '$d')
if [ -z "$CHANGED_FILES" ]; then
    CHANGED_FILES="- \`\`"
fi

# 生成 CHANGELOG 条目
CHANGELOG_ENTRY="### $NOW_TIME - $COMMIT_TYPE($COMMIT_SCOPE): $COMMIT_SUBJECT

**影响文件**:
$CHANGED_FILES

**变更摘要**:
- $COMMIT_SUBJECT

---

"

# 检查今天是否已有条目
if grep -q "^## $TODAY" "$CHANGELOG_FILE"; then
    # 今天已有条目,找到日期行号,在日期后追加
    DATE_LINE=$(grep -n "^## $TODAY" "$CHANGELOG_FILE" | head -1 | cut -d: -f1)

    # 创建临时文件
    TEMP_FILE=$(mktemp)

    # 读取日期行之前的内容
    head -n $DATE_LINE "$CHANGELOG_FILE" > "$TEMP_FILE"

    # 在日期后追加新条目
    echo "$CHANGELOG_ENTRY" >> "$TEMP_FILE"

    # 追加日期行之后的内容(从日期行+1开始)
    tail -n +$((DATE_LINE + 1)) "$CHANGELOG_FILE" >> "$TEMP_FILE"

    # 替换原文件
    mv "$TEMP_FILE" "$CHANGELOG_FILE"
else
    # 今天没有条目,创建新的日期部分
    TEMP_FILE=$(mktemp)

    # 新建日期标题和条目
    echo "## $TODAY" > "$TEMP_FILE"
    echo "" >> "$TEMP_FILE"
    echo "$CHANGELOG_ENTRY" >> "$TEMP_FILE"
    echo "" >> "$TEMP_FILE"

    # 追加原文件内容
    cat "$CHANGELOG_FILE" >> "$TEMP_FILE"

    # 替换原文件
    mv "$TEMP_FILE" "$CHANGELOG_FILE"
fi

# 将 CHANGELOG.md 加入暂存区
# 重要:这里只是加入暂存区,实际包含在提交中由 post-commit 的 amend 完成
git add "$CHANGELOG_FILE"

echo "  ${GREEN}✅ CHANGELOG.md 已自动更新${NC}"
echo "  ${BLUE}   类型: $CHANGE_TYPE${NC}"
echo "  ${BLUE}   范围: $COMMIT_SCOPE${NC}"
echo "  ${BLUE}   描述: $COMMIT_SUBJECT${NC}"