Last active 1 month ago

pin-calf.sh Raw
1#!/usr/bin/env bash
2# pin-calf-0.90.8-4.sh
3# Downgrade calf to 0.90.8-4 and pin it. Use --unpin to remove the pin.
4
5set -euo pipefail
6
7PKG="calf"
8PKGVER="0.90.8-4"
9PKGFILE="${PKG}-${PKGVER}-x86_64.pkg.tar.zst"
10URL="https://archive.archlinux.org/packages/c/${PKG}/${PKGFILE}"
11PACCONF="/etc/pacman.conf"
12
13usage() {
14 cat <<EOF
15Usage:
16 $0 # downgrade to ${PKGVER} and pin
17 $0 --unpin # remove pin for ${PKG}
18EOF
19}
20
21ensure_root() {
22 if [[ $EUID -ne 0 ]]; then
23 echo "Re-running with sudo..."
24 exec sudo -E "$0" "$@"
25 fi
26}
27
28backup_conf() {
29 [[ -f "${PACCONF}.bak" ]] || cp -a "$PACCONF" "${PACCONF}.bak"
30}
31
32pin_pkg() {
33 backup_conf
34 # If IgnorePkg exists, ensure 'calf' is present. Otherwise add a line
35 # under [options]. This edit is idempotent.
36 awk -v pkg="$PKG" '
37 BEGIN { done=0 }
38 /^\[options\]/ {
39 print; inopt=1; next
40 }
41 inopt && /^IgnorePkg\s*=.*/ {
42 if ($0 ~ ("(^|\\s)" pkg "(\\s|$)")) { print; done=1 }
43 else { print $0 " " pkg; done=1 }
44 inopt=0; next
45 }
46 { print }
47 END {
48 if (!done) {
49 if (inopt) {
50 print "IgnorePkg = " pkg
51 } else {
52 print ""; print "[options]"; print "IgnorePkg = " pkg
53 }
54 }
55 }
56 ' "$PACCONF" > "${PACCONF}.new"
57 mv "${PACCONF}.new" "$PACCONF"
58}
59
60unpin_pkg() {
61 backup_conf
62 awk -v pkg="$PKG" '
63 {
64 if ($0 ~ /^IgnorePkg\s*=/) {
65 # remove only exact word matches of pkg
66 gsub("(^|[ \t])" pkg "([ \t]|$)", " ")
67 # normalize spaces
68 sub(/^[ \t]+/, "")
69 sub(/[ \t]+$/, "")
70 sub(/[ \t]+/, " ")
71 # drop line if now just "IgnorePkg =" with nothing after
72 if ($0 ~ /^IgnorePkg\s*=\s*$/) next
73 }
74 print
75 }
76 ' "$PACCONF" > "${PACCONF}.new"
77 mv "${PACCONF}.new" "$PACCONF"
78}
79
80install_pkg() {
81 tmp="$(mktemp -d)"
82 trap 'rm -rf "$tmp"' EXIT
83 cd "$tmp"
84 echo "Downloading ${URL} ..."
85 curl -fL --retry 3 -O "$URL"
86 echo "Installing ${PKGFILE} ..."
87 pacman -U --noconfirm "./${PKGFILE}"
88 echo "Installed:"
89 pacman -Qi "$PKG" | sed -n '1,12p'
90}
91
92main() {
93 if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
94 usage; exit 0
95 fi
96
97 if [[ "${1:-}" == "--unpin" ]]; then
98 ensure_root "$@"
99 unpin_pkg
100 echo "Unpinned ${PKG}. You may now upgrade normally."
101 exit 0
102 fi
103
104 ensure_root "$@"
105 install_pkg
106 pin_pkg
107 echo
108 echo "Pinned ${PKG} at ${PKGVER} via IgnorePkg in ${PACCONF}."
109 echo "To undo: sudo $0 --unpin"
110}
111
112main "$@"
113