#!/bin/bash # 自动运行代码质量检查 # 显示使用说明 show_usage() { echo "用法: $0 [选项] [文件或目录...]" echo "选项:" echo " -a, --all 检查所有文件" echo " -g, --git [默认] 只检查git相关的文件(已修改、已暂存、未跟踪)" echo " -f, --file FILE 指定要检查的特定文件" echo " -d, --dir DIR 指定要检查的目录" echo " --help 显示此帮助信息" echo "" echo "示例:" echo " $0 # 检查所有git相关文件(默认)" echo " $0 -f file1.go -f file2.py # 检查指定文件" echo " $0 -d src/ -d tests/ # 检查指定目录" echo " $0 file1.go src/ tests/ # 混合指定文件和目录" } # 默认模式:检查git相关文件 MODE="git" # 解析命令行参数 declare -a USER_FILES_ARRAY=() while [[ $# -gt 0 ]]; do case $1 in -a | --all) MODE="all" shift ;; -g | --git) MODE="git" shift ;; -f | --file) MODE="file" if [ -f "$2" ]; then USER_FILES_ARRAY+=("$2") else echo "警告:文件 '$2' 不存在,跳过" fi shift 2 ;; -d | --dir) MODE="dir" if [ -d "$2" ]; then # 查找目录下的所有文件并添加到数组 while IFS= read -r file; do [ -n "${file}" ] && [[ ${file} != */.* ]] && [[ ${file} != .* ]] && USER_FILES_ARRAY+=("${file}") done < <(find "$2" -type f 2>/dev/null | grep -v '/\.' || true) else echo "警告:目录 '$2' 不存在,跳过" fi shift 2 ;; --help) show_usage exit 0 ;; -*) echo "错误:未知选项 '$1'" show_usage exit 1 ;; *) # 处理直接指定的文件或目录 MODE="处理直接指定的文件或目录" if [ -f "$1" ]; then USER_FILES_ARRAY+=("$1") elif [ -d "$1" ]; then # 查找目录下的所有文件并添加到数组 while IFS= read -r file; do [ -n "${file}" ] && [[ ${file} != */.* ]] && [[ ${file} != .* ]] && USER_FILES_ARRAY+=("${file}") done < <(find "$1" -type f 2>/dev/null | grep -v '/\.' || true) else echo "警告:'$1' 不是文件或目录,跳过" fi shift ;; esac done # 将数组转换为换行分隔的字符串 if [ ${#USER_FILES_ARRAY[@]} -gt 0 ]; then USER_FILES=$(printf "%s\n" "${USER_FILES_ARRAY[@]}") else USER_FILES="" fi echo "" echo "🚀 正在运行代码质量检查..." echo "========================================" echo "模式: ${MODE}" # 切换到工作目录 cd /workspace || exit # 检查trunk工具是否可用 if ! command -v ./trunk &>/dev/null; then echo "❌ trunk工具未找到,请确保已正确安装" exit 1 fi # 根据模式获取需要检查的文件 if [ "${MODE}" = "all" ]; then # 检查所有文件 ALL_FILES=$(find . -type f 2>/dev/null | grep -v '/\.' | grep -v '^/\.' | sort | uniq || true) elif [ -n "${USER_FILES}" ]; then # 使用用户指定的文件 ALL_FILES="${USER_FILES}" else # 默认:检查git相关文件 STAGED_FILES=$(git diff --name-only --diff-filter=d 2>/dev/null || true) NEW_FILES=$(git diff --cached --name-only --diff-filter=A 2>/dev/null || true) UNTRACKED_FILES=$(git ls-files --others --exclude-standard 2>/dev/null || true) # 使用数组安全地合并文件列表 declare -a ALL_FILES_ARRAY=() # 添加已修改的文件 if [ -n "${STAGED_FILES}" ]; then while IFS= read -r file; do [ -n "${file}" ] && [[ ${file} != */.* ]] && [[ ${file} != .* ]] && ALL_FILES_ARRAY+=("${file}") done <<<"${STAGED_FILES}" fi # 添加新暂存的文件 if [ -n "${NEW_FILES}" ]; then while IFS= read -r file; do [ -n "${file}" ] && [[ ${file} != */.* ]] && [[ ${file} != .* ]] && ALL_FILES_ARRAY+=("${file}") done <<<"${NEW_FILES}" fi # 添加未跟踪的文件 if [ -n "${UNTRACKED_FILES}" ]; then while IFS= read -r file; do [ -n "${file}" ] && [[ ${file} != */.* ]] && [[ ${file} != .* ]] && ALL_FILES_ARRAY+=("${file}") done <<<"${UNTRACKED_FILES}" fi # 去重并生成最终文件列表 if [ ${#ALL_FILES_ARRAY[@]} -gt 0 ]; then ALL_FILES=$(printf "%s\n" "${ALL_FILES_ARRAY[@]}" | sort | uniq || true) else ALL_FILES="" fi fi # 去重并过滤空行和隐藏文件(仅在all模式下过滤隐藏文件) if [ "${MODE}" = "all" ] || [ -n "${USER_FILES}" ]; then # 始终过滤空行并去重 ALL_FILES=$(echo "${ALL_FILES}" | grep -v '^$' | sort | uniq || true) # 仅在all模式下过滤隐藏文件(用户明确指定文件时不过滤) if [ "${MODE}" = "all" ]; then ALL_FILES=$(echo "${ALL_FILES}" | grep -v '/\.' | grep -v '^/\.' || true) fi fi if [ -z "${ALL_FILES}" ]; then echo "ℹ️ 没有找到需要检查的文件" exit 0 fi # 检查文件数量 FILE_COUNT=$(echo "${ALL_FILES}" | wc -l) echo "" echo "📊 共发现 ${FILE_COUNT} 个需要检查的文件:" echo "${ALL_FILES}" echo "" # 运行trunk check检查代码质量 echo "" echo "🔍 正在运行代码质量检查..." if ! ./trunk check ${ALL_FILES}; then echo "" echo "❌ 代码质量检查失败!" echo "" echo "请修复上述问题后再提交" echo "" exit 1 fi # 检查安全漏洞 echo "" echo "🔒 正在检查安全漏洞..." if ! ./trunk check --filter=trivy ${ALL_FILES}; then echo "" echo "⚠️ 发现安全相关问题,建议检查后再推送" echo "" exit 1 fi echo "" echo "✅ 代码质量检查通过!可以安全提交。" echo "========================================" echo "" exit 0