list what the system update would actually upgrade

The section asked "Proceed?" without saying what it was proposing to change —
the one question in the script where the answer matters most, since it is the
only step that moves versions of software already on the machine.

pkg_upgradable now names them, from `apt-get upgrade -s`: the same calculation
the real run does, as opposed to `apt list --upgradable`, which also lists
packages held back that would not actually move.

Nothing to upgrade means no prompt at all, and the summary says so rather than
claiming an upgrade happened. The list is capped at 25 with a count of the rest,
because a box untouched for months lists hundreds and a wall of names is no more
informative than the number.

Verified against this host (0 upgradable, so it reports current and does not
ask) and with a stubbed 40-package list for the cap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 17:39:00 +00:00
co-authored by Claude Opus 5
parent f896d4882f
commit 454faf5406
2 changed files with 40 additions and 9 deletions
@@ -121,6 +121,25 @@ pkg_refresh() {
esac 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 <name> …" 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: # Upgrade everything already installed. Separate from pkg_install on purpose:
# this one DOES move versions, so it is a deliberate step rather than something # this one DOES move versions, so it is a deliberate step rather than something
# that happens as a side effect of installing a tool. # that happens as a side effect of installing a tool.
+16 -4
View File
@@ -87,17 +87,29 @@ if ! skip; then
info "Refreshing the package index..." info "Refreshing the package index..."
pkg_refresh >/dev/null pkg_refresh >/dev/null
mapfile -t UPGRADABLE < <(pkg_upgradable)
echo "" echo ""
info "System update — upgrades packages already installed to their latest versions" info "System update — the only step that changes software already on this machine"
echo " this is 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
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 if confirm "Proceed?"; then
pkg_upgrade_all pkg_upgrade_all
ok "System upgraded" ok "System upgraded"
SUMMARY+=("System packages upgraded") SUMMARY+=("System upgraded: ${#UPGRADABLE[@]} package(s)")
else else
warn "skipped by request" warn "skipped by request"
SUMMARY+=("System update: SKIPPED by request") SUMMARY+=("System update: SKIPPED by request${#UPGRADABLE[@]} package(s) left as they are")
fi
fi fi
step_ok step_ok
fi fi