- 更新script/README.md,增加详细的使用指南和最佳实践 - 新增simple-fix.sh脚本用于快速修复包名重复问题 - 新增fix-duplicate-packages.sh脚本专门处理重复包名检测和修复 - 新增fix-directory-structure.sh脚本用于重建目录结构 - 优化project-refactor.sh脚本,增强重复包名处理能力 - 完善脚本选择建议和问题排查步骤
493 lines
18 KiB
Bash
Executable File
493 lines
18 KiB
Bash
Executable File
#!/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 "$@" |