Git钩子脚本如何检查持续改进

wen 实用脚本 1

本文目录导读:

Git钩子脚本如何检查持续改进

  1. 代码质量检查(pre-commit)
  2. 性能与改进检测(pre-push)
  3. 测试覆盖率检查(post-checkout/commit)
  4. 安全与规范检查(pre-receive - 服务端)
  5. 智能改进建议(commit-msg)
  6. 部署改进监控(post-receive)
  7. 最佳实践集成脚本
  8. 使用建议

Git 钩子脚本可以通过检查代码质量、运行测试和验证规范来推动持续改进,以下是几种常见场景的实现方法和示例脚本:

代码质量检查(pre-commit)

#!/bin/bash
# .git/hooks/pre-commit
echo "🔍 运行代码质量检查..."
# 设置错误标志
ERROR=0
# 1. 检查暂存区中的修改文件
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
# 2. 对不同的文件类型运行不同的检查
for FILE in $STAGED_FILES; do
    if [[ $FILE == *.py ]]; then
        # Python文件检查
        if ! flake8 "$FILE" 2>/dev/null; then
            echo "❌ Python语法/风格问题: $FILE"
            ERROR=1
        fi
        if ! pylint "$FILE" --exit-zero 2>/dev/null; then
            echo "⚠️ Python代码改进建议: $FILE"
        fi
    elif [[ $FILE == *.js || $FILE == *.ts ]]; then
        # JavaScript/TypeScript检查
        if ! eslint "$FILE" --quiet 2>/dev/null; then
            echo "❌ JavaScript问题: $FILE"
            ERROR=1
        fi
    elif [[ $FILE == *.md ]]; then
        # Markdown检查
        if ! markdownlint "$FILE" 2>/dev/null; then
            echo "⚠️ Markdown格式可以改进: $FILE"
        fi
    fi
    # 检查文件大小是否合理
    SIZE=$(wc -c < "$FILE")
    if [ $SIZE -gt 100000 ]; then
        echo "⚠️ 文件过大 (>100KB): $FILE (${SIZE}字节)"
        echo "建议拆分或优化"
    fi
done
# 3. 检查是否包含调试代码
if grep -r "console.log\|debugger\|TODO\|FIXME\|HACK" --include="*.js" --include="*.py" . 2>/dev/null; then
    echo "⚠️ 发现调试代码或待办事项"
    ERROR=1
fi
if [ $ERROR -ne 0 ]; then
    echo "❌ 提交被阻止,请修复上述问题"
    exit 1
fi
echo "✅ 代码质量检查通过"

性能与改进检测(pre-push)

#!/bin/bash
# .git/hooks/pre-push
echo "📊 运行性能与持续改进检查..."
# 获取将要推送的分支信息
while read local_ref local_sha remote_ref remote_sha; do
    if [ "$local_sha" = "0000000000000000000000000000000000000000" ]; then
        echo "删除分支,跳过检查"
        continue
    fi
    # 获取变更文件
    CHANGED_FILES=$(git diff --name-only "$remote_sha".."$local_sha")
    # 1. 检查重复代码(使用jscpd或其他工具)
    if command -v jscpd &> /dev/null; then
        DUPLICATES=$(jscpd --min-lines 5 --min-tokens 50 "$CHANGED_FILES" 2>/dev/null)
        if [ -n "$DUPLICATES" ]; then
            echo "❌ 发现重复代码:"
            echo "$DUPLICATES"
            exit 1
        fi
    fi
    # 2. 检查复杂度过高
    for FILE in $CHANGED_FILES; do
        if [[ $FILE == *.py ]]; then
            COMPLEXITY=$(radon cc "$FILE" -s 2>/dev/null | grep -oP '\([0-9]+\)' | grep -oP '[0-9]+')
            if [ -n "$COMPLEXITY" ] && [ "$COMPLEXITY" -gt 15 ]; then
                echo "⚠️ 代码复杂度高 ($COMPLEXITY): $FILE"
                echo "建议重构以提高可维护性"
            fi
        fi
    done
done
echo "✅ 性能检查通过"
exit 0

测试覆盖率检查(post-checkout/commit)

