-
Notifications
You must be signed in to change notification settings - Fork 138
Expand file tree
/
Copy pathpreinstall
More file actions
executable file
·294 lines (253 loc) · 11.3 KB
/
Copy pathpreinstall
File metadata and controls
executable file
·294 lines (253 loc) · 11.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#!/bin/bash
# Blitz PKG Preinstall Script
# Checks all prerequisites: Xcode, disk space, CLI tools, license, simulator runtime.
# Shows errors via osascript dialogs using launchctl asuser for GUI access.
IS_ROOT=false
if [ "$(id -u)" = "0" ]; then
IS_ROOT=true
fi
run_as_user() {
if [ "$IS_ROOT" = true ] && [ -n "${CONSOLE_UID:-}" ]; then
launchctl asuser "$CONSOLE_UID" sudo -u "$CONSOLE_USER" "$@"
else
"$@"
fi
}
LOG="/tmp/blitz_install.log"
# clear and create (truncate if exists)
: > "$LOG" 2>/dev/null || { rm -f "$LOG"; : > "$LOG"; } || LOG="/dev/null"
echo "" >> "$LOG"
echo "=== Blitz Preinstall $(date) ===" >> "$LOG"
T_PREINSTALL_START=$(date +%s)
# Make log file writable by all users so console user can write to it
chmod 666 "$LOG" 2>/dev/null || true
# Show an error dialog to the user (pkg installer hides script output)
show_error() {
local title="$1"
local message="$2"
echo "FATAL: $title — $message" >> "$LOG"
run_as_user osascript \
-e 'on run argv' \
-e 'display dialog (item 2 of argv) with title (item 1 of argv) buttons {"OK"} default button "OK" with icon stop' \
-e 'end run' \
-- "$title" "$message" 2>/dev/null || true
}
# Show a notification (non-blocking)
show_status() {
local message="$1"
echo "STATUS: $message" >> "$LOG"
run_as_user osascript \
-e 'on run argv' \
-e 'display notification (item 1 of argv) with title "Blitz Installer"' \
-e 'end run' \
-- "$message" 2>/dev/null || true
}
has_full_xcode() {
xcode-select -p >/dev/null 2>&1 && \
/usr/bin/xcodebuild -version >/dev/null 2>&1
}
# Skip checks if not installing to startup volume
if [ "$3" != "/" ]; then
echo "Not installing to startup volume ($3), skipping checks" >> "$LOG"
exit 0
fi
ERRORS=()
# ============================================================================
# 0a. Clean up old Tauri-based Blitz app (dev.blitz.mac)
# The Tauri app has a different bundle ID and icon — remove it to avoid
# confusion with the new native app.
# ============================================================================
# ----------------------------------------------------------------------------
# TAURI MIGRATION CLEANUP (can be removed once Tauri users have migrated)
# Only runs if an old Tauri-based Blitz app is detected — skipped otherwise.
# ----------------------------------------------------------------------------
OLD_TAURI_APP="/Applications/Blitz.app"
EXISTING_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$OLD_TAURI_APP/Contents/Info.plist" 2>/dev/null || echo "")
if [ "$EXISTING_ID" = "dev.blitz.mac" ] || [ "$EXISTING_ID" = "dev1.blitz.mac" ]; then
echo "Found old Tauri Blitz app ($EXISTING_ID), running migration cleanup..." >> "$LOG"
killall Blitz 2>/dev/null || true
rm -rf "$OLD_TAURI_APP"
echo "Removed old Tauri Blitz.app" >> "$LOG"
# Forget stale pkg receipts and reset TCC for old Tauri bundle IDs
for OLD_ID in dev.blitz.mac dev1.blitz.mac; do
pkgutil --forget "$OLD_ID" >> "$LOG" 2>&1 || true
tccutil reset ScreenCapture "$OLD_ID" >> "$LOG" 2>&1 || true
tccutil reset Accessibility "$OLD_ID" >> "$LOG" 2>&1 || true
done
# Remove .localized directories left by previous pkg relocations
for d in /Applications/Blitz.localized /Applications/Blitz-*.localized; do
[ -d "$d" ] && rm -rf "$d" && echo "Removed stale install dir: $d" >> "$LOG"
done
echo "Tauri migration cleanup done" >> "$LOG"
else
echo "No old Tauri app detected, skipping migration cleanup" >> "$LOG"
fi
# ----------------------------------------------------------------------------
# ============================================================================
# 0b. Reset TCC permissions (first install only)
# With Developer ID signing, TCC entries persist across binary replacement
# (matched on team ID, not CDHash). Only reset on first install.
# ============================================================================
# Check if a native Blitz.app (com.blitz.macos) is already installed
NATIVE_EXISTS=false
if [ -d "/Applications/Blitz.app" ]; then
EXISTING_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "/Applications/Blitz.app/Contents/Info.plist" 2>/dev/null || echo "")
if [ "$EXISTING_ID" = "com.blitz.macos" ]; then
NATIVE_EXISTS=true
fi
fi
if [ "$NATIVE_EXISTS" = false ]; then
echo "First install, resetting any stale TCC entries..." >> "$LOG"
tccutil reset ScreenCapture com.blitz.macos >> "$LOG" 2>&1 || true
tccutil reset Accessibility com.blitz.macos >> "$LOG" 2>&1 || true
echo "TCC entries reset for com.blitz.macos" >> "$LOG"
else
echo "Upgrade detected, preserving existing TCC permissions" >> "$LOG"
fi
# ============================================================================
# 1. Disk space check
# ============================================================================
T_STEP=$(date +%s)
# Detect console user
CONSOLE_USER=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }')
CONSOLE_HOME=""
CONSOLE_UID=""
if [ -n "$CONSOLE_USER" ] && [ "$CONSOLE_USER" != "loginwindow" ]; then
CONSOLE_HOME=$(eval echo "~$CONSOLE_USER")
CONSOLE_UID=$(id -u "$CONSOLE_USER" 2>/dev/null)
fi
# Base: 5 GB (Blitz.app ~0.5 + warm template ~4.5 including node_modules, Pods, xcodebuild)
REQUIRED_MB=5120
# +7 GB if iOS Simulator runtime is not installed
if ! xcrun simctl list runtimes 2>/dev/null | grep -q 'iOS.*SimRuntime'; then
REQUIRED_MB=$((REQUIRED_MB + 7168))
echo "Disk check: iOS Simulator runtime not found, adding 7 GB to requirement" >> "$LOG"
fi
AVAILABLE_KB=$(df -k / | awk 'NR==2 {print $4}')
AVAILABLE_MB=$((AVAILABLE_KB / 1024))
echo "Disk check: available ${AVAILABLE_MB} MB, required ${REQUIRED_MB} MB" >> "$LOG"
if [ "$AVAILABLE_MB" -lt "$REQUIRED_MB" ]; then
AVAILABLE_GB=$(awk "BEGIN {printf \"%.1f\", $AVAILABLE_MB / 1024}")
REQUIRED_GB=$(awk "BEGIN {printf \"%.1f\", $REQUIRED_MB / 1024}")
ERRORS+=("Not enough disk space.\n\
Blitz requires approximately ${REQUIRED_GB} GB of free space for installation, \
but only ${AVAILABLE_GB} GB is available.\n\n\
Free up some disk space and try again.")
fi
echo "TIMING: disk space check took $(( $(date +%s) - T_STEP ))s" >> "$LOG"
# ============================================================================
# 2. Full Xcode check (auto-fix xcode-select if Xcode.app found on disk)
# ============================================================================
T_STEP=$(date +%s)
if ! has_full_xcode; then
echo "Xcode not configured, searching for Xcode.app on disk..." >> "$LOG"
XCODE_SEARCH_PATHS=(
"/Applications/Xcode.app"
"/Applications/Xcode-beta.app"
)
if [ -n "$CONSOLE_HOME" ]; then
XCODE_SEARCH_PATHS+=(
"$CONSOLE_HOME/Downloads/Xcode.app"
"$CONSOLE_HOME/Downloads/Xcode-beta.app"
"$CONSOLE_HOME/Desktop/Xcode.app"
"$CONSOLE_HOME/Applications/Xcode.app"
)
fi
FOUND_XCODE=""
for xpath in "${XCODE_SEARCH_PATHS[@]}"; do
if [ -d "$xpath/Contents/Developer" ]; then
FOUND_XCODE="$xpath"
break
fi
done
if [ -n "$FOUND_XCODE" ]; then
echo "Found Xcode at $FOUND_XCODE, running xcode-select -s ..." >> "$LOG"
if [ "$IS_ROOT" = true ]; then
sudo xcode-select -s "$FOUND_XCODE/Contents/Developer" 2>> "$LOG"
else
echo "WARNING: Not root, cannot run xcode-select -s" >> "$LOG"
fi
if has_full_xcode; then
echo "OK: xcode-select now points to $FOUND_XCODE" >> "$LOG"
else
echo "FATAL: xcode-select -s succeeded but xcodebuild still fails" >> "$LOG"
ERRORS+=("Xcode was found at $FOUND_XCODE but could not be configured.\n\
Try opening Xcode once to complete setup, then re-run this installer.")
fi
else
echo "FATAL: Xcode.app not found in any search path" >> "$LOG"
ERRORS+=("Xcode is not installed.\n\
Blitz requires the full Xcode app to build and run iOS apps.\n\n\
Please install Xcode from the App Store, then re-run this installer.")
fi
else
echo "OK: Xcode at $(xcode-select -p 2>/dev/null)" >> "$LOG"
fi
echo "TIMING: xcode check took $(( $(date +%s) - T_STEP ))s" >> "$LOG"
# ============================================================================
# 3. Xcode Command Line Tools
# ============================================================================
T_STEP=$(date +%s)
if ! xcode-select -p >/dev/null 2>&1; then
echo "Xcode CLI tools not found, attempting install..." >> "$LOG"
xcode-select --install 2>> "$LOG"
until xcode-select -p >/dev/null 2>&1; do
sleep 5
done
echo "Xcode CLI tools installed successfully" >> "$LOG"
fi
echo "OK: Xcode CLI tools at $(xcode-select -p 2>/dev/null || echo 'not found')" >> "$LOG"
echo "TIMING: xcode CLI tools check took $(( $(date +%s) - T_STEP ))s" >> "$LOG"
# ============================================================================
# 4. Xcode license (auto-accept)
# ============================================================================
T_STEP=$(date +%s)
if xcode-select -p >/dev/null 2>&1; then
LICENSE_CHECK=$(xcrun clang 2>&1)
if echo "$LICENSE_CHECK" | grep -qi "license"; then
echo "Xcode license not accepted, attempting to accept..." >> "$LOG"
xcodebuild -license accept 2>> "$LOG"
LICENSE_CHECK=$(xcrun clang 2>&1)
if echo "$LICENSE_CHECK" | grep -qi "license"; then
ERRORS+=("Xcode license has not been accepted.\nRun: sudo xcodebuild -license accept")
else
echo "Xcode license accepted successfully" >> "$LOG"
fi
else
echo "OK: Xcode license accepted" >> "$LOG"
fi
fi
echo "TIMING: xcode license check took $(( $(date +%s) - T_STEP ))s" >> "$LOG"
# ============================================================================
# 5. iOS Simulator runtime (auto-download if Xcode is present)
# ============================================================================
T_STEP=$(date +%s)
if xcrun simctl list runtimes 2>/dev/null | grep -q 'iOS.*SimRuntime'; then
echo "OK: iOS Simulator runtime installed" >> "$LOG"
else
echo "iOS Simulator runtime not found, attempting install..." >> "$LOG"
xcodebuild -runFirstLaunch 2>> "$LOG" || true
xcodebuild -downloadPlatform iOS > /dev/null 2>> "$LOG"
if xcrun simctl list runtimes 2>/dev/null | grep -q 'iOS.*SimRuntime'; then
echo "OK: Simulator runtime now available" >> "$LOG"
else
ERRORS+=("iOS Simulator runtime could not be installed.\n\
Open Xcode and install an iOS Simulator runtime from:\n\
Xcode -> Settings -> Platforms")
fi
fi
echo "TIMING: simulator check took $(( $(date +%s) - T_STEP ))s" >> "$LOG"
if [ ${#ERRORS[@]} -gt 0 ]; then
MSG="Blitz requires the following to be fixed before installation:\n\n"
for i in "${!ERRORS[@]}"; do
MSG+="$((i+1)). ${ERRORS[$i]}\n\n"
done
MSG+="After fixing these, re-run the installer.\nSee /tmp/blitz_install.log for details."
echo "=== Preinstall FAILED with ${#ERRORS[@]} error(s) ===" >> "$LOG"
printf "%b\n" "$MSG" >> "$LOG"
show_error "Blitz - Missing Prerequisites" "$(printf "%b" "$MSG")"
exit 1
fi
echo "TIMING: preinstall total took $(( $(date +%s) - T_PREINSTALL_START ))s" >> "$LOG"
echo "=== Preinstall checks passed ===" >> "$LOG"
exit 0