#!/usr/bin/env bash # install.sh — set up the Kidsbox development environment # Installs ESP-IDF v5.2 + ESP-ADF v2.7, or validates an existing installation. # Supports: Linux (Debian/Ubuntu/Arch) and macOS (with Homebrew) set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" BOLD='\033[1m'; GREEN='\033[0;32m'; YELLOW='\033[0;33m'; RED='\033[0;31m'; NC='\033[0m' info() { echo -e "${GREEN}[install]${NC} $*"; } warn() { echo -e "${YELLOW}[warn]${NC} $*"; } die() { echo -e "${RED}[error]${NC} $*" >&2; exit 1; } heading() { echo -e "\n${BOLD}$*${NC}"; } IDF_VERSION="v5.2.3" ADF_VERSION="v2.7" IDF_DEFAULT="$HOME/esp/esp-idf" ADF_DEFAULT="$HOME/esp/esp-adf" # ── detect OS ───────────────────────────────────────────────────────────────── OS="$(uname -s)" if [[ "$OS" == "Darwin" ]]; then info "macOS detected" MISSING_HINT=' Install missing tools with Homebrew: brew install git python3 cmake ninja' elif [[ "$OS" == "Linux" ]]; then info "Linux detected" MISSING_HINT=' Install missing tools: sudo apt-get install git python3 python3-pip cmake ninja-build' else die "Unsupported OS: $OS" fi # ── prerequisites ───────────────────────────────────────────────────────────── heading "Checking prerequisites" MISSING=() for cmd in git python3 cmake ninja; do if command -v "$cmd" &>/dev/null; then info "$cmd: $(command -v $cmd)" else MISSING+=("$cmd") warn "$cmd: NOT FOUND" fi done if [[ ${#MISSING[@]} -gt 0 ]]; then echo "" echo -e "${MISSING_HINT}" if [[ "$OS" == "Darwin" ]]; then echo " If Homebrew is not installed: https://brew.sh" fi echo "" die "Missing prerequisites: ${MISSING[*]}" fi # pip3 may not exist as a standalone command on newer Python installs; try both if command -v pip3 &>/dev/null; then info "pip3: $(command -v pip3)" elif python3 -m pip --version &>/dev/null 2>&1; then info "pip: available via python3 -m pip" else echo -e "${MISSING_HINT}" die "pip not found (tried pip3 and python3 -m pip)" fi PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') python3 -c 'import sys; sys.exit(0 if sys.version_info >= (3,8) else 1)' \ || die "Python >= 3.8 required (found $PYTHON_VERSION)" info "Python $PYTHON_VERSION: OK" # macOS: Xcode Command Line Tools are required by ESP-IDF's install script if [[ "$OS" == "Darwin" ]]; then if ! xcode-select -p &>/dev/null; then die "Xcode Command Line Tools not found.\n Run: xcode-select --install\n Then re-run this script." fi info "Xcode CLT: $(xcode-select -p)" fi # ── ESP-IDF ─────────────────────────────────────────────────────────────────── heading "ESP-IDF ($IDF_VERSION)" if [[ -n "${IDF_PATH:-}" && -f "$IDF_PATH/export.sh" ]]; then INSTALLED_TAG=$(git -C "$IDF_PATH" describe --tags 2>/dev/null || echo "unknown") info "Found existing ESP-IDF at \$IDF_PATH=$IDF_PATH (tag: $INSTALLED_TAG)" warn "Skipping IDF install. To use a fresh install, unset \$IDF_PATH and re-run." else IDF_PATH="${IDF_DEFAULT}" info "Installing ESP-IDF $IDF_VERSION to $IDF_PATH" mkdir -p "$(dirname "$IDF_PATH")" if [[ -d "$IDF_PATH/.git" ]]; then git -C "$IDF_PATH" fetch --tags git -C "$IDF_PATH" checkout "$IDF_VERSION" else git clone --depth 1 --branch "$IDF_VERSION" \ https://github.com/espressif/esp-idf.git "$IDF_PATH" fi git -C "$IDF_PATH" submodule update --init --recursive info "Running ESP-IDF install script (downloads toolchain — may take a while)" "$IDF_PATH/install.sh" esp32 info "ESP-IDF installed." fi # ── ESP-ADF ─────────────────────────────────────────────────────────────────── heading "ESP-ADF ($ADF_VERSION)" if [[ -n "${ADF_PATH:-}" && -d "$ADF_PATH" ]]; then INSTALLED_TAG=$(git -C "$ADF_PATH" describe --tags 2>/dev/null || echo "unknown") info "Found existing ESP-ADF at \$ADF_PATH=$ADF_PATH (tag: $INSTALLED_TAG)" warn "Skipping ADF install. To use a fresh install, unset \$ADF_PATH and re-run." else ADF_PATH="${ADF_DEFAULT}" info "Installing ESP-ADF $ADF_VERSION to $ADF_PATH" mkdir -p "$(dirname "$ADF_PATH")" if [[ -d "$ADF_PATH/.git" ]]; then git -C "$ADF_PATH" fetch --tags git -C "$ADF_PATH" checkout "$ADF_VERSION" else git clone --depth 1 --branch "$ADF_VERSION" \ https://github.com/espressif/esp-adf.git "$ADF_PATH" fi git -C "$ADF_PATH" submodule update --init --recursive info "ESP-ADF installed." fi # ── write .env ──────────────────────────────────────────────────────────────── heading "Writing .env" ENV_FILE="$SCRIPT_DIR/.env" cat > "$ENV_FILE" <