Files
Zoomatch_unity_ios/submodule_script.sh
T
2026-05-28 15:23:36 +08:00

243 lines
6.6 KiB
Bash

#!/bin/bash
# 配置文件
CONFIG_FILE="submodule_config.ini"
# 定义颜色常量
RED='\033[31mi'
BLUE='\033[34m'
YELLOW='\033[33m'
GREEN='\033[32m'
NC='\033[0m' # No Color
# 函数:显示帮助信息
show_help() {
echo "Usage: $0 [-h] [-i] [-up]"
echo " -h 显示帮助信息"
echo " -i 根据.gitmodules初始化子模块"
echo " -up 根据配置文件更新子模块"
}
# 检查配置文件是否存在
if [[ ! -f "$CONFIG_FILE" ]]; then
echo -e "${RED}配置文件 $CONFIG_FILE 不存在!${NC}"
exit 1
fi
# 检查 .gitmodules 文件是否存在
if [[ ! -f ".gitmodules" ]]; then
touch .gitmodules
fi
# 普通数组和模拟的关联数组
module_list=() # 用来存储模块名列表
config_array=() # 用来存储键值对
# 函数:从 INI 文件中读取所有字段并存储在普通数组中
parse_ini_all() {
local section=""
while IFS= read -r line || [[ -n "$line" ]]; do
# 去除前后空格
line="${line#"${line%%[![:space:]]*}"}" # 去掉前面的空格
line="${line%"${line##*[![:space:]]}"}" # 去掉后面的空格
# 跳过注释和空行
[[ "$line" =~ ^\s*(#|$) ]] && continue
# 如果是新的 section
if [[ "$line" =~ ^\[(.*)\]$ ]]; then
section="${BASH_REMATCH[1]}"
module_list+=("$section") # 添加 module 名到 module_list 数组中
elif [[ "$line" =~ ^([^=]+)=(.*)$ ]]; then
key="${BASH_REMATCH[1]//[[:space:]]/}" # 去掉键的空格
value="${BASH_REMATCH[2]//[[:space:]]/}" # 去掉值的空格
# 构造键值对并存储在数组中
config_array+=("$section.$key=$value")
fi
done < "$CONFIG_FILE"
}
# 函数:根据键获取值
get_value() {
local key=$1
for entry in "${config_array[@]}"; do
if [[ "$entry" == "$key="* ]]; then
echo "${entry#*=}" # 输出值
return
fi
done
echo ""
}
# 函数:检查远程仓库是否包含指定版本标签
check_tag_exists() {
local repo_url=$1
local version_tag=$2
git ls-remote --tags "$repo_url" | grep -q "refs/tags/$version_tag"
if [[ $? -ne 0 ]]; then
echo -e "${RED}仓库: $repo_url 版本标签 $version_tag 不存在!${NC}"
return 1
fi
return 0
}
# 函数:获取当前子模块的版本标签
get_current_version() {
local target_dir=$1
cd "$target_dir" || return 1
# 尝试获取当前HEAD指向的标签名
current_version=$(git tag --points-at HEAD)
# 如果没有标签名,则返回commit的SHA
if [[ -z "$current_version" ]]; then
current_version=$(git rev-parse HEAD)
fi
cd - > /dev/null || return 1
echo "$current_version"
}
# 函数:初始化子模块
init_submodule() {
local module=$1
local repo_url=$2
local target_dir=$3
local version_tag=$4
# 检查子模块路径是否已经存在
if [[ -f "$target_dir/.git" ]]; then
# 存在子模块,获取当前版本
current_version=$(get_current_version "$target_dir")
# 如果当前版本和目标版本相同,直接返回
if [[ "$current_version" == "$version_tag" ]]; then
echo -e "${GREEN}子模块: $module 已经是版本: $version_tag 无需更新${NC}"
return 0
else
if ! check_tag_exists "$repo_url" "$version_tag"; then
return 1
fi
fi
else
# 子模块不存在,检查远程版本标签
echo -e "${YELLOW}子模块: $module 不存在,添加子模块...${NC}"
if ! check_tag_exists "$repo_url" "$version_tag"; then
return 1
fi
# 添加子模块
git submodule add --force "$repo_url" "$target_dir"
if [[ $? -ne 0 ]]; then
echo -e "${RED}子模块: $module($target_dir) 添加失败!${NC}"
return 1
fi
fi
# 子模块已存在或成功添加,尝试切换到指定版本
cd "$target_dir" || return 1
echo "子模块: $module 切换到版本: $version_tag"
# 更新标签并切换到指定的版本标签
git fetch --tags > /dev/null 2>&1
git checkout "tags/$version_tag" > /dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo -e "${RED}$module 版本切换失败: $version_tag${NC}"
cd - > /dev/null || return 1
return 1
fi
cd - > /dev/null || return 1
echo -e "${GREEN}子模块: $module($target_dir) 初始化完成,版本: $version_tag\n${NC}"
return 0
}
# 函数:删除配置文件中已经不存在的子模块
remove_deleted_submodules() {
# 获取当前子模块列表
current_submodules=$(git config --file .gitmodules --name-only --get-regexp path | sed 's/^submodule\.//;s/\.path$//')
for submodule in $current_submodules; do
# 获取当前子模块的路径
submodule_path=$(git config --file .gitmodules --get submodule."$submodule".path)
# 标志:是否在配置文件中找到该子模块
found_in_config=false
# 遍历配置文件中的模块,检查是否存在
for module in "${module_list[@]}"; do
if [[ "$submodule_path" == "$(get_value "$module.target_dir")" ]]; then
found_in_config=true
break
fi
done
# 如果在配置文件中没有找到子模块,则删除它
if [[ "$found_in_config" == false ]]; then
echo -e "${YELLOW}子模块: $submodule_path 已从配置文件中删除,正在删除...${NC}"
git submodule deinit -f "$submodule_path" > /dev/null 2>&1
git rm -f "$submodule_path" > /dev/null 2>&1
rm -rf .git/modules/"$submodule_path"
echo -e "${GREEN}子模块: $submodule_path 已成功删除!${NC}"
fi
done
}
update_submodule(){
# 调用 parse_ini_all 函数,读取所有配置
parse_ini_all
# 调用删除函数,清理已删除的子模块
remove_deleted_submodules
# 遍历所有模块的 section
for module in "${module_list[@]}"; do
repo_url=$(get_value "$module.repo_url")
target_dir=$(get_value "$module.target_dir")
version_tag=$(get_value "$module.version_tag")
if [[ -z "$repo_url" || -z "$target_dir" || -z "$version_tag" ]]; then
echo -e "${YELLOW}跳过无效配置:$module${NC}"
continue
fi
init_submodule "$module" "$repo_url" "$target_dir" "$version_tag"
if [[ $? -ne 0 ]]; then
echo -e "${RED}子模块 $target_dir 初始化失败,退出...${NC}"
exit 1
fi
done
echo -e "${GREEN}所有子模块已成功同步到指定版本!${NC}"
}
# 解析脚本参数
case "$1" in
-h )
show_help
exit 0
;;
-i )
echo -e "${BLUE}根据.gitmodules初始化子模块...${NC}"
git submodule update --init --recursive
git submodule status
echo -e "${GREEN}初始化子模块成功!${NC}"
exit 0
;;
-up )
echo -e "${BLUE}根据配置文件更新子模块...${NC}"
update_submodule
exit 0
;;
* )
show_help
exit 1
;;
esac