194 lines
4.5 KiB
Bash
Executable file
194 lines
4.5 KiB
Bash
Executable file
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
AUR_DIR="${AUR_DIR:-$HOME/Aur}"
|
|
END_UPDATE="Mis à jour avec succès ;p."
|
|
SYSTEM_NAME="$(cat /etc/hostname 2>/dev/null || echo "unknown")"
|
|
|
|
RESET='\033[0m'
|
|
BOLD='\033[1m'
|
|
RED='\033[1;31m'
|
|
GREEN='\033[1;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[1;34m'
|
|
CYAN='\033[1;36m'
|
|
|
|
info() { printf "${BLUE}==>${RESET} %s\n" "$1"; }
|
|
ok() { printf "${GREEN}==>${RESET} %s\n" "$1"; }
|
|
warn() { printf "${YELLOW}==>${RESET} %s\n" "$1"; }
|
|
error() { printf "${RED}==>${RESET} %s\n" "$1"; }
|
|
section() { printf "\n${CYAN}${BOLD}>>> %s${RESET}\n" "$1"; }
|
|
|
|
[[ -d "$AUR_DIR" ]] || {
|
|
error "Répertoire AUR introuvable : $AUR_DIR"
|
|
exit 1
|
|
}
|
|
|
|
sudo -v || exit 1
|
|
while true; do
|
|
sudo -n true || exit
|
|
sleep 30
|
|
done 2>/dev/null &
|
|
SUDO_LOOP_PID=$!
|
|
trap 'kill "$SUDO_LOOP_PID" 2>/dev/null' EXIT INT TERM
|
|
|
|
cd "$AUR_DIR" || exit 1
|
|
|
|
shopt -s nullglob
|
|
repos=(*/)
|
|
shopt -u nullglob
|
|
|
|
if [[ ${#repos[@]} -eq 0 ]]; then
|
|
warn "Aucun dépôt AUR dans $AUR_DIR"
|
|
exit 0
|
|
fi
|
|
|
|
declare -a outdated_repos=()
|
|
|
|
audit_repo() {
|
|
local repo="$1"
|
|
local branch upstream local_rev remote_rev base_rev
|
|
|
|
cd "$AUR_DIR/$repo" || return 1
|
|
|
|
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
error "$repo n'est pas un dépôt git valide"
|
|
return 1
|
|
fi
|
|
|
|
branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null || true)
|
|
[[ -n "$branch" ]] || {
|
|
warn "$repo : HEAD détachée, ignoré"
|
|
return 1
|
|
}
|
|
|
|
if ! git remote update --prune >/dev/null 2>&1; then
|
|
error "Impossible de contacter le remote pour $repo"
|
|
return 1
|
|
fi
|
|
|
|
upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || true)
|
|
[[ -n "$upstream" ]] || upstream="origin/$branch"
|
|
|
|
local_rev=$(git rev-parse HEAD 2>/dev/null || true)
|
|
remote_rev=$(git rev-parse "$upstream" 2>/dev/null || true)
|
|
base_rev=$(git merge-base HEAD "$upstream" 2>/dev/null || true)
|
|
|
|
if [[ -z "$remote_rev" || -z "$local_rev" || -z "$base_rev" ]]; then
|
|
error "Impossible de comparer $repo avec $upstream"
|
|
return 1
|
|
fi
|
|
|
|
if [[ "$local_rev" == "$remote_rev" ]]; then
|
|
return 1
|
|
fi
|
|
|
|
if [[ "$local_rev" != "$base_rev" ]]; then
|
|
warn "$repo a des commits locaux non poussés, ignoré"
|
|
return 1
|
|
fi
|
|
|
|
outdated_repos+=("$repo")
|
|
return 0
|
|
}
|
|
|
|
ask_update() {
|
|
local repo="$1"
|
|
while true; do
|
|
printf "${YELLOW}Mettre à jour %s ? [y/N/q] ${RESET}" "$repo"
|
|
read -r ans
|
|
case "$ans" in
|
|
y|Y) return 0 ;;
|
|
n|N|"") return 1 ;;
|
|
q|Q) return 2 ;;
|
|
*) warn "Réponse invalide, utilise y, n ou q" ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
info "Scan des dépôts AUR..."
|
|
for d in "${repos[@]}"; do
|
|
repo="${d%/}"
|
|
audit_repo "$repo" || true
|
|
done
|
|
|
|
if [[ ${#outdated_repos[@]} -eq 0 ]]; then
|
|
ok "Aucune mise à jour AUR détectée"
|
|
exit 0
|
|
fi
|
|
|
|
section "Mises à jour détectées"
|
|
for repo in "${outdated_repos[@]}"; do
|
|
cd "$AUR_DIR/$repo" || continue
|
|
upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || echo "origin/HEAD")
|
|
printf "${YELLOW}- %s${RESET}\n" "$repo"
|
|
git --no-pager log --oneline --decorate HEAD.."$upstream" | sed 's/^/ /'
|
|
done
|
|
|
|
declare -a selected_repos=()
|
|
|
|
section "Sélection"
|
|
for repo in "${outdated_repos[@]}"; do
|
|
if ask_update "$repo"; then
|
|
selected_repos+=("$repo")
|
|
else
|
|
rc=$?
|
|
if [[ $rc -eq 2 ]]; then
|
|
warn "Sélection interrompue"
|
|
break
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [[ ${#selected_repos[@]} -eq 0 ]]; then
|
|
warn "Aucun paquet sélectionné"
|
|
exit 0
|
|
fi
|
|
|
|
section "Paquets sélectionnés"
|
|
for repo in "${selected_repos[@]}"; do
|
|
printf "${GREEN}- %s${RESET}\n" "$repo"
|
|
done
|
|
|
|
for repo in "${selected_repos[@]}"; do
|
|
cd "$AUR_DIR/$repo" || continue
|
|
section "$repo"
|
|
|
|
info "Récupération des changements"
|
|
if ! git pull --ff-only; then
|
|
error "git pull failed for $repo"
|
|
continue
|
|
fi
|
|
|
|
info "Vérifie au minimum PKGBUILD, sources, checksums et fonctions de build"
|
|
rm -f ./*.pkg.tar.*
|
|
|
|
if ! makepkg -sf; then
|
|
error "Build failed for $repo"
|
|
continue
|
|
fi
|
|
|
|
pkgfile=$(find . -maxdepth 1 -type f -name '*.pkg.tar.*' ! -name '*.sig' | head -n1 || true)
|
|
if [[ -z "$pkgfile" ]]; then
|
|
error "Aucun paquet trouvé pour $repo"
|
|
continue
|
|
fi
|
|
|
|
info "Installation de $pkgfile"
|
|
if ! sudo pacman -U --noconfirm "$pkgfile"; then
|
|
error "Install failed for $repo"
|
|
continue
|
|
fi
|
|
|
|
ok "$repo installé avec succès"
|
|
done
|
|
|
|
printf "\n"
|
|
if command -v figlet >/dev/null 2>&1; then
|
|
figlet -f slant "$SYSTEM_NAME" | while IFS= read -r line; do
|
|
printf "${GREEN}%s${RESET}\n" "$line"
|
|
done
|
|
printf "${GREEN}%s${RESET}\n" "$END_UPDATE"
|
|
else
|
|
printf "${GREEN}%s : %s${RESET}\n" "$SYSTEM_NAME" "$END_UPDATE"
|
|
fi
|