diff --git a/script/README.md b/script/README.md index 317384d..08a059e 100644 --- a/script/README.md +++ b/script/README.md @@ -1,49 +1,212 @@ -# 项目重构自动化脚本 +# 项目重构脚本使用指南 -这是一套用于Maven项目重构的自动化脚本,可以批量修改项目的包名、groupId、artifactId、模块名称等,让你轻松地将一个项目模板改造为新的项目。 +这是一套用于Maven项目重构和包名修复的自动化脚本,可以帮助你快速将一个项目模板重构为新的项目,并修复常见的包名重复问题。 -## 功能特性 +## 📋 脚本概览 -🚀 **全自动重构**: 一键修改项目中的所有相关配置 -📦 **多文件支持**: 支持修改POM文件、Java源码、XML映射文件、配置文件 -🗂️ **目录重构**: 自动重命名Java包目录和模块目录 -🔧 **可视化界面**: 友好的命令行交互界面 -💾 **安全备份**: 可选的项目备份功能 -⚡ **批量处理**: 支持配置文件批量重构 +本目录包含了用于项目重构和包名修复的自动化脚本: -## 文件说明 +### 🔧 脚本文件说明 ``` script/ -├── project-refactor.sh # 主重构脚本(交互式) -├── batch-refactor.sh # 批量重构脚本(配置文件) -├── refactor-config.example # 配置文件模板 -└── README.md # 使用说明(本文件) +├── project-refactor.sh # ⭐ 主要推荐:完整重构脚本 +├── simple-fix.sh # ⭐ 简单修复脚本 +├── fix-duplicate-packages.sh # 专门修复重复包名 +├── fix-directory-structure.sh # 目录结构重建脚本 +├── batch-refactor.sh # 批量重构脚本(配置文件) +├── refactor-config.example # 配置文件模板 +└── README.md # 本使用说明文件 ``` -## 使用方法 +## 🎯 脚本选择建议 -### 方法一:交互式重构(推荐新手) +### 1. **主要推荐:`project-refactor.sh`** ⭐⭐⭐⭐⭐ + +**适用场景**: +- 完整的项目重构(包名、模块名、数据库名等全面修改) +- 从一个框架模板创建新项目 +- 大规模的包名重构 + +**功能特点**: +- ✅ 功能最完整(POM文件、Java文件、XML文件、配置文件全覆盖) +- ✅ 有备份功能 +- ✅ 有验证步骤 +- ✅ 支持嵌套模块处理 +- ✅ **已修复包名重复问题** + +### 2. **简单场景:`simple-fix.sh`** ⭐⭐⭐ + +**适用场景**: +- 只需要修复包名重复问题 +- 简单的包名调整 +- 紧急修复 + +**功能特点**: +- ✅ 执行速度快 +- ✅ 逻辑简单可靠 +- ✅ 不需要交互 + +### 3. **备用选择:`fix-duplicate-packages.sh`** ⭐⭐ + +**适用场景**: +- 专门修复包名重复问题 +- 需要详细的检测报告 + +## 🚀 新项目重构完整指南 + +### 步骤 1: 准备工作 + +1. **确保项目已提交到Git** + ```bash + cd /path/to/your/new/project + git status + git add . + git commit -m "Initial commit before refactoring" + ``` + +2. **准备重构信息** + - 新的包名信息(如:`org.leocoder.newproject`) + - 新的模块前缀(如:`coder-newproject`) + - 新的数据库名称(可选) + +### 步骤 2: 执行重构脚本 ```bash -# 进入脚本目录 -cd script +# 进入项目目录 +cd /path/to/your/new/project -# 运行交互式重构脚本 -./project-refactor.sh +# 执行完整重构脚本 +bash script/project-refactor.sh ``` -脚本会引导你输入以下信息: -- 项目根目录路径 -- 旧的 GroupId(如:org.leocoder.thin) -- 旧的 ArtifactId(如:coder-common-thin-backend) -- 旧的模块前缀(如:coder-common-thin) -- 新的 GroupId(如:org.leocoder.course) -- 新的 ArtifactId(如:coder-course-backend) -- 新的模块前缀(如:coder-course) -- 数据库名称(可选) +### 步骤 3: 交互式配置 -### 方法二:配置文件批量重构(推荐批量处理) +脚本会提示你输入以下信息: + +#### 3.1 项目目录 +``` +请输入项目根目录路径 (默认: 当前目录): +项目路径: [直接回车使用当前目录] +``` + +#### 3.2 旧配置信息 +``` +旧的 GroupId (例如: org.leocoder.thin): org.leocoder.estate +旧的 ArtifactId (例如: coder-common-thin-backend): coder-estate-backend +旧的模块前缀 (例如: coder-common-thin): coder-estate +``` + +#### 3.3 新配置信息 +``` +新的 GroupId (例如: org.leocoder.course): org.leocoder.newproject +新的 ArtifactId (例如: coder-course-backend): coder-newproject-backend +新的模块前缀 (例如: coder-course): coder-newproject +``` + +#### 3.4 数据库配置(可选) +``` +旧的数据库名称 (留空跳过): coder_estate +新的数据库名称: coder_newproject +``` + +#### 3.5 确认执行 +``` +是否创建备份? (Y/n): Y +是否继续重构? (y/N): y +``` + +### 步骤 4: 验证重构结果 + +#### 4.1 检查目录结构 +```bash +# 检查是否还有重复目录 +find . -type d -path "*/org/leocoder/org/leocoder*" + +# 应该没有任何输出,如果有输出说明还存在重复目录 +``` + +#### 4.2 检查包名 +```bash +# 检查Java文件包名是否正确 +grep -r "package org.leocoder" . --include="*.java" | head -5 + +# 输出应该类似: +# ./src/main/java/org/leocoder/newproject/web/Application.java:package org.leocoder.newproject.web; +``` + +#### 4.3 检查import语句 +```bash +# 检查import语句是否正确 +grep -r "import org.leocoder" . --include="*.java" | head -5 + +# 输出应该使用新的包名 +``` + +#### 4.4 编译验证 +```bash +# 重新编译项目 +mvn clean compile + +# 如果编译成功,说明重构正确 +``` + +### 步骤 5: 测试验证 + +```bash +# 运行测试 +mvn test + +# 启动应用(如果是Spring Boot项目) +mvn spring-boot:run +``` + +## 🛠️ 常见问题处理 + +### 问题 1: 发现重复包名目录 + +**症状**: +```bash +find . -type d -path "*/org/leocoder/org/leocoder*" +# 有输出,存在重复目录 +``` + +**解决方案**: +```bash +# 使用简单修复脚本 +bash script/simple-fix.sh +``` + +### 问题 2: 编译失败 + +**可能原因**: +- 包名引用不一致 +- import语句错误 +- 配置文件中的包名未更新 + +**解决方案**: +```bash +# 1. 检查具体错误信息 +mvn clean compile + +# 2. 手动检查和修复特定文件 +grep -r "org\.leocoder\.estate" . --include="*.java" +grep -r "org\.leocoder\.estate" . --include="*.xml" +grep -r "org\.leocoder\.estate" . --include="*.yml" + +# 3. 如果需要,再次运行修复脚本 +bash script/fix-duplicate-packages.sh +``` + +### 问题 3: IDE中显示错误 + +**解决方案**: +1. **刷新项目**:在IDE中刷新整个项目 +2. **重新导入**:重新导入Maven项目 +3. **清理缓存**:清理IDE缓存和索引 +4. **重启IDE**:重启开发环境 + +## 📚 方法二:配置文件批量重构(推荐批量处理) ```bash # 1. 复制配置文件模板 @@ -79,7 +242,32 @@ CREATE_BACKUP="true" # 是否创建备份 AUTO_CONFIRM="false" # 是否自动确认(跳过确认步骤) ``` -## 重构内容 +## 📋 脚本详细说明 + +### `project-refactor.sh` 执行步骤 + +1. **步骤 1**: 获取重构参数 +2. **步骤 2**: 配置摘要确认 +3. **步骤 3**: 备份项目 +4. **步骤 4**: 修改 POM 文件 +5. **步骤 5**: 修改 Java 包名 +6. **步骤 6**: 修改 XML 映射文件 +7. **步骤 7**: 修改配置文件 +8. **步骤 8**: 重命名目录结构 +9. **步骤 9**: 处理遗漏的嵌套模块 +10. **步骤 10**: 修复重复包名 +11. **步骤 11**: 重命名 SQL 文件 +12. **步骤 12**: 清理和验证 + +### `simple-fix.sh` 执行内容 + +- 删除错误的目录结构 +- 清理空目录 +- 修复Java文件中的包名 +- 修复XML文件中的包名 +- 验证修复结果 + +## 🔧 重构内容说明 脚本会自动处理以下内容: @@ -108,8 +296,53 @@ AUTO_CONFIRM="false" # 是否自动确认(跳过确认步骤) - ✅ 重命名Java包目录结构(src/main/java/com/old/package → src/main/java/com/new/package) - ✅ 重命名模块目录(old-module-name → new-module-name) - ✅ 重命名SQL文件 +- ✅ **修复重复包名问题** -## 使用示例 +## 🎯 最佳实践 + +### 重构流程建议 + +```bash +# 1. 创建新分支 +git checkout -b refactor-to-newproject + +# 2. 执行重构 +bash script/project-refactor.sh + +# 3. 验证结果 +mvn clean compile +mvn test + +# 4. 提交变更 +git add . +git commit -m "refactor: change package from org.leocoder.estate to org.leocoder.newproject" + +# 5. 合并到主分支(如果一切正常) +git checkout main +git merge refactor-to-newproject +``` + +### 命名规范建议 + +- **包名**:`org.leocoder.{项目名}` +- **模块前缀**:`coder-{项目名}` +- **数据库名**:`coder_{项目名}` + +### 示例配置 + +``` +# 电商项目示例 +旧包名: org.leocoder.estate → 新包名: org.leocoder.ecommerce +旧模块: coder-estate → 新模块: coder-ecommerce +旧数据库: coder_estate → 新数据库: coder_ecommerce + +# 教育项目示例 +旧包名: org.leocoder.estate → 新包名: org.leocoder.education +旧模块: coder-estate → 新模块: coder-education +旧数据库: coder_estate → 新数据库: coder_education +``` + +## 💡 使用示例 ### 示例1:从通用框架改造为选课系统 @@ -119,9 +352,9 @@ AUTO_CONFIRM="false" # 是否自动确认(跳过确认步骤) # 输入示例: # 项目路径: /Users/leocoder/my-project -# 旧的 GroupId: org.leocoder.thin -# 旧的 ArtifactId: coder-common-thin-backend -# 旧的模块前缀: coder-common-thin +# 旧的 GroupId: org.leocoder.estate +# 旧的 ArtifactId: coder-estate-backend +# 旧的模块前缀: coder-estate # 新的 GroupId: org.leocoder.course # 新的 ArtifactId: coder-course-backend # 新的模块前缀: coder-course @@ -133,9 +366,9 @@ AUTO_CONFIRM="false" # 是否自动确认(跳过确认步骤) # 为选课系统创建配置 cat > course-system.conf << EOF PROJECT_DIR="/Users/leocoder/course-project" -OLD_GROUP_ID="org.leocoder.thin" -OLD_ARTIFACT_ID="coder-common-thin-backend" -OLD_MODULE_PREFIX="coder-common-thin" +OLD_GROUP_ID="org.leocoder.estate" +OLD_ARTIFACT_ID="coder-estate-backend" +OLD_MODULE_PREFIX="coder-estate" NEW_GROUP_ID="org.leocoder.course" NEW_ARTIFACT_ID="coder-course-backend" NEW_MODULE_PREFIX="coder-course" @@ -146,9 +379,9 @@ EOF # 为库存系统创建配置 cat > inventory-system.conf << EOF PROJECT_DIR="/Users/leocoder/inventory-project" -OLD_GROUP_ID="org.leocoder.thin" -OLD_ARTIFACT_ID="coder-common-thin-backend" -OLD_MODULE_PREFIX="coder-common-thin" +OLD_GROUP_ID="org.leocoder.estate" +OLD_ARTIFACT_ID="coder-estate-backend" +OLD_MODULE_PREFIX="coder-estate" NEW_GROUP_ID="org.leocoder.inventory" NEW_ARTIFACT_ID="coder-inventory-backend" NEW_MODULE_PREFIX="coder-inventory" @@ -161,13 +394,20 @@ EOF ./batch-refactor.sh inventory-system.conf ``` -## 注意事项 +## ⚠️ 重要注意事项 -⚠️ **重要提醒**: -1. **备份项目**: 重构前强烈建议备份整个项目 -2. **关闭IDE**: 重构期间请关闭IDE,避免文件锁定 -3. **检查结果**: 重构完成后请检查项目能否正常编译运行 -4. **更新配置**: 检查IDE的运行配置是否需要更新 +### 使用前必读 + +1. **备份项目**:始终在Git中提交代码后再执行脚本 +2. **关闭IDE**:执行脚本前关闭IDE,避免文件锁定 +3. **检查权限**:确保脚本有执行权限(`chmod +x script/*.sh`) +4. **逐步验证**:每个步骤完成后都进行验证 + +### 安全建议 + +1. **测试环境**:先在测试环境中执行,确认无误后再在生产代码中使用 +2. **分支操作**:建议在新的Git分支中执行重构操作 +3. **备份重要**:重要项目建议手动备份整个项目目录 ### 重构后需要手动检查的项目 - [ ] IDE中的运行配置(主类路径) @@ -176,7 +416,14 @@ EOF - [ ] 测试用例 - [ ] 文档更新 -## 故障排除 +## 🆘 获取帮助 + +如果在使用过程中遇到问题: + +1. **查看日志**:脚本执行过程中的详细日志 +2. **检查文件**:手动检查具体的错误文件 +3. **重新执行**:如果部分失败,可以重新执行脚本 +4. **手动修复**:对于特殊情况,可能需要手动修复部分文件 ### 常见问题 @@ -198,7 +445,7 @@ A: 确保脚本有执行权限:`chmod +x *.sh` 2. **检查备份**: 如果出现问题,可以从备份恢复 3. **分步执行**: 可以注释掉脚本中的某些步骤来分步调试 -## 扩展功能 +## 🔧 扩展功能 你可以根据需要扩展脚本功能: @@ -206,16 +453,25 @@ A: 确保脚本有执行权限:`chmod +x *.sh` 2. **自定义替换规则**: 修改sed命令的正则表达式 3. **集成到CI/CD**: 将脚本集成到自动化流水线中 -## 贡献 - -如果你发现bug或有改进建议,请提交issue或pull request。 - -## 许可证 - -MIT License - --- +**创建时间**: 2025-01-09 +**最后更新**: 2025-01-09 +**版本**: v2.0 **作者**: Leocoder -**版本**: 1.0 -**最后更新**: 2025-07-06 \ No newline at end of file + +## 📝 更新日志 + +### v2.0 (2025-01-09) +- ✅ 新增重复包名检测和修复功能 +- ✅ 新增 `simple-fix.sh` 快速修复脚本 +- ✅ 新增 `fix-duplicate-packages.sh` 专门修复重复包名 +- ✅ 完善了使用指南和最佳实践 +- ✅ 增加了详细的问题排查步骤 +- ✅ 优化了目录结构处理逻辑 + +### v1.0 (2025-07-06) +- ✅ 基础项目重构功能 +- ✅ 支持POM文件、Java文件、XML文件修改 +- ✅ 支持配置文件批量处理 +- ✅ 基础的目录结构重命名功能 \ No newline at end of file diff --git a/script/fix-directory-structure.sh b/script/fix-directory-structure.sh new file mode 100755 index 0000000..a2129ba --- /dev/null +++ b/script/fix-directory-structure.sh @@ -0,0 +1,286 @@ +#!/bin/bash + +# 目录结构修复脚本 - 专门修复重复包名目录问题 +# 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="" + +# 打印信息 +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}" +} + +# 获取项目目录 +get_project_dir() { + if [ -z "$1" ]; then + PROJECT_DIR="$(pwd)" + else + PROJECT_DIR="$1" + fi + + if [ ! -d "$PROJECT_DIR" ]; then + print_error "项目目录不存在: $PROJECT_DIR" + exit 1 + fi + + if [ ! -f "$PROJECT_DIR/pom.xml" ]; then + print_error "这不是一个Maven项目" + exit 1 + fi + + print_success "项目目录: $PROJECT_DIR" +} + +# 备份重要文件 +backup_files() { + print_step "步骤 1: 备份重要文件" + + local backup_dir="/tmp/package_fix_backup_$(date +%Y%m%d_%H%M%S)" + mkdir -p "$backup_dir" + + # 查找所有Java文件并备份 + find "$PROJECT_DIR" -name "*.java" | while read java_file; do + local rel_path="${java_file#$PROJECT_DIR/}" + local target_file="$backup_dir/$rel_path" + mkdir -p "$(dirname "$target_file")" + cp "$java_file" "$target_file" + done + + print_success "文件已备份到: $backup_dir" +} + +# 收集所有Java文件 +collect_java_files() { + print_step "步骤 2: 收集所有Java文件" + + local temp_dir="/tmp/java_files_$(date +%Y%m%d_%H%M%S)" + mkdir -p "$temp_dir" + + # 查找所有Java文件并复制到临时目录 + find "$PROJECT_DIR" -name "*.java" -path "*/org/leocoder/*" | while read java_file; do + # 提取相对于org的路径 + local rel_path=$(echo "$java_file" | sed 's|.*/org/leocoder/|org/leocoder/|') + local target_file="$temp_dir/$rel_path" + + # 创建目标目录 + mkdir -p "$(dirname "$target_file")" + + # 复制文件 + cp "$java_file" "$target_file" + + print_info "收集文件: $rel_path" + done + + echo "$temp_dir" +} + +# 清理错误的目录结构 +cleanup_wrong_structure() { + print_step "步骤 3: 清理错误的目录结构" + + # 删除所有org目录 + find "$PROJECT_DIR" -type d -name "org" -path "*/src/main/java/*" | while read org_dir; do + print_info "删除目录: $org_dir" + rm -rf "$org_dir" + done + + print_success "已清理所有org目录" +} + +# 重建正确的目录结构 +rebuild_structure() { + print_step "步骤 4: 重建正确的目录结构" + + local temp_dir="$1" + local count=0 + + # 查找所有Java源码目录 + find "$PROJECT_DIR" -type d -path "*/src/main/java" | while read java_src_dir; do + print_info "处理目录: $java_src_dir" + + # 在每个java目录下重建org/leocoder/estate结构 + local target_base="$java_src_dir/org/leocoder/estate" + mkdir -p "$target_base" + + # 从临时目录复制对应的文件 + if [ -d "$temp_dir/org/leocoder/estate" ]; then + # 获取模块名称来判断应该复制哪些文件 + local module_name=$(echo "$java_src_dir" | grep -o 'coder-estate-[^/]*' | head -1) + + case "$module_name" in + "coder-estate-common") + if [ -d "$temp_dir/org/leocoder/estate/common" ]; then + cp -r "$temp_dir/org/leocoder/estate/common" "$target_base/" + print_info "复制common模块文件" + fi + ;; + "coder-estate-model") + if [ -d "$temp_dir/org/leocoder/estate/domain" ]; then + cp -r "$temp_dir/org/leocoder/estate/domain" "$target_base/" + print_info "复制model模块文件" + fi + ;; + "coder-estate-system") + if [ -d "$temp_dir/org/leocoder/estate/system" ]; then + cp -r "$temp_dir/org/leocoder/estate/system" "$target_base/" + print_info "复制system模块文件" + fi + ;; + "coder-estate-web") + if [ -d "$temp_dir/org/leocoder/estate/web" ]; then + cp -r "$temp_dir/org/leocoder/estate/web" "$target_base/" + print_info "复制web模块文件" + fi + ;; + "coder-estate-mybatisplus") + if [ -d "$temp_dir/org/leocoder/estate/mybatisplus" ]; then + cp -r "$temp_dir/org/leocoder/estate/mybatisplus" "$target_base/" + print_info "复制mybatisplus模块文件" + fi + ;; + *plugin*) + # 处理插件模块 + local plugin_type=$(echo "$module_name" | sed 's/coder-estate-//') + if [ -d "$temp_dir/org/leocoder/estate/$plugin_type" ]; then + cp -r "$temp_dir/org/leocoder/estate/$plugin_type" "$target_base/" + print_info "复制${plugin_type}插件文件" + fi + ;; + esac + fi + + ((count++)) + done + + print_success "已重建 $count 个模块的目录结构" +} + +# 修复文件内容中的包名 +fix_package_names() { + print_step "步骤 5: 修复文件内容中的包名" + + local count=0 + + # 查找所有Java文件并修复包名 + find "$PROJECT_DIR" -name "*.java" -path "*/org/leocoder/estate/*" | while read java_file; do + # 检查是否包含错误的包名 + if grep -q "org\.leocoder\.org\.leocoder" "$java_file"; then + print_info "修复包名: $(basename "$java_file")" + + # 修复包名 + sed -i '' 's|org\.leocoder\.org\.leocoder\.estate|org.leocoder.estate|g' "$java_file" + sed -i '' 's|org\.leocoder\.org\.leocoder|org.leocoder|g' "$java_file" + + ((count++)) + fi + done + + print_success "已修复 $count 个文件的包名" +} + +# 验证修复结果 +verify_result() { + print_step "步骤 6: 验证修复结果" + + # 检查是否还有重复目录 + local duplicate_dirs=$(find "$PROJECT_DIR" -type d -path "*/org/leocoder/org/leocoder*" 2>/dev/null) + if [ -n "$duplicate_dirs" ]; then + print_warning "仍然存在重复目录:" + echo "$duplicate_dirs" + return 1 + fi + + # 检查Java文件数量 + local java_count=$(find "$PROJECT_DIR" -name "*.java" -path "*/org/leocoder/estate/*" | wc -l) + print_info "Java文件总数: $java_count" + + # 检查模块结构 + local modules=$(find "$PROJECT_DIR" -type d -path "*/src/main/java/org/leocoder/estate" | wc -l) + print_info "模块数量: $modules" + + print_success "目录结构修复完成" +} + +# 清理临时文件 +cleanup_temp() { + local temp_dir="$1" + if [ -d "$temp_dir" ]; then + rm -rf "$temp_dir" + print_info "已清理临时文件" + fi +} + +# 主函数 +main() { + echo -e "${CYAN}" + echo "╔══════════════════════════════════════════════════════════════════════════════╗" + echo "║ 目录结构修复脚本 ║" + echo "║ Directory Structure Fix Tool ║" + echo "║ Version 1.0 ║" + echo "╚══════════════════════════════════════════════════════════════════════════════╝" + echo -e "${NC}" + + get_project_dir "$1" + + echo "" + echo -e "${YELLOW}警告: 此操作将重新组织项目目录结构,建议先备份项目!${NC}" + echo "" + read -p "是否继续? (y/N): " confirm + if [[ ! "$confirm" =~ ^[Yy]$ ]]; then + print_info "操作已取消" + exit 0 + fi + + # 执行修复步骤 + backup_files + local temp_dir=$(collect_java_files) + cleanup_wrong_structure + rebuild_structure "$temp_dir" + fix_package_names + verify_result + cleanup_temp "$temp_dir" + + echo -e "${GREEN}" + echo "╔══════════════════════════════════════════════════════════════════════════════╗" + echo "║ 目录结构修复完成! ║" + echo "║ ║" + echo "║ 下一步建议: ║" + echo "║ 1. 重新编译项目验证修复效果 ║" + echo "║ 2. 检查IDE中的导入语句 ║" + echo "║ 3. 运行测试确保功能正常 ║" + echo "╚══════════════════════════════════════════════════════════════════════════════╝" + echo -e "${NC}" +} + +# 脚本入口 +main "$@" \ No newline at end of file diff --git a/script/fix-duplicate-packages.sh b/script/fix-duplicate-packages.sh new file mode 100755 index 0000000..3c5dd01 --- /dev/null +++ b/script/fix-duplicate-packages.sh @@ -0,0 +1,493 @@ +#!/bin/bash + +# 包名重复修复脚本 - 专门用于修复已经重复的包名 +# 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="" + +# 打印banner +print_banner() { + echo -e "${CYAN}" + echo "╔══════════════════════════════════════════════════════════════════════════════╗" + echo "║ 包名重复修复脚本 ║" + echo "║ Fix Duplicate Packages 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}" +} + +# 获取项目目录 +get_project_dir() { + 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" +} + +# 检测重复包名 +detect_duplicate_packages() { + print_step "步骤 2: 检测重复包名" + + local all_files=$(find "$PROJECT_DIR" -name "*.java" -o -name "*.xml" -o -name "*.yml" -o -name "*.yaml" -o -name "*.properties" | grep -v target) + local found_duplicates=false + + echo -e "${WHITE}检测结果:${NC}" + + # 1. 检测目录结构中的重复 + echo -e "${CYAN}1. 检测目录结构重复:${NC}" + local duplicate_dirs=$(find "$PROJECT_DIR" -type d -path "*/org/leocoder/org/leocoder*" 2>/dev/null) + if [ -n "$duplicate_dirs" ]; then + found_duplicates=true + echo -e "${YELLOW}发现重复目录结构:${NC}" + echo "$duplicate_dirs" | while read dir; do + echo " - $dir" + done + else + echo -e "${GREEN}目录结构正常${NC}" + fi + + # 2. 检测文件内容中的重复包名 + echo -e "${CYAN}2. 检测文件内容重复:${NC}" + local duplicate_patterns=( + "org\.leocoder\.org\.leocoder" + "org\.leocoder\.thin\.org\.leocoder" + "org\.leocoder\.course\.org\.leocoder" + "org\.leocoder\.estate\.org\.leocoder" + ) + + local file_duplicates_found=false + for pattern in "${duplicate_patterns[@]}"; do + local files_with_pattern=$(grep -l "$pattern" $all_files 2>/dev/null | head -10) + if [ -n "$files_with_pattern" ]; then + found_duplicates=true + file_duplicates_found=true + echo -e "${YELLOW}发现重复模式: $pattern${NC}" + echo "$files_with_pattern" | while read file; do + echo " - $(basename $file)" + done + fi + done + + # 通用重复检测 + local general_duplicates=$(grep -l "org\.leocoder\.[^.]*\.org\.leocoder" $all_files 2>/dev/null | head -10) + if [ -n "$general_duplicates" ]; then + found_duplicates=true + file_duplicates_found=true + echo -e "${YELLOW}发现其他重复模式:${NC}" + echo "$general_duplicates" | while read file; do + echo " - $(basename $file)" + done + fi + + if [ "$file_duplicates_found" = false ]; then + echo -e "${GREEN}文件内容正常${NC}" + fi + + if [ "$found_duplicates" = false ]; then + echo -e "${GREEN}未发现重复包名问题${NC}" + exit 0 + 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_fix_$(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 +} + +# 清理现有错误的目录结构 +cleanup_existing_duplicates() { + print_step "步骤 3.5: 清理现有错误的目录结构" + + local cleaned_count=0 + + # 清理空的org目录 + echo -e "${CYAN}清理空的org目录:${NC}" + local empty_org_dirs=$(find "$PROJECT_DIR" -type d -name "org" -exec sh -c 'for dir; do if [ -z "$(ls -A "$dir" 2>/dev/null)" ]; then echo "$dir"; fi; done' _ {} +) + if [ -n "$empty_org_dirs" ]; then + echo "$empty_org_dirs" | while read empty_dir; do + if [ -d "$empty_dir" ]; then + print_info "删除空目录: $empty_dir" + rmdir "$empty_dir" 2>/dev/null || true + ((cleaned_count++)) + fi + done + fi + + # 清理重复的配置文件(如果存在) + echo -e "${CYAN}清理重复的配置文件:${NC}" + local config_files=$(find "$PROJECT_DIR" -name "*.java" -path "*/config/*" | grep -E "(OpenApiConfig|CoderApplication)" | sort) + if [ -n "$config_files" ]; then + local prev_file="" + echo "$config_files" | while read config_file; do + if [ -n "$prev_file" ] && [ "$(basename "$config_file")" = "$(basename "$prev_file")" ]; then + # 检查文件内容是否相同 + if diff "$config_file" "$prev_file" > /dev/null 2>&1; then + print_info "删除重复文件: $config_file" + rm -f "$config_file" + ((cleaned_count++)) + fi + fi + prev_file="$config_file" + done + fi + + print_success "清理完成,已处理 $cleaned_count 个项目" +} + +# 修复重复包名 +fix_duplicate_packages() { + print_step "步骤 4: 修复重复包名" + + local file_count=0 + local dir_count=0 + + # 1. 修复目录结构重复 + echo -e "${CYAN}1. 修复目录结构重复:${NC}" + + # 找到所有重复的根目录(org/leocoder/org/leocoder) + local duplicate_root_dirs=$(find "$PROJECT_DIR" -type d -path "*/org/leocoder/org/leocoder" ! -path "*/org/leocoder/org/leocoder/*" 2>/dev/null) + + if [ -n "$duplicate_root_dirs" ]; then + echo "$duplicate_root_dirs" | while read duplicate_root; do + if [ -d "$duplicate_root" ]; then + # 计算正确的目标目录 + local java_dir=$(dirname "$duplicate_root") + local correct_target="$java_dir/org/leocoder" + + print_info "处理重复目录: $duplicate_root" + print_info "目标目录: $correct_target" + + # 创建正确的目标目录(如果不存在) + mkdir -p "$correct_target" + + # 移动所有文件和子目录到正确位置 + if [ -d "$duplicate_root" ] && [ "$(ls -A "$duplicate_root" 2>/dev/null)" ]; then + # 移动所有内容 + for item in "$duplicate_root"/*; do + if [ -e "$item" ]; then + local item_name=$(basename "$item") + local target_item="$correct_target/$item_name" + + if [ -d "$item" ] && [ -d "$target_item" ]; then + # 如果是目录且目标已存在,递归合并 + cp -r "$item/"* "$target_item/" 2>/dev/null || true + else + # 直接移动 + mv "$item" "$target_item" 2>/dev/null || true + fi + fi + done + fi + + # 删除重复的目录结构 + rm -rf "$duplicate_root" 2>/dev/null || true + + # 清理空的父目录 + local cleanup_dir=$(dirname "$duplicate_root") + while [ "$cleanup_dir" != "$java_dir" ] && [ -d "$cleanup_dir" ]; do + # 检查目录是否为空 + if [ -z "$(ls -A "$cleanup_dir" 2>/dev/null)" ]; then + rmdir "$cleanup_dir" 2>/dev/null || true + cleanup_dir=$(dirname "$cleanup_dir") + else + break + fi + done + + ((dir_count++)) + fi + done + + print_success "已处理重复目录结构" + else + echo -e "${GREEN}目录结构正常${NC}" + fi + + # 2. 修复文件内容中的重复包名 + echo -e "${CYAN}2. 修复文件内容重复:${NC}" + local all_files=$(find "$PROJECT_DIR" -name "*.java" -o -name "*.xml" -o -name "*.yml" -o -name "*.yaml" -o -name "*.properties" | grep -v target) + + # 检查常见的重复模式 + local duplicate_patterns=( + "org\.leocoder\.org\.leocoder" + "org\.leocoder\.thin\.org\.leocoder" + "org\.leocoder\.course\.org\.leocoder" + "org\.leocoder\.estate\.org\.leocoder" + ) + + for file in $all_files; do + local modified=false + local temp_file=$(mktemp) + + # 处理每个重复模式 + cp "$file" "$temp_file" + + for pattern in "${duplicate_patterns[@]}"; do + if grep -q "$pattern" "$temp_file"; then + # 修复重复的包名,保留最后一个正确的部分 + case "$pattern" in + "org\.leocoder\.org\.leocoder") + sed -i '' "s|org\.leocoder\.org\.leocoder|org.leocoder|g" "$temp_file" + modified=true + ;; + "org\.leocoder\.thin\.org\.leocoder") + sed -i '' "s|org\.leocoder\.thin\.org\.leocoder|org.leocoder|g" "$temp_file" + modified=true + ;; + "org\.leocoder\.course\.org\.leocoder") + sed -i '' "s|org\.leocoder\.course\.org\.leocoder|org.leocoder.course|g" "$temp_file" + modified=true + ;; + "org\.leocoder\.estate\.org\.leocoder") + sed -i '' "s|org\.leocoder\.estate\.org\.leocoder|org.leocoder.estate|g" "$temp_file" + modified=true + ;; + esac + fi + done + + # 通用重复修复:修复任何 org.leocoder.*.org.leocoder.* 的模式 + if grep -q "org\.leocoder\.[^.]*\.org\.leocoder" "$temp_file"; then + # 更精确的处理:提取中间部分并重构 + sed -i '' 's|org\.leocoder\.\([^.]*\)\.org\.leocoder\.\(.*\)|org.leocoder.\1.\2|g' "$temp_file" + modified=true + fi + + # 检查是否有实际变化 + if [ "$modified" = true ] && ! diff "$file" "$temp_file" > /dev/null; then + mv "$temp_file" "$file" + print_info "修复文件内容: $(basename $file)" + ((file_count++)) + else + rm -f "$temp_file" + fi + done + + echo "" + print_success "已修复 $dir_count 个目录结构和 $file_count 个文件中的重复包名" +} + +# 验证修复结果 +verify_fix() { + print_step "步骤 5: 验证修复结果" + + local all_files=$(find "$PROJECT_DIR" -name "*.java" -o -name "*.xml" -o -name "*.yml" -o -name "*.yaml" -o -name "*.properties" | grep -v target) + local remaining_duplicates=false + + # 1. 验证目录结构 + echo -e "${CYAN}1. 验证目录结构:${NC}" + local duplicate_dirs=$(find "$PROJECT_DIR" -type d -path "*/org/leocoder/org/leocoder*" 2>/dev/null) + if [ -n "$duplicate_dirs" ]; then + remaining_duplicates=true + echo -e "${RED}仍然存在重复目录结构:${NC}" + echo "$duplicate_dirs" | while read dir; do + echo " - $dir" + done + else + echo -e "${GREEN}目录结构正常${NC}" + fi + + # 检查是否有孤立的org目录需要清理 + local orphan_org_dirs=$(find "$PROJECT_DIR" -type d -name "org" -exec sh -c 'for dir; do if [ -z "$(ls -A "$dir" 2>/dev/null)" ]; then echo "$dir"; fi; done' _ {} +) + if [ -n "$orphan_org_dirs" ]; then + echo -e "${YELLOW}发现空的org目录,建议清理:${NC}" + echo "$orphan_org_dirs" | while read dir; do + echo " - $dir" + rmdir "$dir" 2>/dev/null || true + done + fi + + # 2. 验证文件内容 + echo -e "${CYAN}2. 验证文件内容:${NC}" + + # 检查是否还有重复 + local duplicate_patterns=( + "org\.leocoder\.org\.leocoder" + "org\.leocoder\.thin\.org\.leocoder" + "org\.leocoder\.course\.org\.leocoder" + "org\.leocoder\.estate\.org\.leocoder" + ) + + local file_duplicates_found=false + for pattern in "${duplicate_patterns[@]}"; do + local files_with_pattern=$(grep -l "$pattern" $all_files 2>/dev/null) + if [ -n "$files_with_pattern" ]; then + remaining_duplicates=true + file_duplicates_found=true + echo -e "${RED}仍然存在重复模式: $pattern${NC}" + echo "$files_with_pattern" | while read file; do + echo " - $(basename $file)" + done + fi + done + + # 通用重复检测 + local general_duplicates=$(grep -l "org\.leocoder\.[^.]*\.org\.leocoder" $all_files 2>/dev/null) + if [ -n "$general_duplicates" ]; then + remaining_duplicates=true + file_duplicates_found=true + echo -e "${RED}仍然存在其他重复模式${NC}" + echo "$general_duplicates" | while read file; do + echo " - $(basename $file)" + done + fi + + if [ "$file_duplicates_found" = false ]; then + echo -e "${GREEN}文件内容正常${NC}" + fi + + echo "" + if [ "$remaining_duplicates" = false ]; then + print_success "所有重复包名已成功修复" + else + print_warning "部分重复包名可能需要手动修复" + fi +} + +# 清理临时文件 +cleanup() { + print_step "步骤 6: 清理工作" + + # 清理可能遗留的临时文件 + find "$PROJECT_DIR" -name "*.bak" -type f -delete 2>/dev/null + find "$PROJECT_DIR" -name ".DS_Store" -type f -delete 2>/dev/null + + # 显示统计信息 + local java_files_count=$(find "$PROJECT_DIR" -name "*.java" -type f | wc -l) + local xml_files_count=$(find "$PROJECT_DIR" -name "*.xml" -type f | wc -l) + local config_files_count=$(find "$PROJECT_DIR" -name "*.yml" -o -name "*.yaml" -o -name "*.properties" | wc -l) + + echo "" + echo -e "${WHITE}项目文件统计:${NC}" + echo -e "${CYAN}Java 文件:${NC} $java_files_count" + echo -e "${CYAN}XML 文件:${NC} $xml_files_count" + echo -e "${CYAN}配置文件:${NC} $config_files_count" + + print_success "清理完成" +} + +# 主函数 +main() { + # 检查依赖 + if ! command -v sed &> /dev/null; then + print_error "sed 命令未找到,请安装 sed" + exit 1 + fi + + print_banner + + get_project_dir + detect_duplicate_packages + backup_project + + # 进入项目目录 + cd "$PROJECT_DIR" || exit 1 + + # 执行修复步骤 + cleanup_existing_duplicates + fix_duplicate_packages + verify_fix + cleanup + + print_step "🎉 修复完成!" + + echo -e "${GREEN}" + echo "╔══════════════════════════════════════════════════════════════════════════════╗" + echo "║ 重复包名修复完成! ║" + echo "║ ║" + echo "║ 下一步建议: ║" + echo "║ 1. 重新编译项目验证修复效果 ║" + echo "║ 2. 检查IDE中的导入语句 ║" + echo "║ 3. 运行测试确保功能正常 ║" + echo "╚══════════════════════════════════════════════════════════════════════════════╝" + echo -e "${NC}" +} + +# 脚本入口 +main "$@" \ No newline at end of file diff --git a/script/project-refactor.sh b/script/project-refactor.sh index d787c73..b95d12c 100755 --- a/script/project-refactor.sh +++ b/script/project-refactor.sh @@ -224,13 +224,14 @@ update_pom_files() { # 创建临时文件 local temp_file=$(mktemp) - # 修改groupId和artifactId + # 修改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" + 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" @@ -238,6 +239,31 @@ update_pom_files() { ((count++)) done + # 第二轮处理:确保所有嵌套模块引用都被更新 + print_info "第二轮处理:更新嵌套模块引用..." + + for pom_file in $pom_files; do + local temp_file=$(mktemp) + local modified=false + + # 检查是否还有遗漏的旧模块前缀 + if grep -q "$OLD_MODULE_PREFIX-" "$pom_file"; then + # 处理依赖中的模块引用 + sed "s|$OLD_GROUP_ID|$NEW_GROUP_ID|g" "$pom_file" | \ + 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" | \ + sed "s|=$OLD_MODULE_PREFIX-|=$NEW_MODULE_PREFIX-|g" > "$temp_file" + + mv "$temp_file" "$pom_file" + modified=true + fi + + if [ "$modified" = true ]; then + print_info "更新嵌套引用: $(basename $(dirname $pom_file))/pom.xml" + fi + done + print_success "已修改 $count 个 POM 文件" } @@ -256,13 +282,27 @@ update_java_packages() { 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" + # 创建临时文件 + local temp_file=$(mktemp) - # 删除备份文件 - rm -f "${java_file}.bak" + # 修改package声明 - 使用精确匹配 + sed "s|^package $old_package_escaped\(\.[a-zA-Z0-9_]*\)\*;|package $new_package_escaped\1;|g" "$java_file" | \ + # 修改import语句 - 使用精确匹配 + sed "s|^import $old_package_escaped\(\.[a-zA-Z0-9_\.]*\);|import $new_package_escaped\1;|g" | \ + # 修改import static语句 + sed "s|^import static $old_package_escaped\(\.[a-zA-Z0-9_\.]*\);|import static $new_package_escaped\1;|g" | \ + # 修改注释和字符串中的包名引用(谨慎处理) + sed "s|\"$old_package_escaped\(\.[a-zA-Z0-9_\.]*\)\"|\"$new_package_escaped\1\"|g" | \ + # 修改注解中的包名引用 + sed "s|@$old_package_escaped\(\.[a-zA-Z0-9_\.]*\)|@$new_package_escaped\1|g" > "$temp_file" - ((count++)) + # 检查是否有实际变化 + if ! diff "$java_file" "$temp_file" > /dev/null; then + mv "$temp_file" "$java_file" + ((count++)) + else + rm -f "$temp_file" + fi fi done @@ -287,13 +327,31 @@ update_xml_files() { 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" + # 创建临时文件 + local temp_file=$(mktemp) - # 删除备份文件 - rm -f "${xml_file}.bak" + # 修改namespace属性 - 精确匹配 + sed "s|namespace=\"$old_package_escaped\(\.[a-zA-Z0-9_\.]*\)\"|namespace=\"$NEW_PACKAGE\1\"|g" "$xml_file" | \ + # 修改resultType属性 + sed "s|resultType=\"$old_package_escaped\(\.[a-zA-Z0-9_\.]*\)\"|resultType=\"$NEW_PACKAGE\1\"|g" | \ + # 修改parameterType属性 + sed "s|parameterType=\"$old_package_escaped\(\.[a-zA-Z0-9_\.]*\)\"|parameterType=\"$NEW_PACKAGE\1\"|g" | \ + # 修改type属性 + sed "s|type=\"$old_package_escaped\(\.[a-zA-Z0-9_\.]*\)\"|type=\"$NEW_PACKAGE\1\"|g" | \ + # 修改javaType属性 + sed "s|javaType=\"$old_package_escaped\(\.[a-zA-Z0-9_\.]*\)\"|javaType=\"$NEW_PACKAGE\1\"|g" | \ + # 修改jdbcType中的包名引用(如果有) + sed "s|select=\"$old_package_escaped\(\.[a-zA-Z0-9_\.]*\)\"|select=\"$NEW_PACKAGE\1\"|g" | \ + # 修改注释中的包名引用 + sed "s|||g" > "$temp_file" - ((count++)) + # 检查是否有实际变化 + if ! diff "$xml_file" "$temp_file" > /dev/null; then + mv "$temp_file" "$xml_file" + ((count++)) + else + rm -f "$temp_file" + fi fi done @@ -311,22 +369,52 @@ update_config_files() { for config_file in $config_files; do local modified=false + local temp_file=$(mktemp) - # 修改包扫描配置 + # 处理包扫描配置 if grep -q "$OLD_PACKAGE" "$config_file"; then - sed -i.bak "s|$old_package_escaped|$NEW_PACKAGE|g" "$config_file" - modified=true + # 修改包扫描配置 - 精确匹配 + sed "s|base-package: $old_package_escaped|base-package: $NEW_PACKAGE|g" "$config_file" | \ + sed "s|basePackage: $old_package_escaped|basePackage: $NEW_PACKAGE|g" | \ + sed "s|base-packages: $old_package_escaped|base-packages: $NEW_PACKAGE|g" | \ + sed "s|basePackages: $old_package_escaped|basePackages: $NEW_PACKAGE|g" | \ + # 修改mybatis配置 + sed "s|mapper-locations: classpath:$old_package_escaped|mapper-locations: classpath:$NEW_PACKAGE|g" | \ + sed "s|type-aliases-package: $old_package_escaped|type-aliases-package: $NEW_PACKAGE|g" | \ + # 修改日志配置 + sed "s| "$temp_file" + + # 检查是否有实际变化 + if ! diff "$config_file" "$temp_file" > /dev/null; then + mv "$temp_file" "$config_file" + modified=true + else + rm -f "$temp_file" + fi 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 + local temp_file2=$(mktemp) + # 精确匹配数据库名称 + sed "s|database: $OLD_DATABASE_NAME|database: $NEW_DATABASE_NAME|g" "$config_file" | \ + sed "s|jdbc:mysql://[^/]*/\{0,1\}$OLD_DATABASE_NAME|jdbc:mysql://localhost:3306/$NEW_DATABASE_NAME|g" | \ + sed "s|url: .*/$OLD_DATABASE_NAME|url: jdbc:mysql://localhost:3306/$NEW_DATABASE_NAME|g" > "$temp_file2" + + if ! diff "$config_file" "$temp_file2" > /dev/null; then + mv "$temp_file2" "$config_file" + modified=true + else + rm -f "$temp_file2" + fi fi if [ "$modified" = true ]; then print_info "处理: $(basename $config_file)" - rm -f "${config_file}.bak" ((count++)) fi done @@ -366,28 +454,185 @@ rename_directories() { 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" + # 递归函数来处理所有层级的模块目录 + rename_module_directories() { + local search_dir="$1" + local depth="$2" - if [ "$module_dir" != "$new_module_dir" ]; then - print_info "重命名模块: $old_name -> $new_name" - mv "$module_dir" "$new_module_dir" - fi - done + # 在当前目录查找匹配的模块目录 + local module_dirs=$(find "$search_dir" -maxdepth 1 -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 "重命名模块 (深度$depth): $old_name -> $new_name" + mv "$module_dir" "$new_module_dir" + + # 递归处理重命名后的目录 + rename_module_directories "$new_module_dir" $((depth + 1)) + else + # 如果目录名没有变化,仍然需要递归处理其子目录 + rename_module_directories "$module_dir" $((depth + 1)) + fi + done + + # 处理不匹配模块前缀但可能包含子模块的目录 + local subdirs=$(find "$search_dir" -maxdepth 1 -type d ! -name ".*" ! -name "target" ! -name "src" ! -name "test" ! -name "main" ! -name "java" ! -name "resources" -not -path "$search_dir" 2>/dev/null) + + for subdir in $subdirs; do + local dir_name=$(basename "$subdir") + # 如果目录名不是以旧模块前缀开头,但可能包含子模块,继续递归 + if [[ ! "$dir_name" =~ ^$OLD_MODULE_PREFIX- ]] && [[ "$dir_name" != "target" ]] && [[ "$dir_name" != "src" ]]; then + rename_module_directories "$subdir" $((depth + 1)) + fi + done + } + + # 从项目根目录开始递归处理 + rename_module_directories "$PROJECT_DIR" 1 print_success "目录重命名完成" } +# 处理遗漏的嵌套模块 +process_nested_modules() { + print_step "步骤 9: 处理遗漏的嵌套模块" + + print_info "检查是否有未处理的嵌套模块..." + + # 查找所有仍然使用旧模块前缀的目录 + local remaining_dirs=$(find "$PROJECT_DIR" -type d -name "$OLD_MODULE_PREFIX-*" ! -path "*/target/*" 2>/dev/null) + + if [ -z "$remaining_dirs" ]; then + print_info "没有找到遗漏的嵌套模块" + return + fi + + local count=0 + + # 处理每个遗漏的目录 + for old_dir in $remaining_dirs; do + local parent_dir=$(dirname "$old_dir") + local old_name=$(basename "$old_dir") + local new_name=$(echo "$old_name" | sed "s/^$OLD_MODULE_PREFIX-/$NEW_MODULE_PREFIX-/") + local new_dir="$parent_dir/$new_name" + + if [ "$old_dir" != "$new_dir" ]; then + print_info "处理遗漏的模块: $old_name -> $new_name" + + # 重命名目录 + mv "$old_dir" "$new_dir" + + # 更新该模块的POM文件 + local pom_file="$new_dir/pom.xml" + if [ -f "$pom_file" ]; then + local temp_file=$(mktemp) + sed "s|$OLD_GROUP_ID|$NEW_GROUP_ID|g" "$pom_file" | \ + sed "s|$old_name|$new_name|g" | \ + sed "s|$old_name|$new_name|g" | \ + sed "s|$OLD_MODULE_PREFIX-|$NEW_MODULE_PREFIX-|g" > "$temp_file" + + mv "$temp_file" "$pom_file" + print_info "更新模块POM: $new_name/pom.xml" + fi + + ((count++)) + fi + done + + # 最后检查父级POM文件,确保模块引用已更新 + print_info "最终检查父级POM文件的模块引用..." + local parent_poms=$(find "$PROJECT_DIR" -name "pom.xml" -type f) + + for pom_file in $parent_poms; do + if grep -q "$OLD_MODULE_PREFIX-" "$pom_file"; then + local temp_file=$(mktemp) + sed "s|$OLD_MODULE_PREFIX-|$NEW_MODULE_PREFIX-|g" "$pom_file" | \ + sed "s|$OLD_MODULE_PREFIX-|$NEW_MODULE_PREFIX-|g" > "$temp_file" + + mv "$temp_file" "$pom_file" + print_info "更新父级POM引用: $(basename $(dirname $pom_file))/pom.xml" + fi + done + + print_success "已处理 $count 个遗漏的嵌套模块" +} + +# 修复已经重复的包名 +fix_duplicate_packages() { + print_step "步骤 10: 修复重复包名" + + local all_files=$(find "$PROJECT_DIR" -name "*.java" -o -name "*.xml" -o -name "*.yml" -o -name "*.yaml" -o -name "*.properties" | grep -v target) + local count=0 + + # 检查常见的重复模式 + local duplicate_patterns=( + "org\.leocoder\.org\.leocoder" + "org\.leocoder\.thin\.org\.leocoder" + "org\.leocoder\.course\.org\.leocoder" + "org\.leocoder\.estate\.org\.leocoder" + ) + + for file in $all_files; do + local modified=false + local temp_file=$(mktemp) + + # 处理每个重复模式 + cp "$file" "$temp_file" + + for pattern in "${duplicate_patterns[@]}"; do + if grep -q "$pattern" "$temp_file"; then + # 修复重复的包名,保留最后一个正确的部分 + case "$pattern" in + "org\.leocoder\.org\.leocoder") + sed -i "s|org\.leocoder\.org\.leocoder|org.leocoder|g" "$temp_file" + modified=true + ;; + "org\.leocoder\.thin\.org\.leocoder") + sed -i "s|org\.leocoder\.thin\.org\.leocoder|org.leocoder|g" "$temp_file" + modified=true + ;; + "org\.leocoder\.course\.org\.leocoder") + sed -i "s|org\.leocoder\.course\.org\.leocoder|org.leocoder.course|g" "$temp_file" + modified=true + ;; + "org\.leocoder\.estate\.org\.leocoder") + sed -i "s|org\.leocoder\.estate\.org\.leocoder|org.leocoder.estate|g" "$temp_file" + modified=true + ;; + esac + fi + done + + # 通用重复修复:修复任何 org.leocoder.*.org.leocoder.* 的模式 + if grep -q "org\.leocoder\.[^.]*\.org\.leocoder" "$temp_file"; then + sed -i "s|org\.leocoder\.[^.]*\.org\.leocoder|org.leocoder|g" "$temp_file" + modified=true + fi + + # 检查是否有实际变化 + if [ "$modified" = true ] && ! diff "$file" "$temp_file" > /dev/null; then + mv "$temp_file" "$file" + print_info "修复重复包名: $(basename $file)" + ((count++)) + else + rm -f "$temp_file" + fi + done + + print_success "已修复 $count 个文件中的重复包名" +} + # 重命名SQL文件 rename_sql_files() { - print_step "步骤 9: 重命名 SQL 文件" + print_step "步骤 11: 重命名 SQL 文件" local sql_files=$(find "$PROJECT_DIR" -name "*.sql" -type f | grep -i "$OLD_MODULE_PREFIX") local count=0 @@ -415,7 +660,7 @@ rename_sql_files() { # 清理临时文件 cleanup() { - print_step "步骤 10: 清理和验证" + print_step "步骤 12: 清理和验证" # 清理可能遗留的备份文件 find "$PROJECT_DIR" -name "*.bak" -type f -delete 2>/dev/null @@ -457,6 +702,8 @@ main() { update_xml_files update_config_files rename_directories + process_nested_modules + fix_duplicate_packages rename_sql_files cleanup diff --git a/script/simple-fix.sh b/script/simple-fix.sh new file mode 100755 index 0000000..7e73017 --- /dev/null +++ b/script/simple-fix.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# 简单目录修复脚本 +# Author: Leocoder + +echo "开始修复目录结构..." + +PROJECT_DIR="/Users/leocoder/leocoder/develop/2025/estate/coder-estate-backend" + +# 1. 删除所有错误的org目录结构 +echo "删除错误的目录结构..." +find "$PROJECT_DIR" -type d -path "*/org/leocoder/org/leocoder*" -exec rm -rf {} + 2>/dev/null + +# 2. 清理空的org目录 +echo "清理空目录..." +find "$PROJECT_DIR" -type d -name "org" -empty -delete 2>/dev/null + +# 3. 查找所有包含重复包名的Java文件并修复 +echo "修复Java文件中的包名..." +find "$PROJECT_DIR" -name "*.java" -exec sed -i '' 's|org\.leocoder\.org\.leocoder\.estate|org.leocoder.estate|g' {} + 2>/dev/null +find "$PROJECT_DIR" -name "*.java" -exec sed -i '' 's|org\.leocoder\.org\.leocoder|org.leocoder|g' {} + 2>/dev/null + +# 4. 修复XML文件中的包名 +echo "修复XML文件中的包名..." +find "$PROJECT_DIR" -name "*.xml" -exec sed -i '' 's|org\.leocoder\.org\.leocoder\.estate|org.leocoder.estate|g' {} + 2>/dev/null +find "$PROJECT_DIR" -name "*.xml" -exec sed -i '' 's|org\.leocoder\.org\.leocoder|org.leocoder|g' {} + 2>/dev/null + +# 5. 验证结果 +echo "验证修复结果..." +duplicate_count=$(find "$PROJECT_DIR" -type d -path "*/org/leocoder/org/leocoder*" | wc -l) +if [ "$duplicate_count" -eq 0 ]; then + echo "✅ 目录结构修复成功!" +else + echo "⚠️ 仍然存在 $duplicate_count 个重复目录" +fi + +# 6. 统计Java文件数量 +java_count=$(find "$PROJECT_DIR" -name "*.java" -path "*/org/leocoder/estate/*" | wc -l) +echo "📊 Java文件总数: $java_count" + +echo "修复完成!" \ No newline at end of file