#!/usr/bin/env bash # # Bootstrap for the iOS receiver. Intended to be run on a Mac with Xcode 26. # It installs XcodeGen (if absent) from the GitHub release (no Homebrew needed), # generates the Xcode project, and builds/tests. # # Usage: # ./bootstrap.sh # generate + build for device # ./bootstrap.sh test # generate + run the unit tests (simulator) # ./bootstrap.sh build-sim # generate + build for the simulator # ./bootstrap.sh generate # just generate the project # # Device install/signing is intentionally left to Xcode: open # Receiver.xcodeproj, set your Apple ID on the Receiver target, and hit Run. set -euo pipefail IOS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TOOLS_DIR="$IOS_DIR/tools" XCODEGEN_BIN="$TOOLS_DIR/xcodegen" PROJ="$IOS_DIR/Receiver.xcodeproj" # 1. Xcode if ! command -v xcodebuild >/dev/null 2>&1; then echo "error: xcodebuild not found. Install Xcode (26.x) and select its CLI tools." >&2 echo " xcode-select --install (or: sudo xcode-select -s /Applications/Xcode.app/Contents/Developer)" >&2 exit 1 fi # 2. XcodeGen: prefer a system copy, then a local install, else download latest. if ! command -v xcodegen >/dev/null 2>&1 && [ ! -x "$XCODEGEN_BIN" ]; then echo "Installing XcodeGen into $TOOLS_DIR ..." mkdir -p "$TOOLS_DIR" url="https://github.com/yonaskolb/XcodeGen/releases/latest/download/xcodegen.zip" tmp="$(mktemp -d)" curl -fL "$url" -o "$tmp/xcodegen.zip" unzip -o -q "$tmp/xcodegen.zip" -d "$TOOLS_DIR" # The release zip extracts to a flat binary named "xcodegen". if [ ! -x "$XCODEGEN_BIN" ] && [ -f "$TOOLS_DIR/xcodegen" ]; then chmod +x "$XCODEGEN_BIN" fi rm -rf "$tmp" fi XCODEGEN="$(command -v xcodegen || echo "$XCODEGEN_BIN")" if [ ! -x "$XCODEGEN" ] && [ ! -x "$XCODEGEN_BIN" ]; then echo "error: XcodeGen not found and download failed." >&2 exit 1 fi XCODEGEN="${XCODEGEN_BIN}" generate() { "$XCODEGEN_BIN" generate --spec "$IOS_DIR/project.yml" --project "$IOS_DIR" echo "Generated $PROJ" } dest_sim() { echo "${IOS_DEST:-platform=iOS Simulator,name=iPhone 16}"; } command="${1:-build}" generate case "$command" in generate) ;; build) xcodebuild -project "$PROJ" -scheme Receiver -destination "generic/platform=iOS" build ;; build-sim) xcodebuild -project "$PROJ" -scheme Receiver -destination "$(dest_sim)" build ;; test) xcodebuild test -project "$PROJ" -scheme Receiver -destination "$(dest_sim)" \ -only-testing:ReceiverTests ;; *) echo "usage: bootstrap.sh [generate|build|build-sim|test]" >&2 exit 1 ;; esac echo "Done."