From c12431446666cd09ceceb0d9fa9f1c73113b4d9c Mon Sep 17 00:00:00 2001 From: Kévin Le Gouguec Date: Sat, 23 Aug 2025 23:11:36 +0200 Subject: Change Emacs ELPA update script Be cautiously optimistic: hope that the update process will work; stop "generate dummy config & install everything from scratch" shenanigans. (Do create a backup folder tho, just in case) Also, compute patches for perusal. --- .local/bin/emacs-update-packages | 104 +++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 32 deletions(-) diff --git a/.local/bin/emacs-update-packages b/.local/bin/emacs-update-packages index 28d231d..2f162a5 100755 --- a/.local/bin/emacs-update-packages +++ b/.local/bin/emacs-update-packages @@ -1,47 +1,87 @@ #!/bin/bash +# Backup package-user-dir, update packages, compute diffs. +# +# Might be worth re-implementing as advice for package.el commands: +# would avoid the "sacrificial" Emacs sessions… + set -euo pipefail -set -x +test "${DEBUG:-}" && set -x + +BKPDIR=.elpa.$(date +%F-%T) -backup-elpa () +read-packages () { - ( - cd ~/.emacs.d - - # Make a timestamped snapshot for archival. - tar czf elpa.$(date +%F).tgz elpa - - # Move directory out of Emacs's sight. We could remove it - # altogether since we have the archived snapshot; keep it - # around for the very minor convenience gain. - rm -rf elpa.bkp - mv -T elpa elpa.bkp - ) + local -n pkgarray=$1 + + local pkgel name version + for pkgel in elpa/*/*-pkg.el + do + # Extract NAME & VERSION out of elpa/NAME-VERSION/NAME-pkg.el. + pkgel=${pkgel#elpa/} + + name=${pkgel} + name=${name##*/} + name=${name%-pkg.el} + + version=${pkgel} + version=${version%/${name}-pkg.el} + version=${version#${name}-} + + pkgarray[${name}]=${version} + done } -gen-dotemacs () +enum-packages () { - # --batch will not read my configuration. Fall back to print-like - # functions, redirecting to 'external-debugging-output, - # redirecting stderr to stdout, and kill-emacs. - emacs 2>&1 \ - --eval '(pp `(use-package package - :custom - (package-archives '\''(,@package-archives)) - (package-selected-packages '\''(,@package-selected-packages))) - '\''external-debugging-output)' \ - --funcall kill-emacs + IFS=$'\n' eval ' + echo "${!OLDPACKAGES[*]}" + echo "${!NEWPACKAGES[*]}" + ' | sort -u } +compare-packages () +{ + local pkg oldv newv -cd ~ + while read pkg + do + oldv=${OLDPACKAGES[${pkg}]:-} + newv=${NEWPACKAGES[${pkg}]:-} + + test "${oldv}" = "${newv}" && + # No changes, skip. + continue + + test "${oldv}" -a "${newv}" && + # Make a patch for later review. + ( + set +e + diff > ${BKPDIR}/update-${pkg}.patch \ + -ru ${BKPDIR}/${pkg}-${oldv} elpa/${pkg}-${newv} + + + diffstatus=$? + case ${diffstatus} + in + 0|1) exit 0 ;; + *) exit ${diffstatus} ;; + esac + ) + + echo -e "${pkg}\t${oldv:-[NEW]}\t${newv:-[REMOVED]}" + done +} -gen-dotemacs > .emacs.upgrade +( + cd ~/.config/emacs + cp -a elpa ${BKPDIR} -backup-elpa -mv .emacs .emacs.bkp + declare -A OLDPACKAGES NEWPACKAGES -cp .emacs.upgrade .emacs -emacs --funcall package-install-selected-packages + read-packages OLDPACKAGES + emacs -f package-upgrade-all -f package-autoremove + read-packages NEWPACKAGES -mv .emacs.bkp .emacs + enum-packages | compare-packages | column -ts$'\t' +) -- cgit v1.2.3