diff --git a/scripts/setup/machine-setup/lib/packages.sh b/scripts/setup/machine-setup/lib/packages.sh index 52acdcd4..4828a6f3 100644 --- a/scripts/setup/machine-setup/lib/packages.sh +++ b/scripts/setup/machine-setup/lib/packages.sh @@ -121,6 +121,25 @@ pkg_refresh() { esac } +# What an upgrade would actually move, one package name per line. +# +# Asked before the upgrade runs so the section can name what it is about to +# change rather than asking to be trusted. Needs a refreshed index to be +# accurate, which is why pkg_refresh runs first. +# +# `apt-get upgrade -s` simulates and prints an "Inst …" line per package, +# which is the same calculation the real run does — as opposed to +# `apt list --upgradable`, which also lists packages that are held back and +# would not actually move. +pkg_upgradable() { + case "$PM" in + apt) apt-get upgrade -s 2>/dev/null | awk '/^Inst /{print $2}' ;; + pacman) pacman -Qu 2>/dev/null | awk '{print $1}' ;; + dnf) dnf -q check-update 2>/dev/null | awk 'NF >= 3 && $1 !~ /^(Last|Obsoleting)/ {print $1}' ;; + brew) brew outdated --quiet 2>/dev/null ;; + esac +} + # Upgrade everything already installed. Separate from pkg_install on purpose: # this one DOES move versions, so it is a deliberate step rather than something # that happens as a side effect of installing a tool. diff --git a/scripts/setup/machine-setup/machine-setup.sh b/scripts/setup/machine-setup/machine-setup.sh index 165cc7bd..bccba62c 100755 --- a/scripts/setup/machine-setup/machine-setup.sh +++ b/scripts/setup/machine-setup/machine-setup.sh @@ -87,17 +87,29 @@ if ! skip; then info "Refreshing the package index..." pkg_refresh >/dev/null - echo "" - info "System update — upgrades packages already installed to their latest versions" - echo " this is the only step that changes software already on this machine" + mapfile -t UPGRADABLE < <(pkg_upgradable) - if confirm "Proceed?"; then - pkg_upgrade_all - ok "System upgraded" - SUMMARY+=("System packages upgraded") + echo "" + info "System update — the only step that changes software already on this machine" + + if ((${#UPGRADABLE[@]} == 0)); then + echo " to upgrade: nothing, everything is current" + SUMMARY+=("System update: already up to date") else - warn "skipped by request" - SUMMARY+=("System update: SKIPPED by request") + echo " to upgrade: ${#UPGRADABLE[@]} package(s)" + # Capped, because a box that has not been touched in months lists hundreds + # and a wall of names is no more informative than a count. + printf ' %s\n' "${UPGRADABLE[@]:0:25}" + ((${#UPGRADABLE[@]} > 25)) && echo " … and $((${#UPGRADABLE[@]} - 25)) more" + + if confirm "Proceed?"; then + pkg_upgrade_all + ok "System upgraded" + SUMMARY+=("System upgraded: ${#UPGRADABLE[@]} package(s)") + else + warn "skipped by request" + SUMMARY+=("System update: SKIPPED by request — ${#UPGRADABLE[@]} package(s) left as they are") + fi fi step_ok fi