#!/bin/bash # 项目重构脚本 - 自动化修改包名、groupId、artifactId # Author: Leocoder # Version: 1.0 # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' WHITE='\033[1;37m' NC='\033[0m' # No Color # 全局变量 PROJECT_DIR="" OLD_GROUP_ID="" NEW_GROUP_ID="" OLD_ARTIFACT_ID="" NEW_ARTIFACT_ID="" OLD_PACKAGE="" NEW_PACKAGE="" OLD_MODULE_PREFIX="" NEW_MODULE_PREFIX="" OLD_DATABASE_NAME="" NEW_DATABASE_NAME="" # 打印banner print_banner() { echo -e "${CYAN}" echo "╔══════════════════════════════════════════════════════════════════════════════╗" echo "║ 项目重构自动化脚本 ║" echo "║ Project Refactoring Tool ║" echo "║ Version 1.0 ║" echo "╚══════════════════════════════════════════════════════════════════════════════╝" echo -e "${NC}" } # 打印步骤标题 print_step() { echo -e "${BLUE}════════════════════════════════════════════════════════════════════════════════${NC}" echo -e "${WHITE}$1${NC}" echo -e "${BLUE}════════════════════════════════════════════════════════════════════════════════${NC}" } # 打印成功信息 print_success() { echo -e "${GREEN}✓ $1${NC}" } # 打印警告信息 print_warning() { echo -e "${YELLOW}⚠ $1${NC}" } # 打印错误信息 print_error() { echo -e "${RED}✗ $1${NC}" } # 打印信息 print_info() { echo -e "${PURPLE}ℹ $1${NC}" } # 验证输入 validate_input() { local input="$1" local pattern="$2" local description="$3" if [[ ! "$input" =~ $pattern ]]; then print_error "$description 格式不正确: $input" return 1 fi return 0 } # 获取用户输入 get_user_input() { print_step "步骤 1: 获取重构参数" # 获取项目根目录 echo -e "${CYAN}请输入项目根目录路径 (默认: 当前目录):${NC}" read -p "项目路径: " PROJECT_DIR if [ -z "$PROJECT_DIR" ]; then PROJECT_DIR="$(pwd)" fi # 检查项目目录是否存在 if [ ! -d "$PROJECT_DIR" ]; then print_error "项目目录不存在: $PROJECT_DIR" exit 1 fi # 检查是否是Maven项目 if [ ! -f "$PROJECT_DIR/pom.xml" ]; then print_error "这不是一个Maven项目 (未找到pom.xml)" exit 1 fi print_success "项目目录: $PROJECT_DIR" echo "" echo -e "${CYAN}请输入旧的配置信息:${NC}" # 获取旧的groupId read -p "旧的 GroupId (例如: org.leocoder.thin): " OLD_GROUP_ID validate_input "$OLD_GROUP_ID" "^[a-zA-Z][a-zA-Z0-9_]*(\.[a-zA-Z][a-zA-Z0-9_]*)*$" "GroupId" if [ $? -ne 0 ]; then exit 1; fi # 获取旧的artifactId read -p "旧的 ArtifactId (例如: coder-common-thin-backend): " OLD_ARTIFACT_ID validate_input "$OLD_ARTIFACT_ID" "^[a-zA-Z][a-zA-Z0-9_-]*$" "ArtifactId" if [ $? -ne 0 ]; then exit 1; fi # 获取旧的模块前缀 read -p "旧的模块前缀 (例如: coder-common-thin): " OLD_MODULE_PREFIX validate_input "$OLD_MODULE_PREFIX" "^[a-zA-Z][a-zA-Z0-9_-]*$" "模块前缀" if [ $? -ne 0 ]; then exit 1; fi echo "" echo -e "${CYAN}请输入新的配置信息:${NC}" # 获取新的groupId read -p "新的 GroupId (例如: org.leocoder.course): " NEW_GROUP_ID validate_input "$NEW_GROUP_ID" "^[a-zA-Z][a-zA-Z0-9_]*(\.[a-zA-Z][a-zA-Z0-9_]*)*$" "GroupId" if [ $? -ne 0 ]; then exit 1; fi # 获取新的artifactId read -p "新的 ArtifactId (例如: coder-course-backend): " NEW_ARTIFACT_ID validate_input "$NEW_ARTIFACT_ID" "^[a-zA-Z][a-zA-Z0-9_-]*$" "ArtifactId" if [ $? -ne 0 ]; then exit 1; fi # 获取新的模块前缀 read -p "新的模块前缀 (例如: coder-course): " NEW_MODULE_PREFIX validate_input "$NEW_MODULE_PREFIX" "^[a-zA-Z][a-zA-Z0-9_-]*$" "模块前缀" if [ $? -ne 0 ]; then exit 1; fi # 获取数据库名称(可选) echo "" echo -e "${CYAN}数据库配置 (可选):${NC}" read -p "旧的数据库名称 (留空跳过): " OLD_DATABASE_NAME if [ -n "$OLD_DATABASE_NAME" ]; then read -p "新的数据库名称: " NEW_DATABASE_NAME if [ -z "$NEW_DATABASE_NAME" ]; then print_warning "新数据库名称为空,将跳过数据库配置修改" OLD_DATABASE_NAME="" fi fi # 设置包名 OLD_PACKAGE="$OLD_GROUP_ID" NEW_PACKAGE="$NEW_GROUP_ID" } # 显示配置摘要 show_summary() { print_step "步骤 2: 配置摘要" echo -e "${WHITE}重构配置摘要:${NC}" echo -e "${CYAN}项目目录:${NC} $PROJECT_DIR" echo -e "${CYAN}旧 GroupId:${NC} $OLD_GROUP_ID" echo -e "${CYAN}新 GroupId:${NC} $NEW_GROUP_ID" echo -e "${CYAN}旧 ArtifactId:${NC} $OLD_ARTIFACT_ID" echo -e "${CYAN}新 ArtifactId:${NC} $NEW_ARTIFACT_ID" echo -e "${CYAN}旧模块前缀:${NC} $OLD_MODULE_PREFIX" echo -e "${CYAN}新模块前缀:${NC} $NEW_MODULE_PREFIX" echo -e "${CYAN}旧包名:${NC} $OLD_PACKAGE" echo -e "${CYAN}新包名:${NC} $NEW_PACKAGE" if [ -n "$OLD_DATABASE_NAME" ]; then echo -e "${CYAN}旧数据库名:${NC} $OLD_DATABASE_NAME" echo -e "${CYAN}新数据库名:${NC} $NEW_DATABASE_NAME" fi echo "" echo -e "${YELLOW}警告: 此操作将修改项目中的所有相关文件,建议先备份项目!${NC}" echo "" read -p "是否继续? (y/N): " confirm if [[ ! "$confirm" =~ ^[Yy]$ ]]; then print_info "操作已取消" exit 0 fi } # 备份项目 backup_project() { print_step "步骤 3: 备份项目" local backup_dir="${PROJECT_DIR}_backup_$(date +%Y%m%d_%H%M%S)" echo -e "${CYAN}是否创建项目备份?${NC}" read -p "创建备份到 $backup_dir (Y/n): " create_backup if [[ "$create_backup" =~ ^[Nn]$ ]]; then print_warning "跳过备份步骤" return fi print_info "正在创建备份..." cp -r "$PROJECT_DIR" "$backup_dir" if [ $? -eq 0 ]; then print_success "备份创建成功: $backup_dir" else print_error "备份创建失败" exit 1 fi } # 修改POM文件 update_pom_files() { print_step "步骤 4: 修改 POM 文件" local pom_files=$(find "$PROJECT_DIR" -name "pom.xml" -type f) local count=0 for pom_file in $pom_files; do print_info "处理: $(basename $(dirname $pom_file))/pom.xml" # 创建临时文件 local temp_file=$(mktemp) # 修改groupId和artifactId sed "s|$OLD_GROUP_ID|$NEW_GROUP_ID|g" "$pom_file" | \ sed "s|$OLD_ARTIFACT_ID|$NEW_ARTIFACT_ID|g" | \ sed "s|$OLD_ARTIFACT_ID|$NEW_ARTIFACT_ID|g" | \ sed "s|$OLD_MODULE_PREFIX-|$NEW_MODULE_PREFIX-|g" | \ sed "s|$OLD_MODULE_PREFIX-|$NEW_MODULE_PREFIX-|g" | \ sed "s|$OLD_MODULE_PREFIX-|$NEW_MODULE_PREFIX-|g" > "$temp_file" # 替换原文件 mv "$temp_file" "$pom_file" ((count++)) done print_success "已修改 $count 个 POM 文件" } # 修改Java文件包名 update_java_packages() { print_step "步骤 5: 修改 Java 包名" local java_files=$(find "$PROJECT_DIR" -name "*.java" -type f) local count=0 # 转换包名格式(用于文件内容替换) local old_package_escaped=$(echo "$OLD_PACKAGE" | sed 's/\./\\./g') local new_package_escaped="$NEW_PACKAGE" for java_file in $java_files; do if grep -q "$OLD_PACKAGE" "$java_file"; then print_info "处理: $(basename $java_file)" # 修改package声明和import语句 sed -i.bak "s|$old_package_escaped|$new_package_escaped|g" "$java_file" # 删除备份文件 rm -f "${java_file}.bak" ((count++)) fi done print_success "已修改 $count 个 Java 文件" } # 修改XML映射文件 update_xml_files() { print_step "步骤 6: 修改 XML 映射文件" local xml_files=$(find "$PROJECT_DIR" -name "*.xml" -type f | grep -E "(mapper|mybatis)") local count=0 if [ -z "$xml_files" ]; then print_info "未找到需要修改的XML映射文件" return fi local old_package_escaped=$(echo "$OLD_PACKAGE" | sed 's/\./\\./g') for xml_file in $xml_files; do if grep -q "$OLD_PACKAGE" "$xml_file"; then print_info "处理: $(basename $xml_file)" # 修改namespace和resultType sed -i.bak "s|$old_package_escaped|$NEW_PACKAGE|g" "$xml_file" # 删除备份文件 rm -f "${xml_file}.bak" ((count++)) fi done print_success "已修改 $count 个 XML 文件" } # 修改配置文件 update_config_files() { print_step "步骤 7: 修改配置文件" local config_files=$(find "$PROJECT_DIR" -name "*.yml" -o -name "*.yaml" -o -name "*.properties" | grep -v target) local count=0 local old_package_escaped=$(echo "$OLD_PACKAGE" | sed 's/\./\\./g') for config_file in $config_files; do local modified=false # 修改包扫描配置 if grep -q "$OLD_PACKAGE" "$config_file"; then sed -i.bak "s|$old_package_escaped|$NEW_PACKAGE|g" "$config_file" modified=true fi # 修改数据库配置 if [ -n "$OLD_DATABASE_NAME" ] && grep -q "$OLD_DATABASE_NAME" "$config_file"; then sed -i.bak "s|$OLD_DATABASE_NAME|$NEW_DATABASE_NAME|g" "$config_file" modified=true fi if [ "$modified" = true ]; then print_info "处理: $(basename $config_file)" rm -f "${config_file}.bak" ((count++)) fi done print_success "已修改 $count 个配置文件" } # 重命名目录结构 rename_directories() { print_step "步骤 8: 重命名目录结构" # 重命名Java包目录 print_info "重命名Java包目录结构..." # 将点分隔的包名转换为路径 local old_package_path=$(echo "$OLD_PACKAGE" | tr '.' '/') local new_package_path=$(echo "$NEW_PACKAGE" | tr '.' '/') # 查找所有需要重命名的包目录 local package_dirs=$(find "$PROJECT_DIR" -type d -path "*/java/$old_package_path" 2>/dev/null) for package_dir in $package_dirs; do local parent_dir=$(dirname "$package_dir") local new_package_dir="$parent_dir/$new_package_path" # 创建新的目录结构 mkdir -p "$(dirname $new_package_dir)" # 移动内容 if [ "$package_dir" != "$new_package_dir" ]; then print_info "移动: $package_dir -> $new_package_dir" mv "$package_dir" "$new_package_dir" 2>/dev/null || { # 如果直接移动失败,尝试复制后删除 cp -r "$package_dir" "$new_package_dir" rm -rf "$package_dir" } fi done # 重命名模块目录 print_info "重命名模块目录..." local module_dirs=$(find "$PROJECT_DIR" -maxdepth 2 -type d -name "$OLD_MODULE_PREFIX-*" 2>/dev/null) for module_dir in $module_dirs; do local parent_dir=$(dirname "$module_dir") local old_name=$(basename "$module_dir") local new_name=$(echo "$old_name" | sed "s/^$OLD_MODULE_PREFIX-/$NEW_MODULE_PREFIX-/") local new_module_dir="$parent_dir/$new_name" if [ "$module_dir" != "$new_module_dir" ]; then print_info "重命名模块: $old_name -> $new_name" mv "$module_dir" "$new_module_dir" fi done print_success "目录重命名完成" } # 重命名SQL文件 rename_sql_files() { print_step "步骤 9: 重命名 SQL 文件" local sql_files=$(find "$PROJECT_DIR" -name "*.sql" -type f | grep -i "$OLD_MODULE_PREFIX") local count=0 if [ -z "$sql_files" ]; then print_info "未找到需要重命名的SQL文件" return fi for sql_file in $sql_files; do local dir_name=$(dirname "$sql_file") local old_name=$(basename "$sql_file") local new_name=$(echo "$old_name" | sed "s/$OLD_MODULE_PREFIX/$NEW_MODULE_PREFIX/g") local new_sql_file="$dir_name/$new_name" if [ "$sql_file" != "$new_sql_file" ]; then print_info "重命名SQL文件: $old_name -> $new_name" mv "$sql_file" "$new_sql_file" ((count++)) fi done print_success "已重命名 $count 个 SQL 文件" } # 清理临时文件 cleanup() { print_step "步骤 10: 清理和验证" # 清理可能遗留的备份文件 find "$PROJECT_DIR" -name "*.bak" -type f -delete 2>/dev/null # 显示统计信息 local java_files_count=$(find "$PROJECT_DIR" -name "*.java" -type f | wc -l) local pom_files_count=$(find "$PROJECT_DIR" -name "pom.xml" -type f | wc -l) local xml_files_count=$(find "$PROJECT_DIR" -name "*.xml" -type f | grep -E "(mapper|mybatis)" | wc -l) echo "" echo -e "${WHITE}重构统计:${NC}" echo -e "${CYAN}Java 文件:${NC} $java_files_count" echo -e "${CYAN}POM 文件:${NC} $pom_files_count" echo -e "${CYAN}XML 映射文件:${NC} $xml_files_count" print_success "清理完成" } # 主函数 main() { # 检查依赖 if ! command -v sed &> /dev/null; then print_error "sed 命令未找到,请安装 sed" exit 1 fi print_banner get_user_input show_summary backup_project # 进入项目目录 cd "$PROJECT_DIR" || exit 1 # 执行重构步骤 update_pom_files update_java_packages update_xml_files update_config_files rename_directories rename_sql_files cleanup print_step "🎉 重构完成!" echo -e "${GREEN}" echo "╔══════════════════════════════════════════════════════════════════════════════╗" echo "║ 重构成功完成! ║" echo "║ ║" echo "║ 项目已成功从 $OLD_GROUP_ID 重构为 $NEW_GROUP_ID" echo "║ ║" echo "║ 下一步建议: ║" echo "║ 1. 检查IDE中的运行配置 ║" echo "║ 2. 更新数据库连接配置 ║" echo "║ 3. 清理并重新编译项目 ║" echo "║ 4. 测试项目是否正常运行 ║" echo "╚══════════════════════════════════════════════════════════════════════════════╝" echo -e "${NC}" } # 脚本入口 main "$@"