Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env bash
- STATE_FILE="$HOME/.config/aur-maintainers.json"
- # Ensure jq is installed
- if ! command -v jq >/dev/null 2>&1; then
- echo "ERROR: 'jq' is required for maintainer tracking." >&2
- exit 1
- fi
- # Fetch installed foreign/AUR packages
- mapfile -t foreign_pkgs < <(pacman -Qmq)
- if [ "${#foreign_pkgs[@]}" -eq 0 ]; then
- exit 0
- fi
- # Initialize state file if it doesn't exist
- if [ ! -f "$STATE_FILE" ]; then
- echo "{}" > "$STATE_FILE"
- fi
- # Query AUR RPC v5
- curl_args=(-sL -G "https://aur.archlinux.org/rpc/v5/info")
- for pkg in "${foreign_pkgs[@]}"; do
- curl_args+=(--data-urlencode "arg[]=$pkg")
- done
- response=$(curl "${curl_args[@]}")
- if [ -z "$response" ]; then
- echo "⚠️ WARNING: Unable to reach AUR RPC. Proceed with caution." >&2
- read -p "Continue update anyway? [y/N]: " -n 1 -r
- echo ""
- [[ $REPLY =~ ^[Yy]$ ]] && exit 0 || exit 1
- fi
- # Build current remote state as JSON: {"pkgname": "MaintainerOrNull"}
- remote_json=$(echo "$response" | jq -c '
- [.results[] | {key: .Name, value: (.Maintainer // "ORPHANED")}] | from_entries
- ')
- # Detect maintainer changes and classify risk
- changes=$(jq -n \
- --argjson old "$(cat "$STATE_FILE")" \
- --argjson new "$remote_json" '
- $new | to_entries[] | .key as $pkg | .value as $new_m |
- ($old[$pkg]) as $old_m |
- if $old_m != null and $old_m != $new_m then
- {
- package: $pkg,
- old: $old_m,
- new: $new_m,
- is_high_risk: ($new_m == "ORPHANED" or $old_m == "ORPHANED")
- }
- else
- empty
- end
- ')
- # Check for packages completely removed from AUR
- found_pkgs=$(echo "$response" | jq -r '.results[].Name')
- declare -A found_map
- for pkg in $found_pkgs; do
- found_map["$pkg"]=1
- done
- dropped_pkgs=()
- for pkg in "${foreign_pkgs[@]}"; do
- if [[ -z "${found_map[$pkg]}" ]]; then
- dropped_pkgs+=("$pkg")
- fi
- done
- # Collect all flagged package names for removal option
- flagged_pkgs=()
- if [ -n "$changes" ]; then
- mapfile -t changed_names < <(echo "$changes" | jq -r '.package')
- flagged_pkgs+=("${changed_names[@]}")
- fi
- if [ "${#dropped_pkgs[@]}" -gt 0 ]; then
- flagged_pkgs+=("${dropped_pkgs[@]}")
- fi
- # If changes or dropped packages are found, issue interactive prompt
- if [ "${#flagged_pkgs[@]}" -gt 0 ]; then
- echo -e "\n\033[1;31m========================================================\033[0m"
- echo -e "\033[1;31m⚠️ AUR SECURITY ALERT: HIGH RISK CHANGES DETECTED! ⚠️\033[0m"
- echo -e "\033[1;31m========================================================\033[0m\n"
- high_risk_changes=$(echo "$changes" | jq -c 'select(.is_high_risk == true)')
- std_changes=$(echo "$changes" | jq -c 'select(.is_high_risk == false)')
- if [ -n "$high_risk_changes" ]; then
- echo -e "\033[1;31m🚨 HIGH RISK: Package Orphaned or Adopted:\033[0m"
- echo "$high_risk_changes" | jq -r '" • \(.package): \(.old) ➔ \(.new)"'
- echo ""
- fi
- if [ -n "$std_changes" ]; then
- echo -e "\033[1;33m⚠️ MAINTAINER HANDOFF: Ownership transferred:\033[0m"
- echo "$std_changes" | jq -r '" • \(.package): \(.old) ➔ \(.new)"'
- echo ""
- fi
- if [ "${#dropped_pkgs[@]}" -gt 0 ]; then
- echo -e "\033[1;31m🚨 HIGH RISK: Completely REMOVED from AUR:\033[0m"
- for pkg in "${dropped_pkgs[@]}"; do
- echo " • $pkg"
- done
- echo ""
- fi
- echo "Inspect the PKGBUILD on aur.archlinux.org before approving."
- echo ""
- read -p "Options: [y]es accept all | [r]emove flagged packages | [N]o abort update: " -n 1 -r
- echo ""
- case "$REPLY" in
- [Yy])
- # Save current state to JSON on approval
- echo "$remote_json" > "$STATE_FILE"
- echo ":: AUR maintainer state updated."
- exit 0
- ;;
- [Rr])
- echo -e "\n\033[1;33mSelect packages to remove (space-separated names), or press Enter to remove ALL flagged:\033[0m"
- echo "Flagged packages: ${flagged_pkgs[*]}"
- read -p "Packages to remove [default: all]: " -r pkgs_to_remove
- if [ -z "$pkgs_to_remove" ]; then
- pkgs_to_remove="${flagged_pkgs[*]}"
- fi
- echo -e "\n:: Running: sudo pacman -Rns $pkgs_to_remove"
- if sudo pacman -Rns $pkgs_to_remove; then
- # Re-query remaining foreign packages to update state JSON accurately
- mapfile -t remaining_foreign < <(pacman -Qmq)
- if [ "${#remaining_foreign[@]}" -gt 0 ]; then
- updated_json=$(echo "$response" | jq -c --argjson remaining "$(printf '%s\n' "${remaining_foreign[@]}" | jq -R . | jq -s .)" '
- [.results[] | select(.Name as $name | $remaining | contains([$name])) | {key: .Name, value: (.Maintainer // "ORPHANED")}] | from_entries
- ')
- echo "$updated_json" > "$STATE_FILE"
- else
- echo "{}" > "$STATE_FILE"
- fi
- echo ":: Specified packages removed and state file updated."
- else
- echo -e "\033[1;31mFailed to remove packages via pacman.\033[0m"
- fi
- echo -e "\n\033[1;31mUpdate process paused. Re-run cachy-update to proceed with clean state.\033[0m"
- exit 1
- ;;
- *)
- echo -e "\n\033[1;31mUpdate aborted by user.\033[0m"
- exit 1
- ;;
- esac
- fi
- # Save current state to JSON on normal runs
- echo "$remote_json" > "$STATE_FILE"
- echo ":: AUR maintainer state verified."
- exit 0
Advertisement
Add Comment
Please, Sign In to add comment