refactor(homebrew): 重构脚本中的颜色输出和错误处理功能
- 添加了 RED 颜色常量定义和相应的颜色代码调整 - 替换了原有的 echo 命令为新的打印函数(如 print_error、print_warning 等) - 实现了统一的错误消息输出格式,使用 print_error 函数 - 优化了颜色输出的实现方式,使用 printf 替代 echo -e - 在 bootstrap 脚本中也实现了类似的颜色输出和错误处理函数 - 统一了脚本中的消息输出格式和样式
This commit is contained in:
@@ -20,13 +20,15 @@ export PATH
|
||||
export HOMEBREW_NO_INSTALL_CLEANUP=1
|
||||
|
||||
if [[ -t 1 ]]; then
|
||||
GREEN='\033[1;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[1;34m'
|
||||
CYAN='\033[1;36m'
|
||||
RED='\033[31m'
|
||||
GREEN='\033[32m'
|
||||
YELLOW='\033[33m'
|
||||
BLUE='\033[34m'
|
||||
CYAN='\033[36m'
|
||||
NC='\033[0m'
|
||||
export HOMEBREW_COLOR=1
|
||||
else
|
||||
RED=''
|
||||
GREEN=''
|
||||
YELLOW=''
|
||||
BLUE=''
|
||||
@@ -57,7 +59,7 @@ parse_args() {
|
||||
while (($# > 0)); do
|
||||
case "$1" in
|
||||
--width)
|
||||
[[ $# -ge 2 ]] || { echo "Error: --width requires a value." >&2; exit 2; }
|
||||
[[ $# -ge 2 ]] || { print_error "--width requires a value."; exit 2; }
|
||||
TERMINAL_WIDTH="$2"
|
||||
shift 2
|
||||
;;
|
||||
@@ -70,7 +72,7 @@ parse_args() {
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Error: Unknown argument: $1" >&2
|
||||
print_error "Unknown argument: $1"
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
@@ -88,7 +90,7 @@ resolve_terminal_width() {
|
||||
[[ -n "$TERMINAL_WIDTH" ]] || TERMINAL_WIDTH=130
|
||||
|
||||
if [[ ! "$TERMINAL_WIDTH" =~ ^[0-9]+$ ]] || ((TERMINAL_WIDTH < 40 || TERMINAL_WIDTH > 500)); then
|
||||
echo "Error: terminal width must be an integer between 40 and 500." >&2
|
||||
print_error "terminal width must be an integer between 40 and 500."
|
||||
exit 2
|
||||
fi
|
||||
export COLUMNS="$TERMINAL_WIDTH"
|
||||
@@ -96,14 +98,35 @@ resolve_terminal_width() {
|
||||
|
||||
separator() {
|
||||
local i
|
||||
printf '%b' "$BLUE"
|
||||
for ((i = 0; i < TERMINAL_WIDTH; i++)); do
|
||||
printf '='
|
||||
done
|
||||
printf '\n'
|
||||
printf '%b\n' "$NC"
|
||||
}
|
||||
|
||||
print_header() {
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
printf '%b%s%b\n' "$BLUE" "$1" "$NC"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
printf '%bError:%b %s\n' "$RED" "$NC" "$*" >&2
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
printf '%bWarning:%b %s\n' "$YELLOW" "$NC" "$*"
|
||||
}
|
||||
|
||||
print_notice() {
|
||||
printf '%b%s%b\n' "$YELLOW" "$*" "$NC"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
printf '%b%s%b\n' "$GREEN" "$*" "$NC"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
printf '%b%s%b\n' "$CYAN" "$*" "$NC"
|
||||
}
|
||||
|
||||
is_enabled() {
|
||||
@@ -157,17 +180,17 @@ acquire_lock() {
|
||||
IFS= read -r existing_pid < "$LOCK_DIR/pid" || true
|
||||
fi
|
||||
if [[ "$existing_pid" =~ ^[0-9]+$ ]] && kill -0 "$existing_pid" 2>/dev/null; then
|
||||
echo "Error: another brewup process is already running (PID ${existing_pid})." >&2
|
||||
print_error "another brewup process is already running (PID ${existing_pid})."
|
||||
exit 75
|
||||
fi
|
||||
|
||||
rm -f "$LOCK_DIR/pid" 2>/dev/null || true
|
||||
rmdir "$LOCK_DIR" 2>/dev/null || {
|
||||
echo "Error: unable to remove stale lock directory: $LOCK_DIR" >&2
|
||||
print_error "unable to remove stale lock directory: $LOCK_DIR"
|
||||
exit 75
|
||||
}
|
||||
if ! mkdir "$LOCK_DIR" 2>/dev/null; then
|
||||
echo "Error: another brewup process acquired the lock." >&2
|
||||
print_error "another brewup process acquired the lock."
|
||||
exit 75
|
||||
fi
|
||||
LOCK_ACQUIRED=1
|
||||
@@ -216,7 +239,7 @@ run_brew_with_retries() {
|
||||
|
||||
for ((attempt = 1; attempt <= attempts; attempt++)); do
|
||||
if ((attempt > 1)); then
|
||||
echo -e "${YELLOW}Retrying ${label} (${attempt}/${attempts}) after ${delay}s...${NC}"
|
||||
print_info "Retrying ${label} (${attempt}/${attempts}) after ${delay}s..."
|
||||
sleep "$delay"
|
||||
next_delay=$((delay * 2))
|
||||
((next_delay > 300)) && next_delay=300
|
||||
@@ -230,7 +253,7 @@ run_brew_with_retries() {
|
||||
pipeline_status=("${PIPESTATUS[@]}")
|
||||
status="${pipeline_status[0]}"
|
||||
if ((${pipeline_status[1]:-0} != 0)); then
|
||||
echo "Error: failed to write retry log." >&2
|
||||
print_error "failed to write retry log."
|
||||
status="${pipeline_status[1]}"
|
||||
fi
|
||||
fi
|
||||
@@ -251,7 +274,7 @@ run_brew_with_retries() {
|
||||
ACTIVE_LOG_FILE=""
|
||||
return "$status"
|
||||
fi
|
||||
echo -e "${YELLOW}${label} failed with a retryable error.${NC}"
|
||||
print_notice "${label} failed with a retryable error."
|
||||
done
|
||||
}
|
||||
|
||||
@@ -272,20 +295,20 @@ run_formula_upgrade() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Warning: Formula upgrade returned ${bulk_status}; checking remaining Formulae...${NC}"
|
||||
print_warning "Formula upgrade returned ${bulk_status}; checking remaining Formulae..."
|
||||
if ! outdated_formulae="$(get_outdated_formulae)"; then
|
||||
echo -e "${YELLOW}Warning: unable to verify outdated Formulae.${NC}"
|
||||
print_warning "unable to verify outdated Formulae."
|
||||
return "$bulk_status"
|
||||
fi
|
||||
if [[ -z "$outdated_formulae" ]]; then
|
||||
echo -e "${YELLOW}No outdated Formulae remain; treating the bulk error as recovered.${NC}"
|
||||
print_notice "No outdated Formulae remain; treating the bulk error as recovered."
|
||||
return 0
|
||||
fi
|
||||
|
||||
printf '%s\n' "$outdated_formulae"
|
||||
while IFS= read -r formula; do
|
||||
[[ -n "$formula" ]] || continue
|
||||
echo -e "${CYAN}Retrying Formula: ${formula}${NC}"
|
||||
print_info "Retrying Formula: ${formula}"
|
||||
if run_brew_with_retries "Formula ${formula}" upgrade --formula "$formula"; then
|
||||
:
|
||||
else
|
||||
@@ -294,19 +317,19 @@ run_formula_upgrade() {
|
||||
done <<< "$outdated_formulae"
|
||||
|
||||
if ! remaining_formulae="$(get_outdated_formulae)"; then
|
||||
echo -e "${YELLOW}Warning: unable to verify Formulae after individual retries.${NC}"
|
||||
print_warning "unable to verify Formulae after individual retries."
|
||||
FAILED_FORMULAE=("${failed_formulae[@]}")
|
||||
return 1
|
||||
fi
|
||||
if [[ -z "$remaining_formulae" ]]; then
|
||||
echo -e "${GREEN}All outdated Formulae were upgraded after isolated retries.${NC}"
|
||||
print_success "All outdated Formulae were upgraded after isolated retries."
|
||||
return 0
|
||||
fi
|
||||
|
||||
while IFS= read -r formula; do
|
||||
[[ -n "$formula" ]] && FAILED_FORMULAE+=("$formula")
|
||||
done <<< "$remaining_formulae"
|
||||
echo -e "${YELLOW}Formulae still outdated after retries:${NC}"
|
||||
print_warning "Formulae still outdated after retries:"
|
||||
printf '%s\n' "$remaining_formulae"
|
||||
return 1
|
||||
}
|
||||
@@ -318,7 +341,7 @@ run_cask_upgrade() {
|
||||
|
||||
if is_enabled "${HB_CASK_FORCE:-0}"; then
|
||||
bulk_args+=(--force)
|
||||
echo -e "${YELLOW}HB_CASK_FORCE is enabled; existing Cask files may be overwritten.${NC}"
|
||||
print_warning "HB_CASK_FORCE is enabled; existing Cask files may be overwritten."
|
||||
fi
|
||||
|
||||
brew "${bulk_args[@]}" || bulk_status=$?
|
||||
@@ -326,20 +349,20 @@ run_cask_upgrade() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Warning: Cask upgrade returned ${bulk_status}; checking remaining Casks...${NC}"
|
||||
print_warning "Cask upgrade returned ${bulk_status}; checking remaining Casks..."
|
||||
if ! outdated_casks="$(get_outdated_casks)"; then
|
||||
echo -e "${YELLOW}Warning: unable to verify outdated Casks.${NC}"
|
||||
print_warning "unable to verify outdated Casks."
|
||||
return "$bulk_status"
|
||||
fi
|
||||
if [[ -z "$outdated_casks" ]]; then
|
||||
echo -e "${YELLOW}No outdated Casks remain; treating the bulk error as recovered.${NC}"
|
||||
print_notice "No outdated Casks remain; treating the bulk error as recovered."
|
||||
return 0
|
||||
fi
|
||||
|
||||
printf '%s\n' "$outdated_casks"
|
||||
while IFS= read -r cask; do
|
||||
[[ -n "$cask" ]] || continue
|
||||
echo -e "${CYAN}Retrying Cask: ${cask} (without --force)${NC}"
|
||||
print_info "Retrying Cask: ${cask} (without --force)"
|
||||
if run_brew_with_retries "Cask ${cask}" upgrade --cask --greedy "$cask"; then
|
||||
:
|
||||
else
|
||||
@@ -348,19 +371,19 @@ run_cask_upgrade() {
|
||||
done <<< "$outdated_casks"
|
||||
|
||||
if ! remaining_casks="$(get_outdated_casks)"; then
|
||||
echo -e "${YELLOW}Warning: unable to verify Casks after individual retries.${NC}"
|
||||
print_warning "unable to verify Casks after individual retries."
|
||||
FAILED_CASKS=("${failed_casks[@]}")
|
||||
return 1
|
||||
fi
|
||||
if [[ -z "$remaining_casks" ]]; then
|
||||
echo -e "${GREEN}All outdated Casks were upgraded after isolated retries.${NC}"
|
||||
print_success "All outdated Casks were upgraded after isolated retries."
|
||||
return 0
|
||||
fi
|
||||
|
||||
while IFS= read -r cask; do
|
||||
[[ -n "$cask" ]] && FAILED_CASKS+=("$cask")
|
||||
done <<< "$remaining_casks"
|
||||
echo -e "${YELLOW}Casks still outdated after retries:${NC}"
|
||||
print_warning "Casks still outdated after retries:"
|
||||
printf '%s\n' "$remaining_casks"
|
||||
return 1
|
||||
}
|
||||
@@ -388,7 +411,7 @@ prune_cache_before_today() {
|
||||
|
||||
cache_dir="$(brew --cache)"
|
||||
if [[ ! -d "$cache_dir" || "$cache_dir" == "/" || "$cache_dir" == "$HOME" ]]; then
|
||||
echo "Error: Homebrew returned an unsafe cache path: $cache_dir" >&2
|
||||
print_error "Homebrew returned an unsafe cache path: $cache_dir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -402,11 +425,11 @@ prune_cache_before_today() {
|
||||
|
||||
if ! find "$cache_dir" -mindepth 1 \( -type f -o -type l \) \
|
||||
! -newer "$ACTIVE_CLEANUP_MARKER" -print0 > "$ACTIVE_CLEANUP_MANIFEST"; then
|
||||
echo "Error: failed to enumerate Homebrew cache files to remove." >&2
|
||||
print_error "failed to enumerate Homebrew cache files to remove."
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Removed cache files:"
|
||||
printf '%bRemoved cache files:%b\n' "$YELLOW" "$NC"
|
||||
while IFS= read -r -d '' file; do
|
||||
if ! file_size="$(stat -f '%z' -- "$file" 2>/dev/null)"; then
|
||||
file_size=0
|
||||
@@ -415,25 +438,26 @@ prune_cache_before_today() {
|
||||
if rm -f -- "$file"; then
|
||||
removed_count=$((removed_count + 1))
|
||||
removed_bytes=$((removed_bytes + file_size))
|
||||
printf ' %10s %q\n' "$(format_bytes "$file_size")" "$relative_path"
|
||||
printf ' %b%10s%b %q\n' "$CYAN" "$(format_bytes "$file_size")" "$NC" "$relative_path"
|
||||
else
|
||||
echo "Warning: failed to remove cache file: $file" >&2
|
||||
print_warning "failed to remove cache file: $file" >&2
|
||||
cleanup_failed=1
|
||||
fi
|
||||
done < "$ACTIVE_CLEANUP_MANIFEST"
|
||||
if ((removed_count == 0)); then
|
||||
echo " (none)"
|
||||
printf ' (none)\n'
|
||||
fi
|
||||
printf 'Removed %d Homebrew cache file(s) dated before %s (%s total).\n' \
|
||||
"$removed_count" "$cutoff_date" "$(format_bytes "$removed_bytes")"
|
||||
printf '%bRemoved%b %b%d%b Homebrew cache file(s) dated before %b%s%b (%b%s total%b).\n' \
|
||||
"$YELLOW" "$NC" "$CYAN" "$removed_count" "$NC" "$BLUE" "$cutoff_date" "$NC" \
|
||||
"$CYAN" "$(format_bytes "$removed_bytes")" "$NC"
|
||||
|
||||
if ! find "$cache_dir" -mindepth 1 \( -type f -o -type l \) \
|
||||
-newer "$ACTIVE_CLEANUP_MARKER" -print0 > "$ACTIVE_CLEANUP_MANIFEST"; then
|
||||
echo "Error: failed to enumerate today's retained Homebrew cache files." >&2
|
||||
print_error "failed to enumerate today's retained Homebrew cache files."
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Retained cache files dated today or later:"
|
||||
printf '%bRetained cache files dated today or later:%b\n' "$GREEN" "$NC"
|
||||
while IFS= read -r -d '' file; do
|
||||
if ! file_size="$(stat -f '%z' -- "$file" 2>/dev/null)"; then
|
||||
file_size=0
|
||||
@@ -441,13 +465,14 @@ prune_cache_before_today() {
|
||||
relative_path="${file#"$cache_dir"/}"
|
||||
kept_count=$((kept_count + 1))
|
||||
kept_bytes=$((kept_bytes + file_size))
|
||||
printf ' %10s %q\n' "$(format_bytes "$file_size")" "$relative_path"
|
||||
printf ' %b%10s%b %q\n' "$CYAN" "$(format_bytes "$file_size")" "$NC" "$relative_path"
|
||||
done < "$ACTIVE_CLEANUP_MANIFEST"
|
||||
if ((kept_count == 0)); then
|
||||
echo " (none)"
|
||||
printf ' (none)\n'
|
||||
fi
|
||||
printf "Retained %d Homebrew cache file(s) dated %s or later (%s total).\n" \
|
||||
"$kept_count" "$cutoff_date" "$(format_bytes "$kept_bytes")"
|
||||
printf '%bRetained%b %b%d%b Homebrew cache file(s) dated %b%s%b or later (%b%s total%b).\n' \
|
||||
"$GREEN" "$NC" "$CYAN" "$kept_count" "$NC" "$BLUE" "$cutoff_date" "$NC" \
|
||||
"$CYAN" "$(format_bytes "$kept_bytes")" "$NC"
|
||||
|
||||
rm -f "$ACTIVE_CLEANUP_MARKER"
|
||||
ACTIVE_CLEANUP_MARKER=""
|
||||
@@ -460,7 +485,7 @@ run_cleanup() {
|
||||
local cleanup_days="${HB_CLEANUP_DAYS:-}"
|
||||
|
||||
if is_enabled "${HB_SKIP_CLEANUP:-0}"; then
|
||||
echo -e "${YELLOW}Cleanup skipped because HB_SKIP_CLEANUP is enabled.${NC}"
|
||||
print_notice "Cleanup skipped because HB_SKIP_CLEANUP is enabled."
|
||||
return 0
|
||||
fi
|
||||
if is_enabled "${HB_CLEANUP_ALL:-0}" || [[ "$cleanup_days" == "all" ]]; then
|
||||
@@ -469,7 +494,7 @@ run_cleanup() {
|
||||
fi
|
||||
if [[ -n "$cleanup_days" ]]; then
|
||||
if [[ ! "$cleanup_days" =~ ^[0-9]+$ ]] || ((cleanup_days > 3650)); then
|
||||
echo "Error: HB_CLEANUP_DAYS must be an integer between 0 and 3650." >&2
|
||||
print_error "HB_CLEANUP_DAYS must be an integer between 0 and 3650."
|
||||
return 2
|
||||
fi
|
||||
brew cleanup --prune="$cleanup_days"
|
||||
@@ -488,14 +513,14 @@ print_summary() {
|
||||
|
||||
separator
|
||||
if ((overall_status == 0)); then
|
||||
echo -e "${GREEN}All operations completed successfully.${NC}"
|
||||
print_success "All operations completed successfully."
|
||||
else
|
||||
echo -e "${YELLOW}Homebrew upgrade completed with unresolved failures.${NC}"
|
||||
printf '%bHomebrew upgrade completed with unresolved failures.%b\n' "$RED" "$NC"
|
||||
if ((${#FAILED_FORMULAE[@]} > 0)); then
|
||||
printf 'Failed Formulae: %s\n' "${FAILED_FORMULAE[*]}"
|
||||
printf '%bFailed Formulae:%b %s\n' "$RED" "$NC" "${FAILED_FORMULAE[*]}"
|
||||
fi
|
||||
if ((${#FAILED_CASKS[@]} > 0)); then
|
||||
printf 'Failed Casks: %s\n' "${FAILED_CASKS[*]}"
|
||||
printf '%bFailed Casks:%b %s\n' "$RED" "$NC" "${FAILED_CASKS[*]}"
|
||||
fi
|
||||
fi
|
||||
separator
|
||||
@@ -504,8 +529,8 @@ print_summary() {
|
||||
parse_args "$@"
|
||||
resolve_terminal_width
|
||||
|
||||
command -v brew >/dev/null 2>&1 || { echo "Error: Homebrew is not installed or not in PATH." >&2; exit 127; }
|
||||
command -v tee >/dev/null 2>&1 || { echo "Error: tee is required." >&2; exit 127; }
|
||||
command -v brew >/dev/null 2>&1 || { print_error "Homebrew is not installed or not in PATH."; exit 127; }
|
||||
command -v tee >/dev/null 2>&1 || { print_error "tee is required."; exit 127; }
|
||||
acquire_lock
|
||||
|
||||
separator
|
||||
@@ -517,11 +542,11 @@ printf '\n'
|
||||
separator
|
||||
print_header "Step 2: Performing health check (brew doctor)"
|
||||
if is_enabled "${HB_SKIP_DOCTOR:-0}"; then
|
||||
echo -e "${YELLOW}brew doctor skipped because HB_SKIP_DOCTOR is enabled.${NC}"
|
||||
print_notice "brew doctor skipped because HB_SKIP_DOCTOR is enabled."
|
||||
elif ! brew doctor; then
|
||||
echo -e "${YELLOW}Warning: 'brew doctor' detected issues. Manual review is recommended.${NC}"
|
||||
print_warning "'brew doctor' detected issues. Manual review is recommended."
|
||||
else
|
||||
echo "Homebrew environment is in good health."
|
||||
print_success "Homebrew environment is in good health."
|
||||
fi
|
||||
separator
|
||||
printf '\n'
|
||||
@@ -530,12 +555,14 @@ separator
|
||||
print_header "Step 3: Upgrading Formulae and Casks with failure isolation"
|
||||
overall_status=0
|
||||
|
||||
echo -e "\n${CYAN}>>> [1/2] Upgrading CLI Formulae...${NC}"
|
||||
printf '\n'
|
||||
print_info ">>> [1/2] Upgrading CLI Formulae..."
|
||||
if ! run_formula_upgrade; then
|
||||
overall_status=1
|
||||
fi
|
||||
|
||||
echo -e "\n${CYAN}>>> [2/2] Upgrading GUI Casks...${NC}"
|
||||
printf '\n'
|
||||
print_info ">>> [2/2] Upgrading GUI Casks..."
|
||||
if ! run_cask_upgrade; then
|
||||
overall_status=1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user