代码检查脚本#
脚本说明#
代码检查脚本用于检查代码质量、格式、安全性等问题,支持多种编程语言。
脚本代码#
#!/bin/bash
# 代码检查脚本
# 功能:检查代码质量、格式、安全性等问题
# 作者:System Admin
# 日期:2024-01-01
set -euo pipefail
# 配置变量
PROJECT_DIR=""
CHECK_TYPE="all"
OUTPUT_FORMAT="text"
FIX_ISSUES=false
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 日志函数
log() {
local level=$1
shift
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $@"
}
log_info() {
log "INFO" "$@"
}
log_error() {
log "ERROR" "$@"
}
# 检查项目目录
check_project_dir() {
if [ ! -d "$PROJECT_DIR" ]; then
log_error "项目目录不存在: $PROJECT_DIR"
return 1
fi
return 0
}
# 检查Python代码
check_python() {
local dir=$1
log_info "检查Python代码: $dir"
echo "Python代码检查"
echo "=============="
# 检查pylint
if command -v pylint &> /dev/null; then
log_info "使用pylint检查"
find "$dir" -name "*.py" -exec pylint --output-format=text {} \;
fi
# 检查flake8
if command -v flake8 &> /dev/null; then
log_info "使用flake8检查"
find "$dir" -name "*.py" -exec flake8 {} \;
fi
# 检查black格式
if command -v black &> /dev/null; then
log_info "使用black检查格式"
if [ "$FIX_ISSUES" = true ]; then
find "$dir" -name "*.py" -exec black {} \;
else
find "$dir" -name "*.py" -exec black --check {} \;
fi
fi
# 检查mypy类型
if command -v mypy &> /dev/null; then
log_info "使用mypy检查类型"
find "$dir" -name "*.py" -exec mypy {} \;
fi
# 检查bandit安全
if command -v bandit &> /dev/null; then
log_info "使用bandit检查安全"
find "$dir" -name "*.py" -exec bandit -r {} \;
fi
}
# 检查JavaScript代码
check_javascript() {
local dir=$1
log_info "检查JavaScript代码: $dir"
echo "JavaScript代码检查"
echo "=================="
# 检查ESLint
if command -v eslint &> /dev/null; then
log_info "使用ESLint检查"
find "$dir" -name "*.js" -o -name "*.jsx" | xargs eslint
fi
# 检查Prettier格式
if command -v prettier &> /dev/null; then
log_info "使用Prettier检查格式"
if [ "$FIX_ISSUES" = true ]; then
find "$dir" -name "*.js" -o -name "*.jsx" | xargs prettier --write
else
find "$dir" -name "*.js" -o -name "*.jsx" | xargs prettier --check
fi
fi
}
# 检查TypeScript代码
check_typescript() {
local dir=$1
log_info "检查TypeScript代码: $dir"
echo "TypeScript代码检查"
echo "=================="
# 检查TSLint
if command -v tslint &> /dev/null; then
log_info "使用TSLint检查"
find "$dir" -name "*.ts" -o -name "*.tsx" | xargs tslint
fi
# 检查ESLint
if command -v eslint &> /dev/null; then
log_info "使用ESLint检查"
find "$dir" -name "*.ts" -o -name "*.tsx" | xargs eslint
fi
# 检查Prettier格式
if command -v prettier &> /dev/null; then
log_info "使用Prettier检查格式"
if [ "$FIX_ISSUES" = true ]; then
find "$dir" -name "*.ts" -o -name "*.tsx" | xargs prettier --write
else
find "$dir" -name "*.ts" -o -name "*.tsx" | xargs prettier --check
fi
fi
}
# 检查Go代码
check_go() {
local dir=$1
log_info "检查Go代码: $dir"
echo "Go代码检查"
echo "========="
# 检查gofmt格式
log_info "使用gofmt检查格式"
if [ "$FIX_ISSUES" = true ]; then
find "$dir" -name "*.go" -exec gofmt -w {} \;
else
find "$dir" -name "*.go" -exec gofmt -l {} \;
fi
# 检查go vet
log_info "使用go vet检查"
find "$dir" -name "*.go" -exec go vet {} \;
# 检查golint
if command -v golint &> /dev/null; then
log_info "使用golint检查"
find "$dir" -name "*.go" -exec golint {} \;
fi
# 检查goimports
if command -v goimports &> /dev/null; then
log_info "使用goimports检查"
if [ "$FIX_ISSUES" = true ]; then
find "$dir" -name "*.go" -exec goimports -w {} \;
else
find "$dir" -name "*.go" -exec goimports -l {} \;
fi
fi
}
# 检查Java代码
check_java() {
local dir=$1
log_info "检查Java代码: $dir"
echo "Java代码检查"
echo "==========="
# 检查Checkstyle
if command -v checkstyle &> /dev/null; then
log_info "使用Checkstyle检查"
find "$dir" -name "*.java" -exec checkstyle {} \;
fi
# 检查PMD
if command -v pmd &> /dev/null; then
log_info "使用PMD检查"
find "$dir" -name "*.java" -exec pmd {} \;
fi
# 检查SpotBugs
if command -v spotbugs &> /dev/null; then
log_info "使用SpotBugs检查"
find "$dir" -name "*.java" -exec spotbugs {} \;
fi
}
# 检查C/C++代码
check_cpp() {
local dir=$1
log_info "检查C/C++代码: $dir"
echo "C/C++代码检查"
echo "============="
# 检查clang-format格式
if command -v clang-format &> /dev/null; then
log_info "使用clang-format检查格式"
if [ "$FIX_ISSUES" = true ]; then
find "$dir" -name "*.c" -o -name "*.cpp" -o -name "*.h" -o -name "*.hpp" | xargs clang-format -i
else
find "$dir" -name "*.c" -o -name "*.cpp" -o -name "*.h" -o -name "*.hpp" | xargs clang-format --dry-run -Werror
fi
fi
# 检查cppcheck
if command -v cppcheck &> /dev/null; then
log_info "使用cppcheck检查"
find "$dir" -name "*.c" -o -name "*.cpp" | xargs cppcheck
fi
}
# 检查Shell脚本
check_shell() {
local dir=$1
log_info "检查Shell脚本: $dir"
echo "Shell脚本检查"
echo "============"
# 检查shellcheck
if command -v shellcheck &> /dev/null; then
log_info "使用shellcheck检查"
find "$dir" -name "*.sh" -exec shellcheck {} \;
fi
# 检查shfmt格式
if command -v shfmt &> /dev/null; then
log_info "使用shfmt检查格式"
if [ "$FIX_ISSUES" = true ]; then
find "$dir" -name "*.sh" -exec shfmt -w {} \;
else
find "$dir" -name "*.sh" -exec shfmt -d {} \;
fi
fi
}
# 检查代码复杂度
check_complexity() {
local dir=$1
log_info "检查代码复杂度: $dir"
echo "代码复杂度检查"
echo "============="
# 检查Python复杂度
if command -v radon &> /dev/null; then
log_info "使用radon检查Python复杂度"
find "$dir" -name "*.py" -exec radon cc {} \;
fi
# 检查Go复杂度
if command -v gocyclo &> /dev/null; then
log_info "使用gocyclo检查Go复杂度"
find "$dir" -name "*.go" -exec gocyclo {} \;
fi
}
# 检查代码重复
check_duplication() {
local dir=$1
log_info "检查代码重复: $dir"
echo "代码重复检查"
echo "============="
# 检查Python重复
if command -v pyflakes &> /dev/null; then
log_info "使用pyflakes检查Python重复"
find "$dir" -name "*.py" -exec pyflakes {} \;
fi
# 检查通用重复
if command -v jscpd &> /dev/null; then
log_info "使用jscpd检查代码重复"
jscpd "$dir"
fi
}
# 检查安全性
check_security() {
local dir=$1
log_info "检查安全性: $dir"
echo "安全性检查"
echo "========="
# 检查Python安全
if command -v bandit &> /dev/null; then
log_info "使用bandit检查Python安全"
find "$dir" -name "*.py" -exec bandit -r {} \;
fi
# 检查JavaScript安全
if command -v npm-audit &> /dev/null; then
log_info "使用npm-audit检查JavaScript安全"
cd "$dir" && npm audit
fi
# 检查依赖漏洞
if command -v safety &> /dev/null; then
log_info "使用safety检查Python依赖"
cd "$dir" && safety check
fi
}
# 生成检查报告
generate_report() {
local dir=$1
log_info "生成检查报告"
local report_file="/tmp/code_check_report_$(date +%Y%m%d_%H%M%S).txt"
{
echo "代码检查报告"
echo "==========="
echo "检查时间: $(date)"
echo "项目目录: $dir"
echo ""
echo "检查工具"
echo "========"
# 检查Python工具
if command -v pylint &> /dev/null; then
echo "pylint: $(pylint --version)"
fi
if command -v flake8 &> /dev/null; then
echo "flake8: $(flake8 --version)"
fi
if command -v black &> /dev/null; then
echo "black: $(black --version)"
fi
# 检查JavaScript工具
if command -v eslint &> /dev/null; then
echo "eslint: $(eslint --version)"
fi
if command -v prettier &> /dev/null; then
echo "prettier: $(prettier --version)"
fi
# 检查Go工具
if command -v gofmt &> /dev/null; then
echo "gofmt: $(gofmt --version)"
fi
# 检查Shell工具
if command -v shellcheck &> /dev/null; then
echo "shellcheck: $(shellcheck --version)"
fi
echo ""
echo "报告生成时间: $(date)"
} > "$report_file"
log_info "检查报告已生成: $report_file"
}
# 显示帮助
show_help() {
echo "用法: $0 [选项] <项目目录>"
echo ""
echo "选项:"
echo " -t <类型> 检查类型(all/python/javascript/typescript/go/java/cpp/shell/complexity/duplication/security)"
echo " -f 自动修复问题"
echo " -h 显示帮助信息"
echo ""
echo "示例:"
echo " $0 /path/to/project"
echo " $0 -t python /path/to/project"
echo " $0 -t javascript /path/to/project"
echo " $0 -f /path/to/project"
}
# 主函数
main() {
# 解析选项
while getopts "t:fh" opt; do
case $opt in
t)
CHECK_TYPE="$OPTARG"
log_info "检查类型: $CHECK_TYPE"
;;
f)
FIX_ISSUES=true
log_info "自动修复问题"
;;
h)
show_help
exit 0
;;
*)
log_error "无效选项: $opt"
show_help
exit 1
;;
esac
done
shift $((OPTIND - 1))
# 检查项目目录
if [ $# -eq 0 ]; then
log_error "缺少项目目录"
show_help
exit 1
fi
PROJECT_DIR="$1"
if ! check_project_dir; then
exit 1
fi
# 执行检查
case $CHECK_TYPE in
all)
check_python "$PROJECT_DIR"
check_javascript "$PROJECT_DIR"
check_typescript "$PROJECT_DIR"
check_go "$PROJECT_DIR"
check_java "$PROJECT_DIR"
check_cpp "$PROJECT_DIR"
check_shell "$PROJECT_DIR"
check_complexity "$PROJECT_DIR"
check_duplication "$PROJECT_DIR"
check_security "$PROJECT_DIR"
;;
python)
check_python "$PROJECT_DIR"
;;
javascript)
check_javascript "$PROJECT_DIR"
;;
typescript)
check_typescript "$PROJECT_DIR"
;;
go)
check_go "$PROJECT_DIR"
;;
java)
check_java "$PROJECT_DIR"
;;
cpp)
check_cpp "$PROJECT_DIR"
;;
shell)
check_shell "$PROJECT_DIR"
;;
complexity)
check_complexity "$PROJECT_DIR"
;;
duplication)
check_duplication "$PROJECT_DIR"
;;
security)
check_security "$PROJECT_DIR"
;;
*)
log_error "无效的检查类型: $CHECK_TYPE"
show_help
exit 1
;;
esac
# 生成报告
generate_report "$PROJECT_DIR"
log_info "代码检查完成"
}
# 执行主函数
main "$@"使用说明#
添加执行权限:
chmod +x code_checker.sh基本用法:
# 检查所有代码 ./code_checker.sh /path/to/project # 检查Python代码 ./code_checker.sh -t python /path/to/project # 检查JavaScript代码 ./code_checker.sh -t javascript /path/to/project # 检查Go代码 ./code_checker.sh -t go /path/to/project高级用法:
# 自动修复问题 ./code_checker.sh -f /path/to/project # 检查代码复杂度 ./code_checker.sh -t complexity /path/to/project # 检查安全性 ./code_checker.sh -t security /path/to/project
功能特点#
- 多语言支持(Python、JavaScript、TypeScript、Go、Java、C/C++、Shell)
- 代码质量检查
- 代码格式检查
- 代码复杂度检查
- 代码重复检查
- 安全性检查
- 自动修复功能
依赖项#
- pylint/flake8/black/mypy/bandit: Python检查工具
- eslint/prettier: JavaScript/TypeScript检查工具
- gofmt/golint/goimports: Go检查工具
- checkstyle/pmd/spotbugs: Java检查工具
- clang-format/cppcheck: C/C++检查工具
- shellcheck/shfmt: Shell检查工具
注意事项#
- 需要安装相应的检查工具
- 自动修复功能可能改变代码
- 建议在版本控制下使用
- 大项目检查可能需要较长时间
- 某些工具需要配置文件