diff --git a/setup-aur.sh b/setup-aur.sh index 6b98b6d..c9b49fb 100755 --- a/setup-aur.sh +++ b/setup-aur.sh @@ -200,92 +200,109 @@ fi chown -R "$BUILD_USER:$BUILD_USER" "$BUILD_DIR" # ============================================================ -step "3/4 — Build des paquets AUR : ${AUR_PACKAGES[*]}" +# Helpers — build INCRÉMENTAL (saute un paquet déjà présent dans local-repo +# à la même version pkgver-pkgrel). Gros gain quand on n'itère que sur 1 paquet. # ============================================================ -for pkg in "${AUR_PACKAGES[@]}"; do - info "Clonage $pkg…" - su - "$BUILD_USER" -c "git clone https://aur.archlinux.org/${pkg}.git $BUILD_DIR/$pkg" \ - || error "Clonage $pkg échoué" +mkdir -p "$LOCAL_REPO" - info "Build $pkg (peut prendre plusieurs minutes)…" - su - "$BUILD_USER" -c "cd $BUILD_DIR/$pkg && makepkg -s --noconfirm" \ - || error "Build $pkg échoué" - # Installe le paquet construit AVANT de passer au suivant : indispensable - # pour les chaînes AUR→AUR (libreport dépend de satyr + libxmlrpc) et pour - # que les PKGBUILD locaux (python-meh → libreport) trouvent leurs deps. - # makepkg -s ne résout que les dépôts officiels, jamais les paquets AUR. - pacman -U --noconfirm "$BUILD_DIR/$pkg/"*.pkg.tar.zst \ - || error "Install du paquet $pkg échouée" - success "$pkg build + install OK" +# Version « [epoch:]pkgver-pkgrel » lue dans un PKGBUILD (sourcing en sous-shell). +# Vide si illisible → on (re)construit par sécurité. Nos paquets n'ont pas de +# pkgver() VCS, donc le pkgver littéral est exact. +pkgbuild_fullver() { + ( cd "$1" 2>/dev/null && source ./PKGBUILD >/dev/null 2>&1 \ + && printf '%s%s-%s' "${epoch:+$epoch:}" "$pkgver" "$pkgrel" ) 2>/dev/null || true +} + +# Le paquet en version est-il déjà dans local-repo ? Le motif +# « -$ver- » borne la version (évite qu'« anaconda » matche « anaconda-widgets »). +repo_has() { + [ -n "$2" ] || return 1 + local f + for f in "$LOCAL_REPO/$1-$2-"*.pkg.tar.*; do [ -e "$f" ] && return 0; done + return 1 +} + +# Publie les .pkg d'un build vers local-repo en purgeant d'abord les anciennes +# versions de CE paquet (+ son sous-paquet -debug). Le « -[0-9] » empêche +# « anaconda » d'attraper « anaconda-widgets » / « anaconda-debug ». +publish_to_repo() { + local name="$1" d="$2" + rm -f "$LOCAL_REPO/$name"-[0-9]*.pkg.tar.* \ + "$LOCAL_REPO/$name"-debug-[0-9]*.pkg.tar.* 2>/dev/null || true + cp -f "$d"/*.pkg.tar.* "$LOCAL_REPO/" || error "Copie de $name vers local-repo échouée" +} + +# Construit OU saute (source déjà déposée dans $BUILD_DIR/). +# Installe TOUJOURS le résultat (depuis local-repo si sauté) pour que les +# paquets dépendants suivants résolvent leurs deps (chaînes AUR→AUR, anaconda…). +build_or_skip() { + local name="$1" d="$BUILD_DIR/$name" ver + [ -f "$d/PKGBUILD" ] || error "PKGBUILD introuvable pour $name ($d)" + ver="$(pkgbuild_fullver "$d")" + if repo_has "$name" "$ver"; then + success "$name $ver déjà construit → saut (install depuis local-repo)" + pacman -U --noconfirm --needed "$LOCAL_REPO/$name-$ver-"*.pkg.tar.* \ + || error "Install (repo) de $name échouée" + return 0 + fi + info "Build $name ${ver:+($ver) }(peut prendre plusieurs minutes)…" + chown -R "$BUILD_USER:$BUILD_USER" "$d" + su - "$BUILD_USER" -c "cd '$d' && makepkg -sf --noconfirm" \ + || error "Build $name échoué" + pacman -U --noconfirm "$d/"*.pkg.tar.* || error "Install de $name échouée" + publish_to_repo "$name" "$d" + success "$name build + install OK" +} + +# ============================================================ +step "3/4 — Build des paquets (saut si déjà à jour dans local-repo)" +# ============================================================ +# --- Paquets AUR (ordre : deps avant dépendants ; clone shallow puis build/saut) --- +for pkg in "${AUR_PACKAGES[@]}"; do + info "Clonage $pkg (AUR)…" + rm -rf "$BUILD_DIR/$pkg" + su - "$BUILD_USER" -c "git clone --depth=1 https://aur.archlinux.org/${pkg}.git $BUILD_DIR/$pkg" \ + || error "Clonage $pkg échoué" + build_or_skip "$pkg" done -# ------------------------------------------------------------ -# PKGBUILD locaux FWS (deps Anaconda packagées maison, pkgbuilds/) -# cf. portage de l'installateur Anaconda sur Arch. -# ------------------------------------------------------------ +# --- PKGBUILD locaux FWS (ordre explicite, feuilles d'abord, anaconda dernier) --- LOCAL_PKGBUILDS_DIR="$SCRIPT_DIR/pkgbuilds" - -# Ordre de build des PKGBUILD locaux : les FEUILLES d'abord, « anaconda » EN -# DERNIER (il dépend de tous les autres locaux + des AUR déjà construits). -# La boucle alpha naïve mettrait « anaconda » en premier → makepkg -s échouerait -# (ses deps locales pas encore construites/installées). LOCAL_BUILD_ORDER=( pykickstart python-productmd python-requests-file python-simpleline python-meh python-blivet anaconda-widgets anaconda ) BUILT_LOCAL=() -build_local_pkg() { +prepare_and_build_local() { local name="$1" dir="$LOCAL_PKGBUILDS_DIR/$1" - [ -f "$dir/PKGBUILD" ] || return 0 - info "Build local $name…" + [ -f "$dir/PKGBUILD" ] || return 1 rm -rf "$BUILD_DIR/$name" cp -a "$dir" "$BUILD_DIR/$name" - chown -R "$BUILD_USER:$BUILD_USER" "$BUILD_DIR/$name" - su - "$BUILD_USER" -c "cd $BUILD_DIR/$name && makepkg -sf --noconfirm" \ - || error "Build local $name échoué" - # Install (même logique que la boucle AUR) pour que les paquets locaux - # dépendants se résolvent (ex. anaconda → anaconda-widgets/blivet/meh/…). - pacman -U --noconfirm "$BUILD_DIR/$name/"*.pkg.tar.zst \ - || error "Install du paquet local $name échouée" - success "$name build + install OK" - BUILT_LOCAL+=("$name") + build_or_skip "$name" } if [ -d "$LOCAL_PKGBUILDS_DIR" ]; then # 1) Ordre explicite (deps avant dépendants). - for name in "${LOCAL_BUILD_ORDER[@]}"; do build_local_pkg "$name"; done + for name in "${LOCAL_BUILD_ORDER[@]}"; do + if prepare_and_build_local "$name"; then BUILT_LOCAL+=("$name"); fi + done # 2) Repli : tout PKGBUILD présent mais non listé (futur ajout oublié). for dir in "$LOCAL_PKGBUILDS_DIR"/*/; do [ -f "$dir/PKGBUILD" ] || continue name="$(basename "$dir")" printf '%s\n' "${BUILT_LOCAL[@]}" | grep -qx "$name" && continue - build_local_pkg "$name" + prepare_and_build_local "$name" || true done fi # ============================================================ -step "4/4 — Création du repo pacman local fws-local" +step "4/4 — (Re)génération de la base du repo local fws-local" # ============================================================ -rm -rf "$LOCAL_REPO" -mkdir -p "$LOCAL_REPO" - -for pkg in "${AUR_PACKAGES[@]}"; do - cp "$BUILD_DIR/$pkg"/*.pkg.tar.zst "$LOCAL_REPO/" \ - || error "Paquet $pkg introuvable dans $BUILD_DIR/$pkg" -done - -# PKGBUILD locaux FWS -if [ -d "$LOCAL_PKGBUILDS_DIR" ]; then - for dir in "$LOCAL_PKGBUILDS_DIR"/*/; do - [ -f "$dir/PKGBUILD" ] || continue - name="$(basename "$dir")" - cp "$BUILD_DIR/$name"/*.pkg.tar.zst "$LOCAL_REPO/" \ - || error "Paquet local $name introuvable" - done -fi - -repo-add "$LOCAL_REPO/fws-local.db.tar.gz" "$LOCAL_REPO"/*.pkg.tar.zst \ +# local-repo contient déjà TOUS les paquets (construits ce run + sautés des +# runs précédents). On régénère juste la base de données pacman du dépôt. +rm -f "$LOCAL_REPO"/fws-local.db* "$LOCAL_REPO"/fws-local.files* 2>/dev/null || true +repo-add "$LOCAL_REPO/fws-local.db.tar.gz" "$LOCAL_REPO"/*.pkg.tar.* \ || error "repo-add a échoué" success "Repo local prêt : $LOCAL_REPO"