11#! /usr/bin/env bash
22set -euo pipefail
33trap ' ' PIPE
4+ # Graceful interrupt handling
5+ INTERRUPTED=0
6+ trap ' INTERRUPTED=1; echo; echo "⚠️ Interrupted. Partial summary:"; print_summary; exit 130' INT
47
58DIR=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) "
69ROOT=" $( cd " $DIR /.." && pwd) "
710VERBOSE=" ${VERBOSE:- 0} "
11+ # Suppress Homebrew auto-update during upgrade runs to reduce noise
12+ export HOMEBREW_NO_AUTO_UPDATE=1
813OFFLINE=" ${OFFLINE:- 0} "
914CLI=" ${PYTHON:- python3} "
1015
1116# Ignore pins: IGNORE_PINS=1 to show all tools regardless of pin status
1217IGNORE_PINS=" ${IGNORE_PINS:- 0} "
1318
19+ # Summary counters
20+ SUMMARY_UPDATED=0
21+ SUMMARY_INSTALLED=0
22+ SUMMARY_SKIPPED=0
23+ SUMMARY_FAILED=0
24+ SUMMARY_REMOVED=0
25+
26+ print_summary () {
27+ echo " ================================================================================"
28+ echo " Summary (interrupted)"
29+ echo " ================================================================================"
30+ printf " Updated: %d\n" " $SUMMARY_UPDATED "
31+ printf " Removed: %d\n" " $SUMMARY_REMOVED "
32+ printf " Skipped: %d\n" " $SUMMARY_SKIPPED "
33+ printf " Failed: %d\n" " $SUMMARY_FAILED "
34+ echo
35+ }
36+
1437# Category filter: CATEGORY=python,go or --category=python
1538CATEGORY_FILTER=" ${CATEGORY:- } "
1639for arg in " $@ " ; do
@@ -241,6 +264,7 @@ process_tool() {
241264 printf " installed: %s via %s\n" " $installed " " $method "
242265 printf " target: %s (same)\n" " $( osc8 " $url " " $latest " ) "
243266 check_multi_installs " $catalog_tool "
267+ SUMMARY_SKIPPED=$(( SUMMARY_SKIPPED + 1 ))
244268 printf " up-to-date; skipping.\n"
245269 return 0
246270 fi
@@ -264,7 +288,11 @@ process_tool() {
264288 # BUT: multi-version tools always prompt (more significant operation)
265289 if [ " $auto_update " = " true" ] && [ -z " $is_multi_version " ]; then
266290 printf " \n==> %s %s [auto-update]\n" " $icon " " $display "
267- printf " installed: %s via %s\n" " ${installed:- <none>} " " ${method:- unknown} "
291+ if [ -z " $installed " ]; then
292+ printf " installed: not installed\n"
293+ else
294+ printf " installed: %s via %s\n" " $installed " " ${method:- unknown} "
295+ fi
268296 printf " target: %s\n" " $( osc8 " $url " " ${latest:- <unknown>} " ) "
269297 check_multi_installs " $catalog_tool "
270298 printf " auto-updating...\n"
@@ -297,14 +325,19 @@ process_tool() {
297325 reload_audit_json
298326 # Clean up any already-current marker left by installer
299327 rm -f " /tmp/.cli-audit/${catalog_tool} .already-current"
328+ SUMMARY_UPDATED=$(( SUMMARY_UPDATED + 1 ))
300329 return 0
301330 fi
302331
303332 # Prompt for installation/update
304333 printf " \n==> %s %s\n" " $icon " " $display "
305334 [ -n " $description " ] && printf " %s\n" " $description "
306335 [ -n " $homepage " ] && printf " Homepage: %s\n" " $( osc8 " $homepage " " $homepage " ) "
307- printf " installed: %s via %s\n" " ${installed:- <none>} " " ${method:- unknown} "
336+ if [ -z " $installed " ]; then
337+ printf " installed: not installed\n"
338+ else
339+ printf " installed: %s via %s\n" " $installed " " ${method:- unknown} "
340+ fi
308341
309342 check_multi_installs " $catalog_tool "
310343
@@ -335,7 +368,7 @@ process_tool() {
335368 fi
336369 printf " r = Remove/uninstall this tool\n"
337370 if [ -n " $is_multi_version " ]; then
338- printf " P = Skip ALL %s cycles (never install any %s)\n " " $catalog_tool " " $catalog_tool "
371+ printf " P = Skip ALL outdated %s cycles\n " " $catalog_tool "
339372 fi
340373 else
341374 printf " y = Install now\n"
@@ -344,7 +377,7 @@ process_tool() {
344377 printf " s = Skip only %s (ask again when newer patch available)\n" " $latest "
345378 if [ -n " $is_multi_version " ]; then
346379 printf " p = Never install %s (skip entire %s.x cycle)\n" " $display " " $version_cycle "
347- printf " P = Skip ALL %s cycles (never install any %s)\n " " $catalog_tool " " $catalog_tool "
380+ printf " P = Skip ALL outdated %s cycles\n " " $catalog_tool "
348381 else
349382 printf " p = Never install (permanently skip this tool)\n"
350383 fi
@@ -419,6 +452,7 @@ process_tool() {
419452 if [ " $upgrade_success " = " 0" ]; then
420453 # Install script failed
421454 printf " \n ⚠️ Upgrade failed (install script error)\n"
455+ SUMMARY_FAILED=$(( SUMMARY_FAILED + 1 ))
422456 prompt_pin_version " $tool " " $installed "
423457 elif [ -n " $binary_already_current " ]; then
424458 # Binary hash matches target release - upgrade succeeded despite version string
@@ -435,6 +469,7 @@ process_tool() {
435469 fi
436470 else
437471 # Upgrade succeeded - remove any existing pin to avoid stale pins
472+ SUMMARY_UPDATED=$(( SUMMARY_UPDATED + 1 ))
438473 local existing_pin=" $( pins_get " $tool " ) "
439474 if [ -n " $existing_pin " ] && [ " $existing_pin " != " never" ]; then
440475 " $ROOT " /scripts/unpin_version.sh " $tool " || true
@@ -478,18 +513,23 @@ process_tool() {
478513 if [ " $upgrade_success_a " = " 0" ]; then
479514 printf " \n ⚠️ Upgrade failed (install script error)\n"
480515 printf " Auto-update is still enabled - will try again next time.\n"
516+ SUMMARY_FAILED=$(( SUMMARY_FAILED + 1 ))
481517 elif [ -n " $binary_already_current_a " ]; then
482518 printf " ✓ Auto-update enabled. Binary already matches target release.\n"
519+ SUMMARY_UPDATED=$(( SUMMARY_UPDATED + 1 ))
483520 elif [ " $new_installed_a " = " $installed " ] && [ " $new_installed_a " != " $latest " ]; then
484521 # Version didn't change - but check for prefix match (e.g., 3.13 vs 3.13.11)
485522 if [[ " $latest " == " $new_installed_a " * ]] || [[ " $new_installed_a " == " $latest " * ]]; then
486523 printf " ✓ Auto-update enabled. This tool will update automatically in future.\n"
524+ SUMMARY_UPDATED=$(( SUMMARY_UPDATED + 1 ))
487525 else
488526 printf " \n ⚠️ Upgrade did not succeed (version unchanged)\n"
489527 printf " Auto-update is still enabled - will try again next time.\n"
528+ SUMMARY_FAILED=$(( SUMMARY_FAILED + 1 ))
490529 fi
491530 else
492531 printf " ✓ Auto-update enabled. This tool will update automatically in future.\n"
532+ SUMMARY_UPDATED=$(( SUMMARY_UPDATED + 1 ))
493533 # Remove any existing pin
494534 local existing_pin_a=" $( pins_get " $tool " ) "
495535 if [ -n " $existing_pin_a " ]; then
@@ -501,6 +541,7 @@ process_tool() {
501541 # Skip this specific patch version only
502542 printf " Skipping only %s (will prompt again when newer patch available)\n" " $latest "
503543 " $ROOT " /scripts/pin_version.sh " $tool " " $latest " || true
544+ SUMMARY_SKIPPED=$(( SUMMARY_SKIPPED + 1 ))
504545 ;;
505546 [p])
506547 if [ -n " $installed " ]; then
@@ -550,6 +591,7 @@ process_tool() {
550591 local still_installed=" $( json_field " $tool " installed) "
551592 if [ -z " $still_installed " ]; then
552593 printf " ✓ %s has been removed\n" " $tool "
594+ SUMMARY_REMOVED=$(( SUMMARY_REMOVED + 1 ))
553595 else
554596 printf " ⚠️ %s may not have been fully removed (still detected: %s)\n" " $tool " " $still_installed "
555597 fi
@@ -570,6 +612,7 @@ process_tool() {
570612 ;;
571613 * )
572614 # User declined (N or empty)
615+ SUMMARY_SKIPPED=$(( SUMMARY_SKIPPED + 1 ))
573616 ;;
574617 esac
575618}
@@ -863,7 +906,7 @@ for category in $(printf '%s\n' "${!CATEGORY_TOOLS[@]}" | while read c; do echo
863906 # Category-level prompt (skip if auto-yes mode)
864907 if [ " ${AUTO_YES_ALL:- } " != " 1" ]; then
865908 printf " Tools: %s\n" " $( echo $tools | tr ' ' ' , ' | sed ' s/^, //' ) "
866- printf " Process this category? [Y/n/a=all/s=skip-all] "
909+ printf " Process this category? [Y/n/a=all categories /s=skip-all] "
867910
868911 cat_ans=" "
869912 if [ -t 0 ]; then
@@ -935,5 +978,14 @@ if [ -n "$DEPRECATED_TOOLS" ]; then
935978 fi
936979fi
937980
981+ # Print final summary
982+ echo
983+ echo " ================================================================================"
984+ echo " Summary"
985+ echo " ================================================================================"
986+ printf " Updated: %d\n" " $SUMMARY_UPDATED "
987+ printf " Removed: %d\n" " $SUMMARY_REMOVED "
988+ printf " Skipped: %d\n" " $SUMMARY_SKIPPED "
989+ printf " Failed: %d\n" " $SUMMARY_FAILED "
938990echo
939- echo " All done. Re-run: make audit"
991+ echo " Re-run: make audit"
0 commit comments