diff --git a/updates.d/80-gnome-extensions.sh b/updates.d/80-gnome-extensions.sh index 0a72a89..efc6b99 100755 --- a/updates.d/80-gnome-extensions.sh +++ b/updates.d/80-gnome-extensions.sh @@ -22,4 +22,40 @@ run_update() { else echo "gext update failed; GNOME extensions were not updated." fi + + reinstall_incompatible_extensions +} + +# gext only updates when the store's version number is higher than the installed +# one, so a copy from elsewhere (e.g. a GitHub release with a different numbering) +# can be stuck on a build that doesn't support the current GNOME Shell. GNOME +# disables such extensions, so reinstall them fresh from extensions.gnome.org. +reinstall_incompatible_extensions() { + local shell_major ext_root enabled dir uuid backup + shell_major="$(gnome-shell --version | grep -oE '[0-9]+' | head -1)" + ext_root="$HOME/.local/share/gnome-shell/extensions" + enabled="$(gsettings get org.gnome.shell enabled-extensions)" + + for dir in "$ext_root"/*/; do + [ -f "$dir/metadata.json" ] || continue + uuid="$(basename "$dir")" + [[ "$enabled" == *"'$uuid'"* ]] || continue + + if python3 -c 'import json, sys; m = json.load(open(sys.argv[1])); sys.exit(0 if any(str(v).split(".")[0] == sys.argv[2] for v in m.get("shell-version", [])) else 1)' \ + "$dir/metadata.json" "$shell_major"; then + continue + fi + + echo "$uuid doesn't support GNOME Shell $shell_major, reinstalling from extensions.gnome.org..." + backup="$(mktemp -d)" + mv "$dir" "$backup/$uuid" + if ~/.local/bin/gext --filesystem install "$uuid" && [ -f "$ext_root/$uuid/metadata.json" ]; then + rm -rf "$backup" + else + echo "Reinstall of $uuid failed; restoring the previous version." + rm -rf "$ext_root/$uuid" + mv "$backup/$uuid" "$ext_root/$uuid" + rmdir "$backup" + fi + done }