diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..483eea4 --- /dev/null +++ b/.env.example @@ -0,0 +1,7 @@ +# Connexion SSH au serveur static.alpinux.org +STATIC_USER= +STATIC_HOST=alpinux.org +STATIC_PATH= + +# Répertoire local des assets générés (par wiki/scripts/build-assets.py) +LOCAL_ASSETS_DIR=/tmp/alpinux-static-assets diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env diff --git a/scripts/pull-assets.sh b/scripts/pull-assets.sh new file mode 100755 index 0000000..21f8dfe --- /dev/null +++ b/scripts/pull-assets.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash +# pull-assets.sh — récupère les assets depuis static.alpinux.org vers le répertoire local +# +# Usage : +# ./pull-assets.sh # aperçu des changements + confirmation +# ./pull-assets.sh -y # récupère sans confirmation +# ./pull-assets.sh -n # dry-run seulement (aucune modification) + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ENV_FILE="$SCRIPT_DIR/../.env" + +# ── Couleurs ──────────────────────────────────────────────────────── +RED='\033[0;31m'; YELLOW='\033[1;33m'; GREEN='\033[0;32m' +CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m' + +# ── Config ────────────────────────────────────────────────────────── +if [ ! -f "$ENV_FILE" ]; then + echo -e "${RED}Erreur : fichier .env introuvable.${RESET}" + echo "Copier scripts/../.env.example en .env et remplir les valeurs." + exit 1 +fi +# shellcheck source=/dev/null +source "$ENV_FILE" + +LOCAL_DIR="${LOCAL_ASSETS_DIR:-/tmp/alpinux-static-assets}" +REMOTE_USER="${STATIC_USER:?Variable STATIC_USER manquante dans .env}" +REMOTE_HOST="${STATIC_HOST:?Variable STATIC_HOST manquante dans .env}" +REMOTE_PATH="${STATIC_PATH:?Variable STATIC_PATH manquante dans .env}" +REMOTE="${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}/" + +# ── Arguments ─────────────────────────────────────────────────────── +DRY_RUN=false +AUTO_YES=false +for arg in "$@"; do + case "$arg" in + -n|--dry-run) DRY_RUN=true ;; + -y|--yes) AUTO_YES=true ;; + -h|--help) + sed -n '2,6p' "$0" | sed 's/^# //' + exit 0 ;; + esac +done + +mkdir -p "$LOCAL_DIR" + +# ── Analyse des changements ───────────────────────────────────────── +echo -e "${BOLD}Analyse des changements…${RESET}" +echo -e " Source : ${CYAN}$REMOTE${RESET}" +echo -e " Cible : ${CYAN}$LOCAL_DIR/${RESET}" +echo "" + +DIFF=$(rsync -rlcz --dry-run --itemize-changes \ + "$REMOTE" "$LOCAL_DIR/" 2>&1) + +NEW=0; CHANGED=0 + +while IFS= read -r line; do + item="${line:0:11}" + file="${line:12}" + [ -z "$file" ] && continue + if [[ "$item" =~ ^\>f\+{6,} || "$item" =~ ^\.f\+{6,} ]]; then + echo -e " ${GREEN}nouveau ${RESET} $file" + ((NEW++)) + elif [[ "$item" =~ ^\>f || "$item" =~ ^\.f ]]; then + echo -e " ${YELLOW}modifié ${RESET} $file" + ((CHANGED++)) + fi +done <<< "$DIFF" + +TOTAL=$((NEW + CHANGED)) + +if [ "$TOTAL" -eq 0 ]; then + echo -e "${GREEN}Tout est à jour — aucun fichier à récupérer.${RESET}" + exit 0 +fi + +echo "" +echo -e " ${GREEN}+$NEW nouveau(x)${RESET} ${YELLOW}~$CHANGED modifié(s)${RESET}" +echo "" + +$DRY_RUN && { echo -e "${CYAN}Mode dry-run — aucune modification effectuée.${RESET}"; exit 0; } + +# ── Confirmation ──────────────────────────────────────────────────── +if ! $AUTO_YES; then + read -rp "Récupérer ces fichiers depuis $REMOTE_HOST ? [o/N] " confirm + [[ "$confirm" =~ ^[oOyY]$ ]] || { echo "Annulé."; exit 0; } +fi + +# ── Synchronisation ───────────────────────────────────────────────── +echo "" +echo -e "${BOLD}Récupération en cours…${RESET}" +rsync -rlcz --human-readable --progress \ + "$REMOTE" "$LOCAL_DIR/" + +echo "" +echo -e "${GREEN}✓ Fichiers récupérés dans : $LOCAL_DIR${RESET}" diff --git a/scripts/push-assets.sh b/scripts/push-assets.sh new file mode 100755 index 0000000..5475f63 --- /dev/null +++ b/scripts/push-assets.sh @@ -0,0 +1,105 @@ +#!/usr/bin/env bash +# push-assets.sh — synchronise les assets locaux vers static.alpinux.org +# +# Usage : +# ./push-assets.sh # aperçu des changements + confirmation +# ./push-assets.sh -y # pousse sans confirmation +# ./push-assets.sh -n # dry-run seulement (aucune modification) + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ENV_FILE="$SCRIPT_DIR/../.env" + +# ── Couleurs ──────────────────────────────────────────────────────── +RED='\033[0;31m'; YELLOW='\033[1;33m'; GREEN='\033[0;32m' +CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m' + +# ── Config ────────────────────────────────────────────────────────── +if [ ! -f "$ENV_FILE" ]; then + echo -e "${RED}Erreur : fichier .env introuvable.${RESET}" + echo "Copier scripts/../.env.example en .env et remplir les valeurs." + exit 1 +fi +# shellcheck source=/dev/null +source "$ENV_FILE" + +LOCAL_DIR="${LOCAL_ASSETS_DIR:-/tmp/alpinux-static-assets}" +REMOTE_USER="${STATIC_USER:?Variable STATIC_USER manquante dans .env}" +REMOTE_HOST="${STATIC_HOST:?Variable STATIC_HOST manquante dans .env}" +REMOTE_PATH="${STATIC_PATH:?Variable STATIC_PATH manquante dans .env}" +REMOTE="${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}/" + +# ── Arguments ─────────────────────────────────────────────────────── +DRY_RUN=false +AUTO_YES=false +for arg in "$@"; do + case "$arg" in + -n|--dry-run) DRY_RUN=true ;; + -y|--yes) AUTO_YES=true ;; + -h|--help) + sed -n '2,6p' "$0" | sed 's/^# //' + exit 0 ;; + esac +done + +if [ ! -d "$LOCAL_DIR" ]; then + echo -e "${RED}Erreur : répertoire local introuvable : $LOCAL_DIR${RESET}" + echo "Lancer d'abord : python3 wiki/scripts/build-assets.py" + exit 1 +fi + +# ── Analyse des changements ───────────────────────────────────────── +echo -e "${BOLD}Analyse des changements…${RESET}" +echo -e " Source : ${CYAN}$LOCAL_DIR/${RESET}" +echo -e " Cible : ${CYAN}$REMOTE${RESET}" +echo "" + +DIFF=$(rsync -rlcz --dry-run --itemize-changes --delete \ + "$LOCAL_DIR/" "$REMOTE" 2>&1) + +NEW=0; CHANGED=0; DELETED=0 + +while IFS= read -r line; do + item="${line:0:11}" + file="${line:12}" + [ -z "$file" ] && continue + if [[ "$item" == *"deleting"* ]]; then + echo -e " ${RED}supprimé ${RESET} $file" + ((DELETED++)) + elif [[ "$item" =~ ^\>f\+{6,} ]]; then + echo -e " ${GREEN}nouveau ${RESET} $file" + ((NEW++)) + elif [[ "$item" =~ ^\>f ]]; then + echo -e " ${YELLOW}modifié ${RESET} $file" + ((CHANGED++)) + fi +done <<< "$DIFF" + +TOTAL=$((NEW + CHANGED + DELETED)) + +if [ "$TOTAL" -eq 0 ]; then + echo -e "${GREEN}Tout est à jour — aucun changement à pousser.${RESET}" + exit 0 +fi + +echo "" +echo -e " ${GREEN}+$NEW nouveau(x)${RESET} ${YELLOW}~$CHANGED modifié(s)${RESET} ${RED}-$DELETED supprimé(s)${RESET}" +echo "" + +$DRY_RUN && { echo -e "${CYAN}Mode dry-run — aucune modification effectuée.${RESET}"; exit 0; } + +# ── Confirmation ──────────────────────────────────────────────────── +if ! $AUTO_YES; then + read -rp "Pousser ces changements vers $REMOTE_HOST ? [o/N] " confirm + [[ "$confirm" =~ ^[oOyY]$ ]] || { echo "Annulé."; exit 0; } +fi + +# ── Synchronisation ───────────────────────────────────────────────── +echo "" +echo -e "${BOLD}Synchronisation en cours…${RESET}" +rsync -rlcz --human-readable --progress --delete \ + "$LOCAL_DIR/" "$REMOTE" + +echo "" +echo -e "${GREEN}✓ Synchronisation terminée.${RESET}"