forked from pfalstad/circuitjs1
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdev.sh
More file actions
executable file
·389 lines (330 loc) · 11.2 KB
/
dev.sh
File metadata and controls
executable file
·389 lines (330 loc) · 11.2 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
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
#!/bin/bash
set -o errexit -o nounset # bash script safety
# For GWT download URLs see https://www.gwtproject.org/versions.html
# Note: Google Storage URLs for older GWT versions (2.8.x, 2.9.x) return 403 Forbidden
# Use GitHub releases for newer versions which are more reliably available
GWT_VERSION="2.13.0"
GWT_URL="https://github.com/gwtproject/gwt/releases/download/2.13.0/gwt-2.13.0.zip"
#GWT_URL="https://storage.googleapis.com/gwt-releases/gwt-2.9.0.zip" # 403 Forbidden
#GWT_URL="https://goo.gl/pZZPXS" # 2.8.2 - 403 Forbidden
#GWT_URL="https://goo.gl/TysXZl" # 2.8.1 (does not run)
SCRIPT_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
SDK_DIR="$SCRIPT_DIR/.."
GWT_DIR="$SDK_DIR/gwt-$GWT_VERSION"
GWT_PROD_MODULE="com.lushprojects.circuitjs1.circuitjs1"
GWT_DEV_MODULE="com.lushprojects.circuitjs1.circuitjs1dev"
WEB_PORT=${WEB_PORT:-8000}
WEB_BINDADDRESS=${WEB_BINDADDRESS:-127.0.0.1}
CODESERVER_BINDADDRESS=${CODESERVER_BINDADDRESS:-127.0.0.1}
CODESERVER_PORT=${CODESERVER_PORT:-9876}
ensure_gwt_sdk() {
if [[ -d "$GWT_DIR" ]]; then
return
fi
echo "GWT SDK not found at $GWT_DIR"
echo "Downloading GWT $GWT_VERSION from $GWT_URL"
mkdir -p "$SDK_DIR"
(
cd "$SDK_DIR"
wget "$GWT_URL" -O "gwt-$GWT_VERSION.zip"
unzip "gwt-$GWT_VERSION.zip"
rm "gwt-$GWT_VERSION.zip"
)
}
compile() {
ant build
}
package() {
compile
(
cd "$SCRIPT_DIR/war"
tar czf "$SCRIPT_DIR/circuitjs1.tar.gz" .
)
}
setup() {
# Install Java if no java compiler is present
if ! which javac > /dev/null 2>&1 || ! which ant > /dev/null 2>&1; then
echo "Installing packages may need your sudo password."
set -x
sudo apt-get update
sudo apt-get install -y openjdk-11-jdk-headless ant
set +x
fi
ensure_gwt_sdk
if [[ -e build.xml ]]; then
mv build.xml build.xml.backup
fi
chmod +x "$GWT_DIR/webAppCreator"
"$GWT_DIR/webAppCreator" -out ../tempProject "$GWT_PROD_MODULE"
cp ../tempProject/build.xml ./
sed -i 's/source="1.7"/source="1.8"/g' build.xml
sed -i 's/target="1.7"/target="1.8"/g' build.xml
rm -rf ../tempProject
}
codeserver() {
ensure_gwt_sdk
if ! [[ -f "$GWT_DIR/gwt-codeserver.jar" && -f "$GWT_DIR/gwt-dev.jar" && -f "$GWT_DIR/gwt-user.jar" ]]; then
echo "Missing required GWT jars in $GWT_DIR"
echo "Expected: gwt-codeserver.jar, gwt-dev.jar, gwt-user.jar"
return 1
fi
mkdir -p war
java -classpath "src:$GWT_DIR/gwt-codeserver.jar:$GWT_DIR/gwt-dev.jar:$GWT_DIR/gwt-user.jar" \
com.google.gwt.dev.codeserver.CodeServer \
-launcherDir war \
-bindAddress ${CODESERVER_BINDADDRESS} \
-port ${CODESERVER_PORT} \
"$GWT_DEV_MODULE"
}
webserver() {
webroot="$SCRIPT_DIR/war"
(
cd $webroot
# Use PHP server if available (supports shortrelay.php), otherwise fall back to Python
if command -v php > /dev/null 2>&1; then
php -S ${WEB_BINDADDRESS}:${WEB_PORT}
else
echo "Warning: PHP not installed. Short URL feature will not work."
python3 -m http.server --bind ${WEB_BINDADDRESS} ${WEB_PORT}
fi
)
}
stop() {
echo "Stopping code server and web server (if running)..."
# Stop GWT CodeServer instances for this module
pkill -f "com.google.gwt.dev.codeserver.CodeServer.*$GWT_DEV_MODULE" 2>/dev/null || true
# Stop web servers started by this script (matching configured bind/port)
pkill -f "php -S ${WEB_BINDADDRESS}:${WEB_PORT}" 2>/dev/null || true
pkill -f "python3 -m http.server --bind ${WEB_BINDADDRESS} ${WEB_PORT}" 2>/dev/null || true
echo "Stop signal sent."
}
restart() {
stop
start
}
start() {
echo "Starting web server http://${WEB_BINDADDRESS}:${WEB_PORT}"
echo "Starting code server http://${CODESERVER_BINDADDRESS}:${CODESERVER_PORT}"
trap "stop" EXIT
webserver >"webserver.log" 2>&1 &
sleep 0.5
codeserver | tee "codeserver.log"
}
startprod() {
echo "Compiling with full optimization (production mode)..."
compile
echo ""
echo "Starting web server http://${WEB_BINDADDRESS}:${WEB_PORT}"
echo "Press Ctrl+C to stop"
webserver
}
test() {
"$SCRIPT_DIR/tools/run-tests-and-open-report.sh"
}
world2() {
local scenario="${1:-1}"
local steps="${2:-1000}"
local dt="${3:-0.2}"
local world2_port="${WORLD2_PORT:-18082}"
if ! curl -fsS --max-time 2 "http://${WEB_BINDADDRESS}:${WEB_PORT}/world2.html" >/dev/null 2>&1; then
echo "Starting web server http://${WEB_BINDADDRESS}:${WEB_PORT}"
webserver >"webserver.log" 2>&1 &
sleep 0.5
fi
echo "Starting World2 UI flow (scenario=${scenario}, steps=${steps}, dt=${dt}, port=${world2_port})"
"$SCRIPT_DIR/tools/run-world2-ui.sh" \
--scenario "${scenario}" \
--steps "${steps}" \
--dt "${dt}" \
--port "${world2_port}" \
--open
}
stopworld2() {
local world2_port="${1:-${WORLD2_PORT:-18082}}"
local pid_file="$SCRIPT_DIR/build/world2-server-${world2_port}.pid"
local stopped="0"
local was_running="0"
if curl -fsS --max-time 2 "http://127.0.0.1:${world2_port}/health" >/dev/null 2>&1; then
was_running="1"
fi
if [[ -f "$pid_file" ]]; then
local pid
pid="$(cat "$pid_file" 2>/dev/null || true)"
if [[ -n "$pid" ]] && kill -0 "$pid" >/dev/null 2>&1; then
echo "Stopping World2 server PID ${pid} (port ${world2_port})"
kill "$pid" >/dev/null 2>&1 || true
sleep 0.5
stopped="1"
fi
rm -f "$pid_file"
fi
pkill -f ":world2-server:run --args=${world2_port}" 2>/dev/null || true
pkill -f "johnnewto.world2.server.World2Server ${world2_port}" 2>/dev/null || true
if curl -fsS --max-time 2 "http://127.0.0.1:${world2_port}/health" >/dev/null 2>&1; then
echo "World2 server still appears to be running on port ${world2_port}."
return 1
fi
if [[ "$stopped" == "1" || "$was_running" == "1" ]]; then
echo "World2 server stopped."
else
echo "No running World2 server found on port ${world2_port}."
fi
}
restartworld2() {
local scenario="${1:-1}"
local steps="${2:-1000}"
local dt="${3:-0.2}"
stopworld2 >/dev/null 2>&1 || true
world2 "$scenario" "$steps" "$dt"
}
runcircuitjava() {
local circuit="${1:-src/com/lushprojects/circuitjs1/public/circuits/economics/1debug.md}"
local steps="${2:-1000}"
local output="${3:-}"
local format="${4:-}"
local html="${5:-}"
# If only circuit is given, derive output names from circuit basename
if [[ -n "${1:-}" && -z "$output" ]]; then
local basename
basename=$(basename "$circuit")
basename="${basename%.*}" # Remove extension
output="/tmp/${basename}.tsv"
format="${format:-tsv}"
html="/tmp/${basename}.html"
else
output="${output:-/tmp/world2.tsv}"
format="${format:-world2}"
html="${html:-/tmp/world2-runner.html}"
fi
echo "Running runCircuitJava with circuit=${circuit}, steps=${steps}, output=${output}, format=${format}, html=${html}"
"$SCRIPT_DIR/gradlew" -q runCircuitJava \
-Pcircuit="$circuit" \
-Psteps="$steps" \
-Poutput="$output" \
-Pformat="$format" \
-Phtml="$html"
# Print generated file paths
if [[ -f "$output" ]]; then
echo "Output: $output"
fi
if [[ -f "$html" ]]; then
echo "HTML: $html"
fi
}
completion() {
if [[ "${1:-}" == "install" ]]; then
local bashrc="${HOME}/.bashrc"
local line="source <(${SCRIPT_DIR}/dev.sh completion)"
touch "$bashrc"
if grep -Fqx "$line" "$bashrc"; then
echo "Bash completion is already installed in ${bashrc}"
echo "Run: source ${bashrc}"
return 0
fi
{
echo ""
echo "# circuitjs1 dev.sh tab completion"
echo "$line"
} >> "$bashrc"
echo "Installed bash completion in ${bashrc}"
echo "Run: source ${bashrc}"
return 0
fi
cat <<'EOF'
_circuitjs1_dev_completion() {
local cur prev commands
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
commands="help setup compile package start stop restart startprod codeserver webserver test world2 stopworld2 restartworld2 runcircuitjava completion install_completion"
if [[ $COMP_CWORD -eq 1 ]]; then
COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
return 0
fi
if [[ "${COMP_WORDS[1]}" == "completion" && $COMP_CWORD -eq 2 ]]; then
COMPREPLY=( $(compgen -W "install" -- "$cur") )
return 0
fi
case "${COMP_WORDS[1]}" in
runcircuitjava)
case "$prev" in
runcircuitjava)
COMPREPLY=( $(compgen -f -- "$cur") )
;;
world2|csv)
COMPREPLY=( $(compgen -f -- "$cur") )
;;
*)
COMPREPLY=()
;;
esac
;;
stopworld2)
COMPREPLY=()
;;
world2|restartworld2)
COMPREPLY=()
;;
*)
COMPREPLY=()
;;
esac
}
complete -F _circuitjs1_dev_completion ./dev.sh
complete -F _circuitjs1_dev_completion dev.sh
complete -F _circuitjs1_dev_completion dev
EOF
}
install_completion() {
completion install
}
print_commands() {
cat <<'EOF'
Available commands:
help Show this help
setup Install prerequisites and generate build.xml
compile Build with Ant
package Build and create circuitjs1.tar.gz
start Start dev webserver + GWT codeserver
stop Stop dev webserver + GWT codeserver
restart Restart dev webserver + GWT codeserver
webserver Start only dev webserver
codeserver Start only GWT codeserver
startprod Compile optimized build and start webserver
test Run tests and open report
world2 Run World2 UI flow (scenario [steps [dt]])
stopworld2 Stop World2 server (port)
restartworld2 Restart World2 flow (scenario [steps [dt]])
runcircuitjava Run JVM circuit runner locally
completion Print bash completion script
install_completion Alias for 'completion install', install bash completions for dev.sh
runcircuitjava defaults:
circuit=src/com/lushprojects/circuitjs1/public/circuits/economics/1debug.md
steps=1000
output=/tmp/world2.tsv
format=world2
html=/tmp/world2-runner.html
runcircuitjava examples:
./dev.sh runcircuitjava
./dev.sh runcircuitjava <circuit> [steps] [output] [format] [html]
./dev.sh runcircuitjava src/com/lushprojects/circuitjs1/public/circuits/economics/1debug.md 1000 /tmp/world2.tsv world2 /tmp/world2-runner.html
./dev.sh runcircuitjava src/com/lushprojects/circuitjs1/public/circuits/economics/econ_BOMD.txt 10 /tmp/bomd.tsv tsv /tmp/bomd.html
EOF
}
help() {
print_commands
}
if [[ $# -eq 0 ]]; then
help
exit 0
fi
for func in $(compgen -A function); do
if [[ $func == "$1" ]]; then
shift
$func "$@"
exit $?
fi
done
echo "Unknown command '$1'"
echo
help
exit 1