coder-common-thin-backend/script/fix-duplicate-packages.sh
Leo 4a512427ed docs: 完善项目重构脚本功能和文档
- 更新script/README.md,增加详细的使用指南和最佳实践
- 新增simple-fix.sh脚本用于快速修复包名重复问题
- 新增fix-duplicate-packages.sh脚本专门处理重复包名检测和修复
- 新增fix-directory-structure.sh脚本用于重建目录结构
- 优化project-refactor.sh脚本,增强重复包名处理能力
- 完善脚本选择建议和问题排查步骤
2025-07-09 16:47:36 +08:00

493 lines
18 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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 "$@"