From 64bb53eadfc6702e78cfde6c51b1452fb7a632e4 Mon Sep 17 00:00:00 2001 From: Josevi Date: Thu, 17 Sep 2026 18:49:26 +0200 Subject: [PATCH] pkgsync: aborta sin commitear si falla el parcheo, notifica fallos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cmd_push() seguía adelante y commiteaba lo que hubiera en disco aunque patch_array_file no encontrara los arrays -- así fue como el fichero acabó vacío en origin/main. Ahora aborta sin tocar git si cualquiera de los 3 parcheos falla. Añade notify_fail() (notify-send con urgencia critical) en los puntos de fallo real de push/pull: parcheo fallido, git push/pull/clone fallidos. Como push corre en ExecStop durante el apagado (sesión/D-Bus cayéndose, notify-send no garantizado), también deja un marcador en disco que el siguiente pull revisa al arrancar con la sesión completa, para no depender de que la notificación del apagado llegara a verse. Co-Authored-By: Claude Sonnet 5 --- pkgsync/pkgsync.sh | 61 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/pkgsync/pkgsync.sh b/pkgsync/pkgsync.sh index 9d888dc..f392ec2 100644 --- a/pkgsync/pkgsync.sh +++ b/pkgsync/pkgsync.sh @@ -23,6 +23,12 @@ METAPAC_CONFIG_DIR="$HOME/.config/metapac" METAPAC_GROUP="$METAPAC_CONFIG_DIR/groups/arch-setup.toml" OVERRIDES_FILE="$METAPAC_CONFIG_DIR/groups/overrides.local.toml" +# Marca que un push falló. pull la revisa al arrancar (con la sesión gráfica +# ya arriba) para avisar aunque el notify-send del propio push, disparado +# durante el apagado con la sesión cayéndose, no llegara a mostrarse. Se +# borra en el primer push que vuelve a tener éxito. +FAIL_MARKER="$HOME/.local/share/pkgsync.failed" + # flatpak sin --user/--system instala en "system" con la config actual de # install_flatpaks() en packages-common.sh. Si tu máquina usa --user, cambia # esto (o verifica con: flatpak list --columns=installation,application). @@ -219,6 +225,18 @@ notify() { command -v notify-send &>/dev/null && timeout 5 notify-send --app-name=pkgsync "$1" "$2" } +# Como notify(), pero urgencia "critical" (se queda en pantalla hasta que se +# cierra a mano) y además deja constancia en $FAIL_MARKER: push corre en +# ExecStop durante el apagado, con la sesión/D-Bus ya cayéndose, así que su +# notify-send puede no llegar a mostrarse -- el marcador es la red de +# seguridad que garantiza el aviso en el siguiente pull, ya con la sesión +# gráfica completa. +notify_fail() { + echo "!! $1: $2" >&2 + printf '%s -- %s: %s\n' "$(date -Iseconds)" "$1" "$2" >"$FAIL_MARKER" + command -v notify-send &>/dev/null && timeout 5 notify-send --app-name=pkgsync --urgency=critical "$1" "$2" +} + # --- subcomandos -------------------------------------------------------------- cmd_bootstrap() { echo ">> pkgsync bootstrap" @@ -282,7 +300,7 @@ cmd_push() { echo "=== push $(date -Iseconds) ===" if [[ ! -d "$REPO_DIR/.git" ]]; then - echo "!! no existe $REPO_DIR, corre 'pkgsync bootstrap' primero" + notify_fail "pkgsync: push falló" "no existe el clon $REPO_DIR, corre 'pkgsync bootstrap'" return 0 fi @@ -314,25 +332,40 @@ cmd_push() { add_flatpak="$(comm -23 "$work/inst_flatpak" "$work/decl_flatpak" | comm -23 - "$work/overrides")" local pc="$REPO_DIR/shared/packages-common.sh" - patch_array_file "$pc" PACMAN_COMMON "$remove_pacman" "$add_pacman" - patch_array_file "$pc" AUR_COMMON "$remove_aur" "$add_aur" - patch_array_file "$pc" FLATPAK_COMMON "$remove_flatpak" "$add_flatpak" + local patch_failed=0 + patch_array_file "$pc" PACMAN_COMMON "$remove_pacman" "$add_pacman" || patch_failed=1 + patch_array_file "$pc" AUR_COMMON "$remove_aur" "$add_aur" || patch_failed=1 + patch_array_file "$pc" FLATPAK_COMMON "$remove_flatpak" "$add_flatpak" || patch_failed=1 rm -rf "$work" + + # No commitear nunca un parcheo a medias/fallido -- así fue como el fichero + # acabó vacío en origin/main una vez (2026-08-27): el parcheo falló pero el + # script siguió y commiteó igualmente lo que hubiera en disco. El fichero + # de trabajo no se toca cuando patch_array_file falla (solo escribe si + # encuentra el array), así que abortar aquí es seguro: el próximo intento + # vuelve a partir del mismo estado. + if (( patch_failed )); then + notify_fail "pkgsync: push falló" "no se pudo parchear packages-common.sh (arrays no encontrados), reviso sin commitear -- $LOG" + return 1 + fi + write_group_file cd "$REPO_DIR" || return 0 git add shared/packages-common.sh if git diff --cached --quiet; then echo "sin cambios de paquetes que subir" + rm -f "$FAIL_MARKER" return 0 fi git commit -m "pkgsync: actualiza inventario de paquetes $(date '+%Y-%m-%d %H:%M')" if timeout 20 git push origin main; then echo "push OK" + rm -f "$FAIL_MARKER" else - echo "push falló (¿sin red?), el commit queda en local para el próximo intento" + notify_fail "pkgsync: push falló" "commit local OK pero 'git push' falló (¿sin red?); el commit queda en local para el próximo intento" fi } @@ -341,17 +374,31 @@ cmd_pull() { exec >>"$LOG" 2>&1 echo "=== pull $(date -Iseconds) ===" + # Red de seguridad: si un push anterior falló (típicamente en ExecStop + # durante el apagado, con la sesión/D-Bus ya cayéndose y su propio + # notify-send sin garantía de mostrarse), avisar aquí sí o sí -- pull corre + # al arrancar sesión, con el escritorio ya completo. + if [[ -f "$FAIL_MARKER" ]]; then + notify_fail "pkgsync: hay un fallo pendiente de revisar" "$(cat "$FAIL_MARKER")" + fi + if ! timeout 15 git ls-remote --exit-code "$REPO_URL" &>/dev/null; then echo "sin conexión con el remoto, me quedo con el estado local" elif [[ ! -d "$REPO_DIR/.git" ]]; then echo "clonando arch-setup en $REPO_DIR..." mkdir -p "$(dirname "$REPO_DIR")" - timeout 30 git clone "$REPO_URL" "$REPO_DIR" && echo "clon inicial OK" || echo "clone falló" + if timeout 30 git clone "$REPO_URL" "$REPO_DIR"; then + echo "clon inicial OK" + else + notify_fail "pkgsync: pull falló" "no se pudo clonar $REPO_URL, revisa $LOG" + fi else if timeout 30 git -C "$REPO_DIR" pull --ff-only origin main; then echo "git pull OK" else - echo "git pull falló (conflicto local o sin red); sigo con el estado que haya" + # ls-remote de arriba ya confirmó que hay red -- esto es un conflicto + # real (fast-forward imposible), no un simple "sin conexión". + notify_fail "pkgsync: pull falló" "'git pull --ff-only' falló (conflicto local, revisa $REPO_DIR a mano); sigo con el estado que haya" fi fi