#!/bin/bash # shellcheck disable=SC2155 if ! type "include" >/dev/null 2>&1; then include() { . "$(cd "$(dirname "$1")" && pwd)/${2}" } fi include "${BASH_SOURCE[0]}" ../pragma_once.bash if ! pragma_once ${BASH_SOURCE[0]}; then return 0; fi include "${BASH_SOURCE[0]}" ./global_rely/export.bash # shellcheck source=./global_rely/export.bash # 目前只是使用第一个url get_git_urls() { local dep="$1" local -n out_urls="$2" case "$dep" in llvm) out_urls=( "https://github.com/llvm/llvm-project.git" "https://gitee.com/mirrors/llvm-project.git" ) ;; gmp) out_urls=( # 这个需要登陆?没法注册 "https://gitlab.inria.fr/gmp/gmp.git" ) ;; mpfr) out_urls=( "https://gitlab.inria.fr/mpfr/mpfr.git" ) ;; mpc) out_urls=( "https://gitlab.inria.fr/mpc/mpc.git" ) ;; llvm-project) out_urls=( "https://github.com/llvm/llvm-project" "https://gitee.com/mirrors/llvm-project.git" ) ;; linux) out_urls=( "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git" "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" "https://mirrors.tuna.tsinghua.edu.cn/git/linux.git" ) ;; glibc) out_urls=( "https://sourceware.org/git/glibc.git" "https://mirrors.tuna.tsinghua.edu.cn/git/glibc.git" ) ;; newlib-cygwin) out_urls=( "https://github.com/mirror/newlib-cygwin.git" ) ;; mingw-w64) out_urls=( "https://github.com/mingw-w64/mingw-w64.git" "https://mirrors.tuna.tsinghua.edu.cn/git/mingw-w64.git" "https://git.code.sf.net/p/mingw-w64/mingw-w64" ) ;; zlib) out_urls=( "https://github.com/madler/zlib.git" "https://gitee.com/mirrors/zlib.git" ) ;; libxml2) out_urls=( "https://gitlab.gnome.org/GNOME/libxml2.git" "https://gitee.com/mirrors/libxml2.git" ) ;; musl) out_urls=( "https://git.musl-libc.org/git/musl" ) ;; binutils-gdb) out_urls=( "https://sourceware.org/git/binutils-gdb.git" "https://mirrors.tuna.tsinghua.edu.cn/git/binutils-gdb.git" ) ;; gcc) out_urls=( "https://gcc.gnu.org/git/gcc.git" "https://gitee.com/mirrors/gcc.git" ) ;; windows-msvc-sysroot) out_urls=( "https://github.com/trcrsired/windows-msvc-sysroot.git" ) ;; cppwinrt) out_urls=( "https://github.com/microsoft/cppwinrt.git" "https://gitee.com/qabeowjbtkwb/cppwinrt.git" ) ;; Qt) out_urls=( "https://github.com/qt/qt5.git" ) ;; cpython) out_urls=( "https://github.com/python/cpython.git" ) ;; cef) out_urls=( "https://github.com/chromiumembedded/cef.git" ) ;; *) log_error "未知依赖:${dep}" return 1 ;; esac } get_repo_refs_local() { local repo_dir="$1" local -n out_branches="$2" local -n out_tags="$3" if [[ ! -d "${repo_dir}/.git" ]]; then log_error "不是 git 仓库: ${repo_dir}" return 1 fi pushd "$repo_dir" >/dev/null || return 1 mapfile -t out_branches < <( git branch --format='%(refname:short)' ) mapfile -t out_tags < <( git tag --sort=-version:refname ) popd >/dev/null } get_repo_refs_remote() { local repo_url="$1" local -n out_branches="$2" local -n out_tags="$3" if [[ -z "$repo_url" ]]; then log_error "repo_url 为空" return 1 fi mapfile -t out_branches < <( git ls-remote --heads "$repo_url" | awk '{print $2}' | sed 's#refs/heads/##' ) mapfile -t out_tags < <( git ls-remote --tags "$repo_url" | grep -v '\^{}' | awk '{print $2}' | sed 's#refs/tags/##' ) } repo_has_ver_local() { local repo_dir="$1" local ver="$2" local branches=() local tags=() get_repo_refs_local "$repo_dir" branches tags || return 1 for b in "${branches[@]}"; do [[ "$b" == "$ver" ]] && return 0 done for t in "${tags[@]}"; do [[ "$t" == "$ver" ]] && return 0 done return 1 } repo_has_ver_remote() { local repo_url="$1" local ver="$2" local branches=() local tags=() get_repo_refs_remote "$repo_url" branches tags || return 1 for b in "${branches[@]}"; do [[ "$b" == "$ver" ]] && return 0 done for t in "${tags[@]}"; do [[ "$t" == "$ver" ]] && return 0 done return 1 } print_repo_refs_local() { local repo_dir="${1:-.}" log_info "========== 本地仓库信息 ==========" log_info "路径: 【${repo_dir}】" if [[ ! -d "${repo_dir}/.git" ]]; then log_error "不是 git 仓库" return 1 fi pushd "$repo_dir" >/dev/null || return 1 log_info "\n当前 HEAD:" git rev-parse --short HEAD log_info "\n当前分支:" git branch --show-current popd >/dev/null local branches=() local tags=() get_repo_refs_local "$repo_dir" branches tags log_info "本地 Branch:" printf '%s' "${branches[@]:0:20}" log_info "Tag 列表:" printf '%s' "${tags[@]:0:20}" log_info "远端地址:" git -C "$repo_dir" remote -v } print_array_in_columns() { local -n arr_ref="$1" local cols="${2:-3}" if ((cols < 1)); then cols=1 fi local count="${#arr_ref[@]}" if ((count == 0)); then printf '无\n' return 0 fi local max_width=0 local item for item in "${arr_ref[@]}"; do if ((${#item} > max_width)); then max_width="${#item}" fi done local cell_width=$((max_width + 2)) local rows=$(((count + cols - 1) / cols)) local r c idx for ((r = 0; r < rows; r++)); do for ((c = 0; c < cols; c++)); do idx=$((c * rows + r)) if ((idx < count)); then printf "%-*s" "$cell_width" "${arr_ref[idx]}" fi done printf '\n' done } print_repo_refs_remote() { local repo_url="$1" local cols="${2:-4}" log_info "========== 远端仓库信息 ==========" log_info "URL: 【$repo_url】" local branches=() local tags=() get_repo_refs_remote "$repo_url" branches tags || return 1 log_info "远端 Branch:" print_array_in_columns branches "$cols" log_info "远端 Tag:" print_array_in_columns tags "$cols" } get_latest_git_tag() { local repo_url="$1" git ls-remote --tags "$repo_url" | grep -v '\^{}' | awk '{print $2}' | sed 's#refs/tags/##' | sort -V | tail -n 1 } export use_network=1 # ver 指的是 git 的 branch 或者 tag ensure_repo_version() { local -n repo_dir=$1 local dep="$2" local ver="$3" repo_dir="${_git_cache_dir_}/${dep}" local urls=() log_info "ensure_repo_version ${dep} ${ver}" get_git_urls "$dep" urls || exit $? local repo_url="${urls[0]}" log_info "检查是否需要克隆" if [[ ! -d "$repo_dir/.git" ]]; then log_info "克隆仓库: $repo_url → $repo_dir" exec_record_fast_fail "git clone --origin origin \"$repo_url\" \"$repo_dir\" " fi log_info "测试本地是否有版本" if repo_has_ver_local "$repo_dir" "$ver"; then log_info "checkout $ver" exec_record_fast_fail "git -C \"$repo_dir\" checkout \"$ver\" " return 0 fi log_info "fetch 更新仓库" exec_record_fast_fail "git -C \"$repo_dir\" fetch --tags origin" if repo_has_ver_local "$repo_dir" "$ver"; then log_info "checkout $ver" exec_record_fast_fail "git -C \"$repo_dir\" checkout \"$ver\" " return 0 fi if git -C "$repo_dir" show-ref --verify --quiet "refs/remotes/origin/$ver"; then log_info "checkout branch $ver" exec_record_fast_fail "git -C \"$repo_dir\" checkout -B \"$ver\" \"origin/$ver\" " return 0 fi log_error "远端仓库不存在版本: $ver" print_repo_refs_remote "$repo_url" exit 3 } #configure_git_repo(){ # local dep="$1" # local ver="$2" # local opts="$3" # ensure_repo_version "${dep}" "${ver}" # local repo_dir="${_git_cache_dir_}/${dep}" # configure_gnu_ex "${repo_dir}" "$opts" #}