#!/bin/bash
# .git/hooks/post-commit
echo "📈 记录持续改进指标..."
# 获取当前分支名
BRANCH=$(git rev-parse --abbrev-ref HEAD)
# 记录提交统计
COMMIT_HASH=$(git rev-parse HEAD)
COMMIT_MESSAGE=$(git log -1 --pretty=%B)
DIFF_STATS=$(git diff --shortstat HEAD~1 HEAD 2>/dev/null)
# 计算代码变更指标
ADDED_LINES=$(echo "$DIFF_STATS" | grep -oP '\d+(?= insertion)' | head -1)
DELETED_LINES=$(echo "$DIFF_STATS" | grep -oP '\d+(?= deletion)' | head -1)
# 记录到改进日志
LOG_FILE=".git/improvement-log.json"
if [ ! -f "$LOG_FILE" ]; then
    echo "[]" > "$LOG_FILE"
fi
# 更新改进日志
python3 -c "
import json, datetime
with open('$LOG_FILE', 'r') as f:
    log = json.load(f)
log.append({
    'timestamp': datetime.datetime.now().isoformat(),
    'branch': '$BRANCH',
    'hash': '$COMMIT_HASH',
    'message': '''$COMMIT_MESSAGE''',
    'added_lines': ${ADDED_LINES:-0},
    'deleted_lines': ${DELETED_LINES:-0},
    'net_change': $((${ADDED_LINES:-0} - ${DELETED_LINES:-0}))
})
with open('$LOG_FILE', 'w') as f:
    json.dump(log, f, indent=2)
"
# 显示改进统计
echo "📊 本周改进统计:"
python3 -c "
import json
with open('$LOG_FILE', 'r') as f:
    log = json.load(f)
total_added = sum([x['added_lines'] for x in log])
total_deleted = sum([x['deleted_lines'] for x in log])
print(f'新增代码行数: {total_added}')
print(f'删除代码行数: {total_deleted}')
print(f'净改进: {total_added - total_deleted}行')
"

安全与规范检查(pre-receive - 服务端)

#!/bin/bash
# .git/hooks/pre-receive (部署在远程仓库)
echo "🔒 服务端安全检查..."
while read oldrev newrev refname; do
    # 跳过创建删除操作
    if [ "$oldrev" = "0000000000000000000000000000000000000000" ] || \
       [ "$newrev" = "0000000000000000000000000000000000000000" ]; then
        continue
    fi
    # 获取变更文件
    FILES=$(git diff --name-only "$oldrev".."$newrev")
    # 1. 检查敏感信息
    if echo "$FILES" | grep -E "\.env|password|secret|key|token" | grep -v "\.example" > /dev/null; then
        echo "❌ 禁止提交包含敏感信息的文件!"
        exit 1
    fi
    # 2. 检查二进制文件
    for FILE in $FILES; do
        if git show "$newrev:$FILE" | file - | grep -q "binary"; then
            echo "❌ 禁止提交二进制文件: $FILE"
            exit 1
        fi
    done
    # 3. 检查许可证合规
    if echo "$COMMIT_MESSAGE" | grep -qiE "\b(agpl|gpl|lgpl)\b"; then
        echo "⚠️ 提交包含GPL许可证,请确认兼容性"
    fi
done
echo "✅ 安全与规范检查通过"
exit 0

智能改进建议(commit-msg)

#!/bin/bash
# .git/hooks/commit-msg
echo "💡 提交信息改进建议..."
COMMIT_MSG_FILE="$1"
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
# 1. 检查提交信息格式
if ! echo "$COMMIT_MSG" | grep -qE "^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .+"; then
    echo "⚠️ 建议使用 Conventional Commits 格式:"
    echo "   feat: 新功能"
    echo "   fix: 修复Bug"
    echo "   docs: 文档更新"
    echo "   refactor: 重构"
    echo "   test: 测试相关"
    echo "   chore: 日常维护"
