refactor(setup-aur): implement incremental build system for AUR and local packages

Replace the full rebuild approach with an incremental system that skips packages already present in local-repo at the same version. This provides significant performance improvement when iterating on individual packages.

Key changes:
- Add helper functions: pkgbuild_fullver(), repo_has(), publish_to_repo(), and build_or_skip()
- Use shallow git clones (--depth=1) for AUR packages to reduce download time
- Skip package builds if already present in local-repo with matching version
- Always install packages to resolve inter-package dependencies (AUR→AUR chains, anaconda, etc.)
- Consolidate local PKGBUILD building with the new incremental system
- Regenerate only the repo database instead of copying all packages each run
- Update step 4 to regenerate repo database from existing packages in local-repo
This commit is contained in:
2026-06-17 13:21:52 +02:00
parent 4473f0eee7
commit fc62c7e9c2
+75 -58
View File
@@ -200,92 +200,109 @@ fi
chown -R "$BUILD_USER:$BUILD_USER" "$BUILD_DIR" chown -R "$BUILD_USER:$BUILD_USER" "$BUILD_DIR"
# ============================================================ # ============================================================
step "3/4Build des paquets AUR : ${AUR_PACKAGES[*]}" # Helpersbuild 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 mkdir -p "$LOCAL_REPO"
info "Clonage $pkg"
su - "$BUILD_USER" -c "git clone https://aur.archlinux.org/${pkg}.git $BUILD_DIR/$pkg" \
|| error "Clonage $pkg échoué"
info "Build $pkg (peut prendre plusieurs minutes)…" # Version « [epoch:]pkgver-pkgrel » lue dans un PKGBUILD (sourcing en sous-shell).
su - "$BUILD_USER" -c "cd $BUILD_DIR/$pkg && makepkg -s --noconfirm" \ # Vide si illisible → on (re)construit par sécurité. Nos paquets n'ont pas de
|| error "Build $pkg échoué" # pkgver() VCS, donc le pkgver littéral est exact.
# Installe le paquet construit AVANT de passer au suivant : indispensable pkgbuild_fullver() {
# pour les chaînes AUR→AUR (libreport dépend de satyr + libxmlrpc) et pour ( cd "$1" 2>/dev/null && source ./PKGBUILD >/dev/null 2>&1 \
# que les PKGBUILD locaux (python-meh → libreport) trouvent leurs deps. && printf '%s%s-%s' "${epoch:+$epoch:}" "$pkgver" "$pkgrel" ) 2>/dev/null || true
# 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" # Le paquet <name> en version <fullver> est-il déjà dans local-repo ? Le motif
success "$pkg build + install OK" # « -$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 <name> (source déjà déposée dans $BUILD_DIR/<name>).
# 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 done
# ------------------------------------------------------------ # --- PKGBUILD locaux FWS (ordre explicite, feuilles d'abord, anaconda dernier) ---
# PKGBUILD locaux FWS (deps Anaconda packagées maison, pkgbuilds/)
# cf. portage de l'installateur Anaconda sur Arch.
# ------------------------------------------------------------
LOCAL_PKGBUILDS_DIR="$SCRIPT_DIR/pkgbuilds" 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=( LOCAL_BUILD_ORDER=(
pykickstart python-productmd python-requests-file python-simpleline pykickstart python-productmd python-requests-file python-simpleline
python-meh python-blivet anaconda-widgets anaconda python-meh python-blivet anaconda-widgets anaconda
) )
BUILT_LOCAL=() BUILT_LOCAL=()
build_local_pkg() { prepare_and_build_local() {
local name="$1" dir="$LOCAL_PKGBUILDS_DIR/$1" local name="$1" dir="$LOCAL_PKGBUILDS_DIR/$1"
[ -f "$dir/PKGBUILD" ] || return 0 [ -f "$dir/PKGBUILD" ] || return 1
info "Build local $name"
rm -rf "$BUILD_DIR/$name" rm -rf "$BUILD_DIR/$name"
cp -a "$dir" "$BUILD_DIR/$name" cp -a "$dir" "$BUILD_DIR/$name"
chown -R "$BUILD_USER:$BUILD_USER" "$BUILD_DIR/$name" build_or_skip "$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")
} }
if [ -d "$LOCAL_PKGBUILDS_DIR" ]; then if [ -d "$LOCAL_PKGBUILDS_DIR" ]; then
# 1) Ordre explicite (deps avant dépendants). # 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é). # 2) Repli : tout PKGBUILD présent mais non listé (futur ajout oublié).
for dir in "$LOCAL_PKGBUILDS_DIR"/*/; do for dir in "$LOCAL_PKGBUILDS_DIR"/*/; do
[ -f "$dir/PKGBUILD" ] || continue [ -f "$dir/PKGBUILD" ] || continue
name="$(basename "$dir")" name="$(basename "$dir")"
printf '%s\n' "${BUILT_LOCAL[@]}" | grep -qx "$name" && continue printf '%s\n' "${BUILT_LOCAL[@]}" | grep -qx "$name" && continue
build_local_pkg "$name" prepare_and_build_local "$name" || true
done done
fi 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" # local-repo contient déjà TOUS les paquets (construits ce run + sautés des
mkdir -p "$LOCAL_REPO" # 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
for pkg in "${AUR_PACKAGES[@]}"; do repo-add "$LOCAL_REPO/fws-local.db.tar.gz" "$LOCAL_REPO"/*.pkg.tar.* \
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 \
|| error "repo-add a échoué" || error "repo-add a échoué"
success "Repo local prêt : $LOCAL_REPO" success "Repo local prêt : $LOCAL_REPO"