dotfiles

๐ŸŽœ Clone'em, tweak'em, stick'em in your $HOME ๐ŸŽ
git clone https://git.kevinlegouguec.net/dotfiles
Log | Files | Refs | README

emacs-update-packages (2047B)


      1 #!/bin/bash
      2 
      3 # Backup package-user-dir, update packages, compute diffs.
      4 #
      5 # Might be worth re-implementing as advice for package.el commands:
      6 # would avoid the "sacrificial" Emacs sessionsโ€ฆ
      7 
      8 set -euo pipefail
      9 test "${DEBUG:-}" && set -x
     10 
     11 cd ~/.config/emacs
     12 
     13 test -L elpa || {
     14     echo >&2 "'elpa' directory must be a symlink."
     15     exit 1
     16 }
     17 
     18 OLDELPADIR=$(readlink elpa)
     19 NEWELPADIR=.elpa.$(date +%F-%T)
     20 
     21 read-packages ()
     22 {
     23     local -n pkgarray=$1
     24 
     25     local pkgel name version
     26     for pkgel in elpa/*/*-pkg.el
     27     do
     28         # Extract NAME & VERSION out of elpa/NAME-VERSION/NAME-pkg.el.
     29         pkgel=${pkgel#elpa/}
     30 
     31         name=${pkgel}
     32         name=${name##*/}
     33         name=${name%-pkg.el}
     34 
     35         version=${pkgel}
     36         version=${version%/${name}-pkg.el}
     37         version=${version#${name}-}
     38 
     39         pkgarray[${name}]=${version}
     40     done
     41 }
     42 
     43 enum-packages ()
     44 {
     45     IFS=$'\n' eval '
     46         echo "${!OLDPACKAGES[*]}"
     47         echo "${!NEWPACKAGES[*]}"
     48     ' | sort -u
     49 }
     50 
     51 compare-packages ()
     52 {
     53     local pkg oldv newv
     54 
     55     while read pkg
     56     do
     57         oldv=${OLDPACKAGES[${pkg}]:-}
     58         newv=${NEWPACKAGES[${pkg}]:-}
     59 
     60         test "${oldv}" = "${newv}" &&
     61             # No changes, skip.
     62             continue
     63 
     64         test "${oldv}" -a "${newv}" &&
     65             # Make a patch for later review.
     66             (
     67                 set +e
     68                 diff > ${NEWELPADIR}/update-${pkg}.patch \
     69                     -ru ${OLDELPADIR}/${pkg}-${oldv} ${NEWELPADIR}/${pkg}-${newv}
     70 
     71 
     72                 diffstatus=$?
     73                 case ${diffstatus}
     74                 in
     75                     0|1) exit 0 ;;
     76                     *)   exit ${diffstatus} ;;
     77                 esac
     78             )
     79 
     80         echo -e "${pkg}\t${oldv:-[NEW]}\t${newv:-[REMOVED]}"
     81     done
     82 }
     83 
     84 cp -a ${OLDELPADIR} ${NEWELPADIR}
     85 
     86 declare -A OLDPACKAGES NEWPACKAGES
     87 
     88 read-packages OLDPACKAGES
     89 ln -fsT ${NEWELPADIR} elpa
     90 
     91 emacs -f package-upgrade-all -f package-autoremove
     92 read-packages NEWPACKAGES
     93 
     94 enum-packages | compare-packages | column -ts$'\t' |
     95     tee ${NEWELPADIR}/update.sum