fi
# 2. 检查提交信息长度
HEADER_LENGTH=${#COMMIT_MSG}
if [ $HEADER_LENGTH -gt 72 ]; then
    echo "⚠️ 提交信息超过72字符(当前${HEADER_LENGTH}字符)"
    echo "建议缩短以提高可读性"
fi
# 3. 检查是否包含引用号
if echo "$COMMIT_MSG" | grep -qE "close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved"; then
    ISSUE_NUM=$(echo "$COMMIT_MSG" | grep -oP '#\d+')
    if [ -n "$ISSUE_NUM" ]; then
        echo "✅ 关联到问题: $ISSUE_NUM"
    fi
fi
exit 0

部署改进监控(post-receive)

#!/bin/bash
# .git/hooks/post-receive
echo "🚀 部署后改进监控..."
while read oldrev newrev refname; do
    # 记录部署事件
    DEPLOY_LOG="/var/log/deploy-improvements.log"
    echo "[$(date)] 部署更新:$refname" >> "$DEPLOY_LOG"
    # 触发CI/CD检查
    curl -X POST "https://ci.example.com/api/trigger" \
         -H "Authorization: Bearer $CI_TOKEN" \
         -d "branch=${refname##refs/heads/}&commit=$newrev"
    # 记录性能指标
    if [ -f "package.json" ]; then
        npm test -- --coverage 2>/dev/null || true
    fi
    # 部署后健康检查
    sleep 10
    if curl -f "https://app.example.com/health"; then
        echo "✅ 应用健康检查通过"
    else
        echo "⚠️ 应用健康检查失败,可能需要回滚"
        # 可以在这里添加自动回滚逻辑
    fi
done
echo "✅ 部署监控启动"

最佳实践集成脚本

创建一个统一的改进检查脚本:

#!/bin/bash
# .git/hooks/ci-improvement.sh
set -e
echo "🔄 运行持续改进检查..."
# 配置
MAX_COMPLEXITY=10
MAX_FILE_SIZE=100000  # 字节
MIN_COVERAGE=80       # 百分比
REQUIRED_FILES=("README.md" ".gitignore" "package.json")
# 1. 代码风格改进
improve_style() {
    echo "1. 检查代码风格..."
    if command -v prettier &> /dev/null; then
        npx prettier --check "src/**/*.{js,ts,json,css}" 2>/dev/null
    fi
    if command -v black &> /dev/null; then
        black --check --diff "**/*.py" 2>/dev/null
    fi
}
# 2. 技术债务追踪
track_debt() {
    echo "2. 追踪技术债务..."
    # 查找TODO注释
    TODO_COUNT=$(grep -r "TODO\|FIXME\|HACK\|XXX" --include="*.py" --include="*.js" . | wc -l)
    echo "   当前待办事项: $TODO_COUNT"
    # 记录到债务日志
    echo "{\"date\":\"$(date +%Y-%m-%d)\",\"todos\":$TODO_COUNT}" >> .tech-debt.json
}
# 3. 依赖更新建议
check_dependencies() {
    echo "3. 检查依赖更新..."
    if [ -f "package.json" ]; then
        OUTDATED=$(npm outdated --json 2>/dev/null || echo "{}")
        if [ "$OUTDATED" != "{}" ]; then
            echo "   发现过时的依赖包:"
            echo "$OUTDATED" | python3 -c "
import json, sys
data = json.load(sys.stdin)
for pkg, info in data.get('package.json', data).items():
    print(f'   - {pkg}: {info[\"current\"]} -> {info[\"wanted\"]}')
"
        fi
    fi
}
# 4. 生成改进报告
generate_report() {
    echo "4. 生成改进报告..."
    REPORT_FILE=".improvement-report-$(date +%Y%m%d).md"
    cat > "$REPORT_FILE" << EOF
# 持续改进报告
日期: $(date)
## 检查结果
### 代码质量
- 风格检查: ✅
- 复杂度检查: ✅
- 重复代码检查: ✅
### 测试覆盖
- 当前覆盖率: 需要运行测试获取
- 目标覆盖率: ${MIN_COVERAGE}%
### 技术债务
- TODO/FIXME数量: $(grep -r "TODO\|FIXME" --include="*.py" --include="*.js" . | wc -l)
- 待重构代码: 待分析
### 建议
1. 请定期更新依赖包
2. 考虑重构复杂度高的函数
3. 补充必要的文档和测试
EOF
    echo "报告已生成: $REPORT_FILE"
}
# 主流程
improve_style
track_debt
check_dependencies
generate_report
echo "✅ 持续改进检查完成"

使用建议

  1. 启用hooks

    chmod +x .git/hooks/*
    git config core.hooksPath .git/hooks
  2. 配置改进阈值

    # 创建配置文件
    cat > .githooks-config.json << EOF
    {
    "max_complexity": 10,
    "min_coverage": 80,
    "block_on_warnings": false,
    "enabled_checks": ["style", "security", "complexity"]
    }
    EOF
  3. 集成到CI/CD

    # .gitlab-ci.yml
    improvement_check:
    script:
     - .git/hooks/ci-improvement.sh
    artifacts:
     paths:
       - .improvement-report-*.md

这些钩子脚本可以帮助团队:

  • 自动发现代码质量问题
  • 跟踪技术债务
  • 推动持续改进
  • 建立代码规范
  • 提高代码质量

记得根据团队具体需求调整脚本,避免过于严格的检查影响开发效率。

抱歉,评论功能暂时关闭!