Last active
February 6, 2020 19:57
-
-
Save rpigott/36e3e21654542f0fbd5da07f58109713 to your computer and use it in GitHub Desktop.
pacrevert
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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