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