docs: 完善项目重构脚本功能和文档

- 更新script/README.md,增加详细的使用指南和最佳实践
- 新增simple-fix.sh脚本用于快速修复包名重复问题
- 新增fix-duplicate-packages.sh脚本专门处理重复包名检测和修复
- 新增fix-directory-structure.sh脚本用于重建目录结构
- 优化project-refactor.sh脚本,增强重复包名处理能力
- 完善脚本选择建议和问题排查步骤
This commit is contained in:
Leo 2025-07-09 16:47:36 +08:00
parent eaa150f32d
commit 4a512427ed
5 changed files with 1414 additions and 91 deletions

View File

@ -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
```
脚本会引导你输入以下信息:
- 项目根目录路径
- 旧的 GroupIdorg.leocoder.thin
- 旧的 ArtifactIdcoder-common-thin-backend
- 旧的模块前缀coder-common-thin
- 新的 GroupIdorg.leocoder.course
- 新的 ArtifactIdcoder-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
## 📝 更新日志
### v2.0 (2025-01-09)
- ✅ 新增重复包名检测和修复功能
- ✅ 新增 `simple-fix.sh` 快速修复脚本
- ✅ 新增 `fix-duplicate-packages.sh` 专门修复重复包名
- ✅ 完善了使用指南和最佳实践
- ✅ 增加了详细的问题排查步骤
- ✅ 优化了目录结构处理逻辑
### v1.0 (2025-07-06)
- ✅ 基础项目重构功能
- ✅ 支持POM文件、Java文件、XML文件修改
- ✅ 支持配置文件批量处理
- ✅ 基础的目录结构重命名功能

286
script/fix-directory-structure.sh Executable file
View File

@ -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 "$@"

493
script/fix-duplicate-packages.sh Executable file
View File

@ -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 "$@"

View File

@ -224,13 +224,14 @@ update_pom_files() {
# 创建临时文件
local temp_file=$(mktemp)
# 修改groupId和artifactId
# 修改groupId和artifactId,使用更全面的替换规则
sed "s|<groupId>$OLD_GROUP_ID</groupId>|<groupId>$NEW_GROUP_ID</groupId>|g" "$pom_file" | \
sed "s|<artifactId>$OLD_ARTIFACT_ID</artifactId>|<artifactId>$NEW_ARTIFACT_ID</artifactId>|g" | \
sed "s|<name>$OLD_ARTIFACT_ID</name>|<name>$NEW_ARTIFACT_ID</name>|g" | \
sed "s|<module>$OLD_MODULE_PREFIX-|<module>$NEW_MODULE_PREFIX-|g" | \
sed "s|<artifactId>$OLD_MODULE_PREFIX-|<artifactId>$NEW_MODULE_PREFIX-|g" | \
sed "s|<name>$OLD_MODULE_PREFIX-|<name>$NEW_MODULE_PREFIX-|g" > "$temp_file"
sed "s|<name>$OLD_MODULE_PREFIX-|<name>$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|<groupId>$OLD_GROUP_ID</groupId>|<groupId>$NEW_GROUP_ID</groupId>|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|<!--.*$old_package_escaped\(\.[a-zA-Z0-9_\.]*\).*-->|<!--.*$NEW_PACKAGE\1.*-->|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|<logger name=\"$old_package_escaped|<logger name=\"$NEW_PACKAGE|g" | \
# 修改其他包名引用
sed "s|\"$old_package_escaped\(\.[a-zA-Z0-9_\.]*\)\"|\"$NEW_PACKAGE\1\"|g" | \
# 修改注释中的包名引用
sed "s|# $old_package_escaped|# $NEW_PACKAGE|g" > "$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|<groupId>$OLD_GROUP_ID</groupId>|<groupId>$NEW_GROUP_ID</groupId>|g" "$pom_file" | \
sed "s|<artifactId>$old_name</artifactId>|<artifactId>$new_name</artifactId>|g" | \
sed "s|<name>$old_name</name>|<name>$new_name</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|<module>$OLD_MODULE_PREFIX-|<module>$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

41
script/simple-fix.sh Executable file
View File

@ -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 "修复完成!"