run-demo.sh (4964B)
1 #!/bin/bash 2 # Builds Crossmate and launches it with the `--crossmate-seed-demo` flag, which 3 # brings the app up against a throwaway in-memory store pre-filled with a couple 4 # of shared, in-progress games and a few crossmates. Lets you eyeball the Game 5 # List colour strips, the friends list, and the puzzle scoreboard without iCloud 6 # or a real opponent. The real on-disk store is untouched. 7 # 8 # Runs on a dedicated demo simulator — created on first run, reused thereafter — 9 # so it never collides with whatever device Xcode has open. iPhone and iPad each 10 # get their own demo device, so the two can coexist. 11 # 12 # Usage: bash Scripts/run-demo.sh [iOS-major] (iPhone, default major 26) 13 # bash Scripts/run-demo.sh --ipad [iOS-major] (iPad mini) 14 # bash Scripts/run-demo.sh [--ipad] --delete (remove the demo simulator) 15 set -euo pipefail 16 17 SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" 18 REPO_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" 19 source "${SCRIPT_DIR}/select-simulator.sh" 20 21 # Parse arguments in any order: --ipad picks the iPad demo device, --delete tears 22 # the resolved device down, and a bare number overrides the iOS major version. 23 DEVICE_KIND="iphone" 24 DELETE=false 25 MAJOR=26 26 for arg in "$@"; do 27 case "$arg" in 28 --ipad) DEVICE_KIND="ipad" ;; 29 --iphone) DEVICE_KIND="iphone" ;; 30 --delete) DELETE=true ;; 31 [0-9]*) MAJOR="$arg" ;; 32 *) echo "Unknown argument: $arg" >&2; exit 1 ;; 33 esac 34 done 35 36 if [ "$DEVICE_KIND" = "ipad" ]; then 37 DEMO_NAME="Crossmate Demo iPad" 38 else 39 DEMO_NAME="Crossmate Demo" 40 fi 41 BUNDLE_ID="net.inqk.crossmate" 42 DERIVED_DATA="/tmp/crossmate-demo-derived" 43 44 # Look up the demo device (empty if it doesn't exist yet). `|| true` keeps a 45 # no-match grep (the expected first-run case) from tripping `set -o pipefail`. 46 UDID=$(xcrun simctl list devices \ 47 | grep -F "${DEMO_NAME} (" \ 48 | head -1 \ 49 | sed -E 's/.*\(([0-9A-Fa-f-]{36})\).*/\1/' || true) 50 51 # `--delete` tears the demo simulator down and exits. 52 if [ "$DELETE" = true ]; then 53 if [ -n "$UDID" ]; then 54 xcrun simctl shutdown "$UDID" 2>/dev/null || true 55 xcrun simctl delete "$UDID" 56 echo "Deleted '${DEMO_NAME}' (${UDID})." 57 else 58 echo "No '${DEMO_NAME}' simulator to delete." 59 fi 60 exit 0 61 fi 62 63 if [ -n "$UDID" ]; then 64 echo "Reusing '${DEMO_NAME}' (${UDID})" 65 else 66 # Create it on the newest available iOS <major> runtime. select_simulator picks 67 # the runtime (and an iPhone model); for iPad we swap in the newest iPad mini. 68 # Resolve the device type and runtime as CoreSimulator identifiers, which is 69 # what `simctl create` expects. 70 select_simulator "$MAJOR" 71 if [ "$DEVICE_KIND" = "ipad" ]; then 72 # Pick the newest iPad mini without trusting the list's order: tag each one 73 # with the first number in its name — the chip ("A17") or generation ("6th"), 74 # whichever the model uses — then sort numerically and take the largest. Chip 75 # numbers dwarf generation numbers, so chip-named models always win. 76 DEVICE_TYPE_LINE=$(xcrun simctl list devicetypes \ 77 | grep -F "iPad mini" \ 78 | sed -E 's/^iPad mini[^0-9]*([0-9]+).*/\1 &/' \ 79 | sort -rn -k1,1 \ 80 | head -1 \ 81 | cut -f2- || true) 82 else 83 DEVICE_TYPE_LINE=$(xcrun simctl list devicetypes \ 84 | grep -E "^${DEVICE} \(" \ 85 | head -1 || true) 86 fi 87 # The display name is the line minus its trailing "(com.apple…)" identifier; 88 # the identifier is that parenthesised tail. Parse both from the one line so 89 # iPad names that themselves contain parens — "iPad mini (A17 Pro)" — survive. 90 DEVICE=$(sed -E 's/ \(com\.apple[^)]*\)$//' <<<"$DEVICE_TYPE_LINE") 91 DEVICE_TYPE_ID=$(sed -E 's/.*\((com\.apple[^)]*)\)$/\1/' <<<"$DEVICE_TYPE_LINE") 92 RUNTIME_ID=$(xcrun simctl list runtimes available \ 93 | grep "iOS ${RUNTIME} (" \ 94 | head -1 \ 95 | sed -E 's/.* - (com\.apple[^ ]*).*/\1/' || true) 96 if [ -z "$DEVICE_TYPE_ID" ] || [ -z "$RUNTIME_ID" ]; then 97 echo "Couldn't resolve a device type / runtime to create '${DEMO_NAME}'." >&2 98 exit 1 99 fi 100 echo "Creating '${DEMO_NAME}' (${DEVICE}, iOS ${RUNTIME})" 101 UDID=$(xcrun simctl create "${DEMO_NAME}" "${DEVICE_TYPE_ID}" "${RUNTIME_ID}") 102 fi 103 104 # Bring the Simulator app forward, then boot the demo device into it. 105 open -a Simulator 106 xcrun simctl boot "$UDID" 2>/dev/null || true 107 xcrun simctl bootstatus "$UDID" -b 108 109 xcodebuild build \ 110 -scheme "Crossmate" \ 111 -project "${REPO_DIR}/Crossmate.xcodeproj" \ 112 -destination "id=${UDID}" \ 113 -derivedDataPath "$DERIVED_DATA" \ 114 2>&1 115 116 APP_PATH="${DERIVED_DATA}/Build/Products/Debug-iphonesimulator/Crossmate.app" 117 if [ ! -d "$APP_PATH" ]; then 118 echo "Built app not found at ${APP_PATH}" >&2 119 exit 1 120 fi 121 122 xcrun simctl install "$UDID" "$APP_PATH" 123 xcrun simctl launch --terminate-running-process "$UDID" "$BUNDLE_ID" \ 124 --crossmate-seed-demo 125 126 # Bring the Simulator back to the front now the app is up. 127 open -a Simulator 128 129 echo "" 130 echo "Launched ${BUNDLE_ID} with --crossmate-seed-demo on '${DEMO_NAME}' (${UDID})."