crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

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})."