diff --git a/homebrew/README.md b/homebrew/README.md index 0e02b32..4f2331e 100644 --- a/homebrew/README.md +++ b/homebrew/README.md @@ -22,6 +22,7 @@ - 同一用户只能运行一个主脚本实例,避免并发升级争用 Homebrew 锁和 `/Applications`。 - 升级与失败重试全部结束后,执行 `brew cleanup --prune=all` 清理全部缓存和旧版本。 - 支持 `--width`、环境变量宽度和终端动态宽度。 +- 交互式终端中保留 Homebrew 6 的原生实时下载进度条和动态状态。 - 启动器支持通过 macOS Keychain 保存并读取 sudo 密码,用于 `sudo -A -v` 预刷新 sudo 凭据。 ## 依赖 @@ -196,6 +197,8 @@ BREWUP_CONNECT_TIMEOUT_SECONDS=20 BREWUP_LOW_SPEED_TIME_SECONDS=45 brewup 为了兼顾性能,Formula 和 Cask 的批量阶段都只执行一次,只有仍然过期的失败项进入单项重试。单项升级保持串行,因为并行运行多个 Homebrew 写操作会争用 Homebrew 锁和 `/Applications`。用于错误分类的临时日志会在命令结束或收到信号后删除。 +在交互式终端中,主脚本会让 Homebrew 直接连接 TTY,以便 Homebrew 6 实时重绘并行下载进度。需要记录错误以供重试判断时,macOS 自带的 `script(1)` 会创建伪终端并同步保存日志。如果将 `brewup` 输出重定向到文件或 CI,则自动切换为稳定的逐行输出,不绘制动态进度条。 + ## Cask 与清理策略 默认不使用 `--force`。确实需要覆盖已有 Cask 文件时: diff --git a/homebrew/brew-upgrade-manager.sh b/homebrew/brew-upgrade-manager.sh index f8be73c..20d97c6 100644 --- a/homebrew/brew-upgrade-manager.sh +++ b/homebrew/brew-upgrade-manager.sh @@ -573,8 +573,14 @@ colorize_brew_output() { run_brew_colored() { local pipeline_status=() - # 禁用 Homebrew 自带的不完整配色,统一按语义着色。这里不能在 - # 交互式终端直接运行 brew,否则版本变化行会绕过着色器。 + # Homebrew 6 的并行下载队列只有在 stdout 是 TTY 时才会绘制 + # 实时进度。交互式终端中直接运行 brew,保留它的原生进度条与 + # 动态下载状态;重定向到文件或 CI 时再使用按行语义着色。 + if [[ -t 1 ]]; then + env -u HOMEBREW_COLOR brew "$@" + return $? + fi + if env -u HOMEBREW_COLOR brew "$@" 2>&1 | colorize_brew_output; then return 0 fi @@ -698,7 +704,16 @@ run_brew_with_retries() { fi : > "$ACTIVE_LOG_FILE" - if env -u HOMEBREW_COLOR brew "$@" 2>&1 | tee "$ACTIVE_LOG_FILE" | colorize_brew_output; then + if [[ -t 1 && "$(uname -s 2>/dev/null || true)" == "Darwin" && -x /usr/bin/script ]]; then + # tee 会把 brew 的 stdout 变成管道,导致 Homebrew 关闭实时进度。 + # macOS script(1) 为 brew 分配伪终端,同时把完整输出记录到 + # 日志,供后续错误分类与重试决策使用。-F 确保记录实时刷新。 + if /usr/bin/script -qF "$ACTIVE_LOG_FILE" env -u HOMEBREW_COLOR brew "$@"; then + status=0 + else + status=$? + fi + elif env -u HOMEBREW_COLOR brew "$@" 2>&1 | tee "$ACTIVE_LOG_FILE" | colorize_brew_output; then status=0 else pipeline_status=("${PIPESTATUS[@]}")