Files
script/homebrew/brew-upgrade-manager-bootstrap.sh
T
orion ff54bffc53 ♻️ refactor(core): 优化 Homebrew 智能升级管理脚本
* 优化 Shell 环境设置,采用 set -euo pipefail 提升脚本鲁棒性
* 改进路径处理逻辑,动态按需向 PATH 注入 Homebrew 常用路径
* 增强失败隔离机制,实现 Cask 批量失败后仅对过期项精准重试
* 优化临时文件管理,改用临时目录并在退出时自动清理相关资源
* 完善网络容错能力,在 bootstrap 阶段增加 curl 重试与超时限制
* 更新文档说明,同步最新的升级策略、并发控制及错误处理逻辑
* 引入终端动态宽度支持,优化非交互式环境下的输出展示效果
2026-07-17 00:30:07 +08:00

108 lines
3.5 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.
#!/usr/bin/env bash
# 目标:下载远程升级脚本、执行、销毁临时文件
set -euo pipefail
REMOTE="https://git.orionc.me/orion/script/raw/branch/main/homebrew/brew-upgrade-manager.sh"
TEMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/brew-upgrade-manager.XXXXXX")"
TEMP="$TEMP_DIR/brew-upgrade-manager.sh"
ASKPASS_TEMP="$TEMP_DIR/brewup-askpass.sh"
KEYCHAIN_SERVICE="${BREWUP_KEYCHAIN_SERVICE:-brewup-sudo-password}"
CURRENT_USER="${USER:-$(id -un)}"
cleanup() {
rm -f "$TEMP" "$ASKPASS_TEMP"
rmdir "$TEMP_DIR" 2>/dev/null || true
}
on_interrupt() {
exit 130
}
on_terminate() {
exit 143
}
trap cleanup EXIT
trap on_interrupt INT
trap on_terminate TERM
PATH="/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin"
export PATH
download_retries="${BREWUP_DOWNLOAD_RETRIES:-3}"
download_retry_delay="${BREWUP_DOWNLOAD_RETRY_DELAY_SECONDS:-2}"
connect_timeout="${BREWUP_CONNECT_TIMEOUT_SECONDS:-15}"
speed_time="${BREWUP_LOW_SPEED_TIME_SECONDS:-30}"
[[ "$download_retries" =~ ^[1-9][0-9]*$ ]] || download_retries=3
[[ "$download_retry_delay" =~ ^[0-9]+$ ]] || download_retry_delay=2
[[ "$connect_timeout" =~ ^[1-9][0-9]*$ ]] || connect_timeout=15
[[ "$speed_time" =~ ^[1-9][0-9]*$ ]] || speed_time=30
curl_retry_all_errors=()
if curl --help all 2>/dev/null | grep -q -- '--retry-all-errors'; then
curl_retry_all_errors+=(--retry-all-errors)
fi
echo "正在下载远程脚本..."
curl -f -sSL \
--connect-timeout "$connect_timeout" \
--speed-limit 1024 \
--speed-time "$speed_time" \
--retry "$download_retries" \
--retry-delay "$download_retry_delay" \
"${curl_retry_all_errors[@]}" \
"$REMOTE" -o "$TEMP"
[[ -s "$TEMP" ]] || { echo "远程脚本为空,已停止执行。" >&2; exit 1; }
if [[ -n "${BREWUP_SHA256:-}" ]]; then
echo "正在校验脚本 SHA256..."
actual_sha256="$(shasum -a 256 "$TEMP")"
actual_sha256="${actual_sha256%% *}"
if [[ "$actual_sha256" != "$BREWUP_SHA256" ]]; then
echo "脚本 SHA256 不匹配,已停止执行。" >&2
echo "Expected: $BREWUP_SHA256" >&2
echo "Actual: $actual_sha256" >&2
exit 1
fi
fi
bash -n "$TEMP"
if [[ "${BREWUP_DEBUG:-0}" == "1" ]]; then
echo "Downloaded script first line:"
head -n 1 "$TEMP"
fi
setup_sudo_askpass() {
cat > "$ASKPASS_TEMP" <<'EOF'
#!/usr/bin/env bash
exec /usr/bin/security find-generic-password \
-a "${BREWUP_KEYCHAIN_ACCOUNT:-${USER:-$(id -un)}}" \
-s "${BREWUP_KEYCHAIN_SERVICE:-brewup-sudo-password}" -w
EOF
chmod 700 "$ASKPASS_TEMP"
export SUDO_ASKPASS="$ASKPASS_TEMP"
export BREWUP_KEYCHAIN_SERVICE="$KEYCHAIN_SERVICE"
export BREWUP_KEYCHAIN_ACCOUNT="$CURRENT_USER"
if ! /usr/bin/security find-generic-password -a "$CURRENT_USER" -s "$KEYCHAIN_SERVICE" -w >/dev/null 2>&1; then
printf "首次使用:请输入一次 sudo 密码,将保存到 macOS Keychain"
IFS= read -r -s BREWUP_SUDO_PASSWORD
printf '\n'
/usr/bin/security add-generic-password -U -a "$CURRENT_USER" -s "$KEYCHAIN_SERVICE" -w "$BREWUP_SUDO_PASSWORD" >/dev/null
unset BREWUP_SUDO_PASSWORD
fi
echo "正在通过 Keychain 准备 sudo 凭据..."
if ! sudo -A -v; then
echo "Keychain 中的 sudo 密码不可用,请删除后重新保存:" >&2
echo " security delete-generic-password -a \"$CURRENT_USER\" -s \"$KEYCHAIN_SERVICE\"" >&2
exit 1
fi
}
setup_sudo_askpass
export COLUMNS="${COLUMNS:-130}"
bash "$TEMP" "$@"