#!/usr/bin/env bash
# Prévisualisation locale du site GitLab Pages de cette carte, sans passer par la CI.
#
# Usage :
# ./scripts/preview.sh (port 8000 par défaut)
# PORT=9000 ./scripts/preview.sh (autre port)
# FORCE_DOCKER=1 ./scripts/preview.sh (ignore le kicad-cli local, force Docker)
#
# Si kicad-cli n'est pas installé sur ta machine (ou si FORCE_DOCKER=1), le
# script utilise l'image Docker officielle kicad/kicad:10.0.0 (nécessite Docker).
#
# Note : les versions 9.0.8, 9.0.9, 10.0.1+ de kicad-cli ont un bug connu qui
# fait disparaître les composants des rendus/exports 3D (render, step, glb),
# quels que soient les flags utilisés. Voir :
# https://forum.kicad.info/t/kicad-cli-pcb-render-excludes-component-3d-models-in-both-9-0-9-and-10-0-1/68911
# L'image Docker de ce script est fixée sur 10.0.0 (avant la régression).
set -euo pipefail
REPO_DIR="$(pwd)"
PORT="${PORT:-8000}"
FORCE_DOCKER="${FORCE_DOCKER:-0}"
KICAD_KNOWN_BUGGY=("9.0.8" "9.0.9" "10.0.1" "10.0.2" "10.0.3" "10.0.4")
if [ ! -f scripts/export_board.py ] || [ ! -f scripts/generate_page.py ]; then
echo "Erreur : lance ce script depuis la racine du repo (scripts/ introuvable ici)." >&2
exit 1
fi
check_local_version() {
local ver
ver="$(kicad-cli version 2>/dev/null | head -1 || true)"
for bad in "${KICAD_KNOWN_BUGGY[@]}"; do
if [[ "$ver" == *"$bad"* ]]; then
echo " ⚠ kicad-cli $ver correspond à une version avec le bug des composants 3D manquants."
echo " Vue 3D (render/step/glb) probablement incomplète. Options :"
echo " - relance avec FORCE_DOCKER=1 (utilisera l'image pinnée 10.0.0, non affectée)"
echo " - ou installe localement une version antérieure au bug (ex. 10.0.0, 9.0.7)"
return
fi
done
}
echo "→ Export KiCad (schéma, PCB, BOM interactive, STEP, rendu)…"
# ── Modèles 3D ───────────────────────────────────────────────────────────────
# Les empreintes référencent leurs modèles via une variable de chemin KiCad
# personnalisée (ex. ${CREPP_3DMODEL_DIR}), définie dans les préférences KiCad
# de chaque poste. Elle n'existe ni dans Docker ni sur un runner CI : sans elle,
# les exports 3D sortent SANS composants.
#
# Détection auto du nom de la variable utilisée par ce PCB :
PCB_FILE="$(find . -maxdepth 1 -name '*.kicad_pcb' | head -1)"
MODEL_VAR=""
if [ -n "$PCB_FILE" ]; then
MODEL_VAR="$(grep -o '(model "\${[^}]*}' "$PCB_FILE" | sed 's/.*\${//; s/}$//' | sort -u | head -1)"
fi
if [ -n "$MODEL_VAR" ]; then
MODEL_DIR="$(eval echo "\${$MODEL_VAR:-}")"
if [ -z "$MODEL_DIR" ]; then
echo " ⚠ Les modèles 3D de ce PCB utilisent \${$MODEL_VAR}, mais cette variable n'est pas définie."
echo " Sans elle, les exports 3D n'auront AUCUN composant. Définis-la, par exemple :"
echo " export $MODEL_VAR=~/Documents/crepp_git/CREPP.io/3dmodels"
echo " (puis relance ce script)"
elif [ ! -d "$MODEL_DIR" ]; then
echo " ⚠ $MODEL_VAR=$MODEL_DIR : ce dossier n'existe pas."
else
echo " Modèles 3D : $MODEL_VAR=$MODEL_DIR"
fi
fi
if [ "$FORCE_DOCKER" != "1" ] && command -v kicad-cli >/dev/null 2>&1; then
echo " kicad-cli trouvé localement ($(kicad-cli version 2>/dev/null | head -1))."
check_local_version
command -v generate_interactive_bom >/dev/null 2>&1 || pip install --user InteractiveHtmlBom -q
python3 scripts/export_board.py
else
[ "$FORCE_DOCKER" = "1" ] && echo " FORCE_DOCKER=1 → utilisation de Docker (image kicad/kicad:10.0.0)."
[ "$FORCE_DOCKER" != "1" ] && echo " kicad-cli absent → utilisation de Docker (image kicad/kicad:10.0.0)."
if ! command -v docker >/dev/null 2>&1; then
echo "Erreur : ni kicad-cli ni docker ne sont disponibles sur cette machine." >&2
exit 1
fi
# Monte le dossier des modèles dans le conteneur et y redéfinit la variable,
# pour que kicad-cli (via export_board.py --define-var) les retrouve.
DOCKER_MOUNT=()
DOCKER_ENV=()
if [ -n "$MODEL_VAR" ] && [ -n "${MODEL_DIR:-}" ] && [ -d "${MODEL_DIR:-}" ]; then
DOCKER_MOUNT=(-v "$MODEL_DIR":/models3d:ro)
DOCKER_ENV=(-e "$MODEL_VAR=/models3d")
fi
docker run --rm --user root \
-v "$REPO_DIR":/work -w /work \
"${DOCKER_MOUNT[@]}" "${DOCKER_ENV[@]}" \
kicad/kicad:10.0.0 bash -c \
"(apt-get update -qq && apt-get install -y -qq xvfb python3-pip) || echo '[avertissement] apt-get a echoue, on tente sans'; \
(pip3 install --break-system-packages InteractiveHtmlBom -q || pip3 install InteractiveHtmlBom -q || pip install InteractiveHtmlBom -q || echo '[avertissement] InteractiveHtmlBom non installe, ibom.html sera absent'); \
python3 scripts/export_board.py"
fi
echo "→ Génération de la page (public/)…"
pip install --user openpyxl -q 2>/dev/null || true
python3 scripts/generate_page.py --output public
echo "→ Serveur local : http://localhost:${PORT}"
cd public
python3 -m http.server "$PORT" >/tmp/preview-server.log 2>&1 &
SERVER_PID=$!
trap 'kill $SERVER_PID 2>/dev/null' EXIT
sleep 1
URL="http://localhost:${PORT}"
if command -v xdg-open >/dev/null 2>&1; then xdg-open "$URL" >/dev/null 2>&1
elif command -v open >/dev/null 2>&1; then open "$URL"
else echo "Ouvre cette URL dans ton navigateur : $URL"
fi
echo "Aperçu en ligne. Ctrl+C pour arrêter le serveur."
wait $SERVER_PID