Skip to content

Instantly share code, notes, and snippets.

@rpigott
Last active February 6, 2020 19:57
Show Gist options
  • Save rpigott/36e3e21654542f0fbd5da07f58109713 to your computer and use it in GitHub Desktop.
Save rpigott/36e3e21654542f0fbd5da07f58109713 to your computer and use it in GitHub Desktop.
pacrevert
#!/bin/bash
read -d $'\0' HELP <<-EOF
Usage: ${0##*/} [-h|--help]
${0##*/} [-l|--logfile <logfile>] { PACKAGE | - }
Revert package upgrades from the most recent transaction.
Specify which packages on the command line to limit which
are downgraded, or use '-' to read package list from stdin.
Options:
--logfile Use an alternate logfile.
EOF
# Args
TEMP=$(getopt -o 'hl:' --longoptions 'help,logfile' -n "${0##*/}" -- "$@")
if [[ $? -ne 0 ]]; then
echo "$HELP"
exit 1
fi
eval set -- "$TEMP"
unset TEMP
while true; do
case "$1" in
--logfile)
LOGFILE="$2"
shift 2
;;
--help)
echo "$HELP"
exit
;;
--)
shift
break
;;
esac
done
LOGFILE="${LOGFILE:-$(pacconf logfile)}"
declare -a PACKAGES
while true; do
case "$1" in
"")
break
;;
-)
[[ -n "$EXTRA" ]] && break
while read -r -a EXTRA; do
PACKAGES+=("${EXTRA[@]}")
done
shift
;;
*)
PACKAGES+=("$1")
shift
;;
esac
done
# Patterns
PKGEXT="pkg.tar.*"
PTN='([[:alnum:]:.-]+)'
UPGRADE_PTN="s/$PTN \($PTN -> $PTN\)/\1 \2 \3/"
REMOVED_PTN="s/$PTN \($PTN\)/\1 \2/"
# Get the most recent transaction
paclast() {
sed -n 'H;/transaction started$/h;${x;p}' "$LOGFILE"
}
# Find package w/ version in cache
pacfind() {
PKG="$1" VER="$2"
NAME="$PKG-$VER-*.$PKGEXT"
find $(pacconf cachedir) -name "$NAME" | head -n1 |
grep $ || echo "WARNING: '$PKG-$VER' not in cache" 1>&2
}
pacrevert() {
local PKG OLDVER NEWVER
paclast |
while read TIME CALLER TYPE INFO; do
if [[ "$INFO" == "completed" ]]; then
break
fi
if [[ "$CALLER" == "[ALPM]" ]]; then
case "$TYPE" in
upgraded)
sed -E "$UPGRADE_PTN" <<< "$INFO"
;;
downgraded)
sed -E "$UPGRADE_PTN" <<< "$INFO"
;;
removed)
sed -E "$REMOVED_PTN" <<< "$INFO"
;;
*)
continue
esac
fi
done |
while read PKG OLDVER NEWVER; do
if [[ ${#PACKAGES[@]} -gt 0 ]]; then
printf "%s\n" "${PACKAGES[@]}" |
grep -Fqx "$PKG" || {
echo "WARNING: skipping package '$PKG'" 1>&2
continue
}
fi
pacfind "$PKG" "$OLDVER"
done
}
paclast | paclog --caller=ALPM --logfile=-
pacrevert "$@" | pacman -U -
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment