Files
nixos/modules/home-mac/winnie/scripts/doctor.sh
T
Hermes Agent 7498ea4971 feat(macos): setup nix-darwin pour builder l'app Winnie
L'app se build sur le Mac en trois commandes, le toolchain restant dans le
devShell du flake winnie (jamais installé sur le Mac) :
  cd ~/git/nixos && just mac   # déploie ce setup
  winnie-sync                  # attrape ~/git/winnie depuis tower (rsync ssh)
  winnie-ios                   # simulateur ; npm ci + tauri ios init au besoin

- modules/home-mac/winnie : winnie-doctor [--fix], winnie-sync [--delete],
  winnie-shell, winnie-front, winnie-macos, winnie-build-macos, winnie-ios,
  winnie-build-ios, winnie-verify. Scripts en writeShellApplication (shellcheck
  au build) ; scripts.nix est séparé du module pour être constructible depuis
  tower avec les pkgs linux et testable sans Mac.
- profiles/macos : flakes + trusted-users dans nix.conf, et
  system.activationScripts.winnie-xcode (xcode-select -s, licence Xcode,
  -runFirstLaunch) pour que seule l'installation App Store reste manuelle.
- Embarque aussi le setup SSH entrant du Mac (sshd, clé hermes@tower, tunnel
  inverse autossh) qui était déjà dans l'arbre de travail.

Vérifié depuis tower : nix eval du darwinConfigurations.macos (toplevel et
home-manager-generation) + build des scripts en x86_64-linux (shellcheck) et
rsync de bout en bout depuis le dépôt de tower.
2026-10-24 14:33:35 -04:00

144 lines
4.6 KiB
Bash

# winnie-doctor : état du poste Mac pour builder Winnie.
# winnie-doctor diagnostic seul
# winnie-doctor --fix répare ce qui est automatisable (dépôt, node_modules,
# developer dir Xcode, licence, runtime du simulateur)
#
# Xcode, le SDK iOS et les runtimes du simulateur viennent d'Apple, jamais du
# store Nix : ce script est la seule source de vérité sur leur disponibilité.
repo="$HOME/@REPO_REL@"
api="@API_URL@"
sync_bin="@WINNIE_SYNC@"
fix=0
if [ "${1:-}" = "--fix" ]; then
fix=1
fi
todo=0
line() { printf '%-8s %s\n' "$1" "$2"; }
ok() { line "[ok]" "$1"; }
missing() { line "[manque]" "$1"; todo=$((todo + 1)); }
info() { line "[-]" "$1"; }
printf 'winnie-doctor\n\n'
# --- nix ---------------------------------------------------------------
if command -v nix >/dev/null 2>&1; then
ok "nix : $(nix --version)"
else
missing "nix absent du PATH"
fi
# --- dépôt winnie ------------------------------------------------------
if [ -f "$repo/flake.nix" ]; then
ok "dépôt : $repo"
if nix --extra-experimental-features 'nix-command flakes' flake metadata "$repo" >/dev/null 2>&1; then
ok "flake winnie évaluable"
else
missing "flake winnie non évaluable (nix flake metadata $repo)"
fi
else
missing "dépôt : $repo"
if [ "$fix" = 1 ]; then
echo " -> winnie-sync"
"$sync_bin" || true
fi
fi
# --- Xcode : seul le build iOS l'exige ---------------------------------
xcode_ok=0
if [ -d /Applications/Xcode.app ]; then
ok "Xcode.app installé"
xcode_ok=1
else
missing "Xcode.app absent (App Store, recherche « Xcode », ~8 Go)"
info "sans Xcode : le front et le build macOS marchent, seul winnie-ios l'exige"
info "fiche App Store : open 'macappstore://apps.apple.com/app/id497799835'"
fi
if [ -x /usr/bin/xcode-select ]; then
devdir="$(/usr/bin/xcode-select -p 2>/dev/null || true)"
if [ "$devdir" = "/Applications/Xcode.app/Contents/Developer" ]; then
ok "xcode-select : Xcode"
elif [ "$xcode_ok" = 1 ]; then
missing "xcode-select : ${devdir:-vide} (attendu /Applications/Xcode.app/Contents/Developer)"
if [ "$fix" = 1 ]; then
echo " -> sudo xcode-select -s /Applications/Xcode.app (mot de passe macOS demandé)"
sudo /usr/bin/xcode-select -s /Applications/Xcode.app
sudo /usr/bin/xcodebuild -license accept || true
/usr/bin/xcodebuild -runFirstLaunch || true
fi
else
info "xcode-select : ${devdir:-vide} (Command Line Tools, suffisant hors iOS)"
fi
else
info "xcode-select absent (poste non macOS ?)"
fi
if [ "$xcode_ok" = 1 ]; then
sdk="$(/usr/bin/xcrun --sdk iphoneos --show-sdk-version 2>/dev/null || true)"
if [ -n "$sdk" ]; then
ok "SDK iOS : $sdk"
else
missing "SDK iOS (xcrun --sdk iphoneos --show-sdk-version ; licence Xcode non acceptée ?)"
if [ "$fix" = 1 ]; then
echo " -> sudo xcodebuild -license accept"
sudo /usr/bin/xcodebuild -license accept || true
fi
fi
runtime_ok=0
if /usr/bin/xcrun simctl list runtimes 2>/dev/null | grep -q 'iOS '; then
runtime_ok=1
fi
if [ "$runtime_ok" = 1 ]; then
ok "runtime du simulateur iOS"
else
missing "runtime du simulateur iOS"
if [ "$fix" = 1 ]; then
echo " -> xcodebuild -downloadPlatform iOS (~8 Go, plusieurs minutes)"
/usr/bin/xcodebuild -downloadPlatform iOS || true
fi
fi
fi
# --- front / node ------------------------------------------------------
if [ -f "$repo/app/package.json" ]; then
if [ -d "$repo/app/node_modules" ]; then
ok "app/node_modules (npm ci fait)"
else
missing "app/node_modules"
if [ "$fix" = 1 ]; then
echo " -> npm ci dans le devShell (~1 min)"
(cd "$repo" && nix --extra-experimental-features 'nix-command flakes' develop -c bash -c "cd app && npm ci") || true
fi
fi
if [ -d "$repo/app/src-tauri/gen/apple" ]; then
ok "projet Xcode généré (src-tauri/gen/apple)"
else
info "src-tauri/gen/apple absent : winnie-ios le génère (tauri ios init)"
fi
fi
# --- API ---------------------------------------------------------------
code="$(curl -sS -m 8 -o /dev/null -w '%{http_code}' "$api/healthz" 2>/dev/null || true)"
if [ "$code" = "200" ]; then
ok "API : $api"
else
missing "API : $api/healthz (HTTP ${code:-aucune réponse})"
fi
# --- verdict -----------------------------------------------------------
printf '\n'
if [ "$todo" -eq 0 ]; then
echo "tout est prêt : winnie-ios (simulateur), winnie-front, winnie-macos."
exit 0
fi
echo "$todo contrôle(s) en échec."
if [ "$fix" = 1 ]; then
echo "relance winnie-doctor pour vérifier ce qui reste."
else
echo "winnie-doctor --fix répare ce qui est automatisable."
fi
exit 1