-
Notifications
You must be signed in to change notification settings - Fork 19.8k
Expand file tree
/
Copy pathgstack-ios-qa-regen
More file actions
executable file
·154 lines (134 loc) · 4.92 KB
/
Copy pathgstack-ios-qa-regen
File metadata and controls
executable file
·154 lines (134 loc) · 4.92 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
#!/usr/bin/env bash
# gstack-ios-qa-regen — deterministically regenerate the iOS DebugBridge
# package and the app-owned typed state accessors.
set -euo pipefail
usage() {
cat <<'EOF'
Usage: gstack-ios-qa-regen --app-source <dir> --bridge-dir <dir>
--app-source Swift source tree to scan for @Observable state
--bridge-dir Destination for the generated local DebugBridge package
EOF
}
APP_SOURCE=""
BRIDGE_DIR=""
while [[ $# -gt 0 ]]; do
case "$1" in
--app-source)
[[ $# -ge 2 ]] || { echo "gstack-ios-qa-regen: --app-source requires a value" >&2; exit 2; }
APP_SOURCE="$2"
shift 2
;;
--bridge-dir)
[[ $# -ge 2 ]] || { echo "gstack-ios-qa-regen: --bridge-dir requires a value" >&2; exit 2; }
BRIDGE_DIR="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
echo "gstack-ios-qa-regen: unknown argument: $1" >&2
usage >&2
exit 2
;;
esac
done
if [[ -z "$APP_SOURCE" || -z "$BRIDGE_DIR" ]]; then
echo "gstack-ios-qa-regen: both --app-source and --bridge-dir are required" >&2
usage >&2
exit 2
fi
if [[ ! -d "$APP_SOURCE" ]]; then
echo "gstack-ios-qa-regen: app source directory not found: $APP_SOURCE" >&2
exit 1
fi
if ! command -v bun >/dev/null 2>&1; then
echo "gstack-ios-qa-regen: bun runtime not on PATH — install from https://bun.sh" >&2
exit 1
fi
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
GSTACK_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
TEMPLATE_DIR="$GSTACK_ROOT/ios-qa/templates"
GENERATOR="$GSTACK_ROOT/ios-qa/scripts/gen-accessors.ts"
VERSION_FILE="$GSTACK_ROOT/VERSION"
GENERATED_DIR="$APP_SOURCE/DebugBridgeGenerated"
for required in "$GENERATOR" "$VERSION_FILE"; do
if [[ ! -f "$required" ]]; then
echo "gstack-ios-qa-regen: missing required gstack file: $required" >&2
exit 1
fi
done
TMP_FILE=""
cleanup() {
if [[ -n "$TMP_FILE" ]]; then
rm -f "$TMP_FILE"
fi
}
trap cleanup EXIT
# Copy through a sibling temporary file so interruption never leaves a
# truncated generated source. Preserve an unchanged destination byte-for-byte
# and metadata-for-metadata on repeated runs.
install_file() {
local source="$1"
local destination="$2"
if [[ ! -f "$source" ]]; then
echo "gstack-ios-qa-regen: missing template: $source" >&2
exit 1
fi
if [[ -f "$destination" ]] && cmp -s "$source" "$destination"; then
return
fi
mkdir -p "$(dirname "$destination")"
TMP_FILE="${destination}.tmp.$$"
cp "$source" "$TMP_FILE"
mv "$TMP_FILE" "$destination"
TMP_FILE=""
}
# Invalidate the completion marker before changing any package source. A
# failed or interrupted regeneration must never look current to ios-sync.
mkdir -p "$GENERATED_DIR"
rm -f -- "$GENERATED_DIR/.gstack-version"
# This is intentionally an allowlist, not a template glob. Wiring belongs to
# the consuming app and StateAccessor.swift is emitted by the parser below.
install_file "$TEMPLATE_DIR/Package.swift.template" \
"$BRIDGE_DIR/Package.swift"
install_file "$TEMPLATE_DIR/StateServer.swift.template" \
"$BRIDGE_DIR/Sources/DebugBridgeCore/StateServer.swift"
install_file "$TEMPLATE_DIR/DebugBridgeManager.swift.template" \
"$BRIDGE_DIR/Sources/DebugBridgeCore/DebugBridgeManager.swift"
install_file "$TEMPLATE_DIR/Bridges.swift.template" \
"$BRIDGE_DIR/Sources/DebugBridgeUI/Bridges.swift"
install_file "$TEMPLATE_DIR/DebugOverlay.swift.template" \
"$BRIDGE_DIR/Sources/DebugBridgeUI/DebugOverlay.swift"
install_file "$TEMPLATE_DIR/DebugBridgeTouch.m.template" \
"$BRIDGE_DIR/Sources/DebugBridgeTouch/DebugBridgeTouch.m"
install_file "$TEMPLATE_DIR/DebugBridgeTouch.h.template" \
"$BRIDGE_DIR/Sources/DebugBridgeTouch/include/DebugBridgeTouch.h"
# Older ios-sync versions copied the entire template set flat into the app's
# generated-source directory. Those files can shadow the package modules or
# make Xcode compile two harness implementations. Remove only the explicit
# obsolete generated paths; handwritten app sources are never touched.
for obsolete in \
"$BRIDGE_DIR/DebugBridgeWiring.swift" \
"$BRIDGE_DIR/StateAccessor.swift" \
"$GENERATED_DIR/Package.swift" \
"$GENERATED_DIR/StateServer.swift" \
"$GENERATED_DIR/DebugBridgeManager.swift" \
"$GENERATED_DIR/Bridges.swift" \
"$GENERATED_DIR/DebugOverlay.swift" \
"$GENERATED_DIR/DebugBridgeTouch.m" \
"$GENERATED_DIR/DebugBridgeTouch.h" \
"$GENERATED_DIR/DebugBridgeWiring.swift"
do
if [[ -f "$obsolete" || -L "$obsolete" ]]; then
rm -f -- "$obsolete"
echo "gstack-ios-qa-regen: removed obsolete generated file $obsolete"
fi
done
bun run "$GENERATOR" --input "$APP_SOURCE" --output "$GENERATED_DIR"
# Stamp only after successful accessor generation. ios-sync uses this marker
# to distinguish a complete current install from an interrupted regeneration.
install_file "$VERSION_FILE" "$GENERATED_DIR/.gstack-version"
echo "gstack-ios-qa-regen: bridge package ready at $BRIDGE_DIR"
echo "gstack-ios-qa-regen: accessors ready at $GENERATED_DIR/StateAccessor.swift"