113 lines
2.9 KiB
Bash
113 lines
2.9 KiB
Bash
#!/usr/bin/bash
|
|
|
|
set -o pipefail
|
|
|
|
ALHP_STATS_URL='https://api.alhp.dev/stats'
|
|
ALHP_BQ_URL='https://api.alhp.dev/packages?limit=0&offset=0&status=queued&status=building'
|
|
|
|
mirrorlistsOutOfDate(){
|
|
local max_mirrors="${1:-1}"
|
|
local mirrorlists mirrorlist mirror_urls mirror_url all_mirrors=() alhp_timestamp
|
|
local -A mirror_timestamps=()
|
|
|
|
readarray -t mirrorlists < <(awk '
|
|
/^\s*\[.*x86-64-v[2-4].*\]/ { in_repo = 1; next }
|
|
in_repo && /^\s*Include\s*=\s*/ {
|
|
match($0, /Include\s*=\s*(.*)/, arr)
|
|
print arr[1]
|
|
in_repo = 0
|
|
}
|
|
' /etc/pacman.conf | sort -u
|
|
)
|
|
|
|
for mirrorlist in ${mirrorlists[@]}; do
|
|
readarray -t mirror_urls < <(
|
|
grep '^Server =' "$mirrorlist" | \
|
|
sed -E 's/^Server = (https?:\/\/[^$]+).*/\1\/lastupdate/'
|
|
)
|
|
all_mirrors+=(${mirror_urls[@]})
|
|
done
|
|
|
|
mapfile -t all_mirrors < <(printf '%s\n' ${all_mirrors[@]} | sort -u | head -n $max_mirrors)
|
|
#TODO: fork curls for better performance
|
|
for mirror_url in "${all_mirrors[@]}"; do
|
|
# curl quietly, fail silently, timeout 5s
|
|
timestamp=$(curl -fs --max-time 5 "$mirror_url" || echo "error")
|
|
mirror_timestamps["$mirror_url"]=$timestamp
|
|
done
|
|
alhp_timestamp=$(curl -fs --max-time 5 $ALHP_STATS_URL | jq .last_mirror_timestamp || echo "error")
|
|
|
|
for url in "${!mirror_timestamps[@]}"; do
|
|
if [[ ${mirror_timestamps[$url]} -lt $alhp_timestamp ]]; then
|
|
echo "Mirror: $url outdated."
|
|
fi
|
|
done
|
|
}
|
|
|
|
updatesAvailable() {
|
|
readarray -t repos < <(grep '^\[' /etc/pacman.conf | sed -e 's/[][]//g' | grep -E 'x86-64-v[2-4]')
|
|
|
|
output_json=false
|
|
check_pkg=""
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
-j|--json) output_json=true; shift ;;
|
|
--check-pkg)
|
|
check_pkg=$2
|
|
shift 2
|
|
;;
|
|
*)
|
|
echo "Unknown argument: $1"
|
|
return 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
declare -A pkgs
|
|
|
|
while read -r _ name version status; do
|
|
if [[ $status == *installed* ]]; then
|
|
pkgs[$name]=1
|
|
fi
|
|
done < <(pacman -Sl ${repos[@]})
|
|
|
|
repo_query=$(printf '&repo=%s' "${repos[@]}")
|
|
api_url="$ALHP_BQ_URL${repo_query}"
|
|
|
|
if [[ -n $check_pkg ]]; then
|
|
building_pkgs=$(curl -s $api_url \
|
|
| jq -r --arg pkg $check_pkg '.packages[] | select(.split_packages[] == $pkg) | .split_packages[]')
|
|
|
|
matches=()
|
|
for bpkg in $building_pkgs; do
|
|
if [[ -n "${pkgs[$bpkg]}" ]]; then
|
|
matches+=("$bpkg")
|
|
fi
|
|
done
|
|
|
|
if $output_json; then
|
|
printf '%s\n' "${matches[@]}" | jq -Rn '[inputs]'
|
|
else
|
|
printf '%s\n' "${matches[@]}"
|
|
fi
|
|
else
|
|
matches=()
|
|
while read -r pkgname; do
|
|
if [[ -n ${pkgs[$pkgname]} ]]; then
|
|
matches+=($pkgname)
|
|
fi
|
|
done < <(curl -s $api_url | jq -r '.packages[] | .split_packages[]')
|
|
|
|
if $output_json; then
|
|
printf '%s\n' ${matches[@]} | jq -Rn '[inputs]'
|
|
else
|
|
printf '%s\n' ${matches[@]}
|
|
fi
|
|
fi
|
|
}
|
|
|
|
|
|
mirrorlistsOutOfDate
|
|
updatesAvailable $@
|