2026-03-31 07:59:21 -07:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
# Dev commands: play, editor, lint, format, test, verify, screenshot
|
|
|
|
|
|
|
|
|
|
cmd_play() {
|
|
|
|
|
echo -e "${BLUE}Launching Magic Civilization...${NC}"
|
|
|
|
|
WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-0}" \
|
|
|
|
|
XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" \
|
|
|
|
|
$GODOT_BIN --path "$GAME_DIR" --rendering-method gl_compatibility "$@"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cmd_editor() {
|
|
|
|
|
echo -e "${BLUE}Opening Godot editor...${NC}"
|
|
|
|
|
WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-0}" \
|
|
|
|
|
XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" \
|
|
|
|
|
$GODOT_BIN --path "$GAME_DIR" -e --rendering-method gl_compatibility "$@" &
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cmd_lint() {
|
2026-03-31 22:47:32 -07:00
|
|
|
local exit_code=0
|
|
|
|
|
|
|
|
|
|
echo -e "${BLUE}[1/3] GDScript lint...${NC}"
|
2026-03-31 07:59:21 -07:00
|
|
|
lilith-gdtoolkit-sync --check || {
|
|
|
|
|
echo -e "${YELLOW}Config drift detected — syncing...${NC}"
|
|
|
|
|
lilith-gdtoolkit-sync
|
|
|
|
|
}
|
2026-03-31 22:47:32 -07:00
|
|
|
gdlint "$GAME_DIR/engine/src/" || exit_code=$?
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
echo -e "${BLUE}[2/3] Rust lint (fmt + clippy)...${NC}"
|
|
|
|
|
(cd "$SIMULATOR_DIR" && cargo fmt --check --all) || exit_code=$?
|
|
|
|
|
(cd "$SIMULATOR_DIR" && cargo clippy --workspace --all-targets -- -D warnings) || exit_code=$?
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
echo -e "${BLUE}[3/3] Guide lint (ESLint)...${NC}"
|
|
|
|
|
pnpm --prefix "$GUIDE_DIR" lint || exit_code=$?
|
|
|
|
|
|
|
|
|
|
return $exit_code
|
2026-03-31 07:59:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cmd_format() {
|
2026-03-31 22:47:32 -07:00
|
|
|
echo -e "${BLUE}[1/3] GDScript format...${NC}"
|
2026-03-31 07:59:21 -07:00
|
|
|
lilith-gdtoolkit-sync --check || {
|
|
|
|
|
echo -e "${YELLOW}Config drift detected — syncing...${NC}"
|
|
|
|
|
lilith-gdtoolkit-sync
|
|
|
|
|
}
|
2026-03-31 22:47:32 -07:00
|
|
|
gdformat "$GAME_DIR/engine/src/"
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
echo -e "${BLUE}[2/3] Rust format...${NC}"
|
|
|
|
|
(cd "$SIMULATOR_DIR" && cargo fmt --all)
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
echo -e "${BLUE}[3/3] Guide format (ESLint --fix)...${NC}"
|
|
|
|
|
pnpm --prefix "$GUIDE_DIR" lint:fix
|
2026-03-31 07:59:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cmd_test() {
|
|
|
|
|
local exit_code=0
|
|
|
|
|
|
|
|
|
|
echo -e "${BLUE}Running GUT tests (GDScript)...${NC}"
|
|
|
|
|
WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-0}" \
|
|
|
|
|
XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" \
|
|
|
|
|
$GODOT_BIN --path "$GAME_DIR" --headless --script res://addons/gut/gut_cmdln.gd \
|
|
|
|
|
-gexit "$@" || exit_code=$?
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
echo -e "${BLUE}Running Rust tests (simulator)...${NC}"
|
|
|
|
|
(cd "$SIMULATOR_DIR" && cargo test --workspace) || exit_code=$?
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
echo -e "${BLUE}Running vitest (guide)...${NC}"
|
|
|
|
|
pnpm --prefix "$GUIDE_DIR" test || exit_code=$?
|
|
|
|
|
|
|
|
|
|
return $exit_code
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cmd_verify() {
|
2026-04-08 15:25:07 -07:00
|
|
|
local -a step_names step_times step_results
|
|
|
|
|
local overall_exit=0
|
|
|
|
|
|
|
|
|
|
_verify_step() {
|
|
|
|
|
local step_num="$1"
|
|
|
|
|
local total="$2"
|
|
|
|
|
local label="$3"
|
|
|
|
|
shift 3
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
echo -e "${BLUE}[${step_num}/${total}] ${label}${NC}"
|
|
|
|
|
|
|
|
|
|
local t_start
|
|
|
|
|
t_start=$(date +%s%N)
|
|
|
|
|
|
|
|
|
|
if ! "$@"; then
|
|
|
|
|
local t_end elapsed
|
|
|
|
|
t_end=$(date +%s%N)
|
|
|
|
|
elapsed=$(( (t_end - t_start) / 1000000 ))
|
|
|
|
|
step_names+=("$label")
|
|
|
|
|
step_times+=("${elapsed}ms")
|
|
|
|
|
step_results+=("FAIL")
|
|
|
|
|
echo ""
|
|
|
|
|
echo -e "${RED}ABORT: '${label}' failed after ${elapsed}ms${NC}"
|
|
|
|
|
_verify_summary
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
local t_end elapsed
|
|
|
|
|
t_end=$(date +%s%N)
|
|
|
|
|
elapsed=$(( (t_end - t_start) / 1000000 ))
|
|
|
|
|
step_names+=("$label")
|
|
|
|
|
step_times+=("${elapsed}ms")
|
|
|
|
|
step_results+=("PASS")
|
|
|
|
|
}
|
2026-03-31 07:59:21 -07:00
|
|
|
|
2026-04-08 15:25:07 -07:00
|
|
|
_verify_run_in_dir() {
|
|
|
|
|
local dir="$1"; shift
|
|
|
|
|
(cd "$dir" && "$@")
|
|
|
|
|
}
|
2026-03-31 07:59:21 -07:00
|
|
|
|
2026-04-08 15:25:07 -07:00
|
|
|
_verify_summary() {
|
|
|
|
|
echo ""
|
|
|
|
|
echo -e "${BLUE}─────────────────────────────────────────────────${NC}"
|
|
|
|
|
echo -e "${BLUE} Regression Gate Summary${NC}"
|
|
|
|
|
echo -e "${BLUE}─────────────────────────────────────────────────${NC}"
|
|
|
|
|
local i
|
|
|
|
|
for i in "${!step_names[@]}"; do
|
|
|
|
|
local result="${step_results[$i]}"
|
|
|
|
|
local color
|
|
|
|
|
if [ "$result" = "PASS" ]; then
|
|
|
|
|
color="$GREEN"
|
|
|
|
|
else
|
|
|
|
|
color="$RED"
|
|
|
|
|
fi
|
|
|
|
|
printf " %-40s %s%-4s%s %s\n" \
|
|
|
|
|
"${step_names[$i]}" \
|
|
|
|
|
"$color" "$result" "$NC" \
|
|
|
|
|
"${step_times[$i]}"
|
|
|
|
|
done
|
|
|
|
|
echo -e "${BLUE}─────────────────────────────────────────────────${NC}"
|
|
|
|
|
# Count pending steps not yet run
|
|
|
|
|
local n_pass=0 n_fail=0
|
|
|
|
|
for r in "${step_results[@]}"; do
|
2026-04-08 15:39:55 -07:00
|
|
|
if [ "$r" = "PASS" ]; then
|
|
|
|
|
n_pass=$(( n_pass + 1 ))
|
|
|
|
|
else
|
|
|
|
|
n_fail=$(( n_fail + 1 ))
|
|
|
|
|
fi
|
2026-04-08 15:25:07 -07:00
|
|
|
done
|
|
|
|
|
if [ "$n_fail" -eq 0 ]; then
|
|
|
|
|
echo -e " ${GREEN}All ${n_pass} checks passed${NC}"
|
|
|
|
|
else
|
|
|
|
|
echo -e " ${RED}${n_fail} check(s) failed, ${n_pass} passed${NC}"
|
|
|
|
|
fi
|
|
|
|
|
echo -e "${BLUE}─────────────────────────────────────────────────${NC}"
|
|
|
|
|
}
|
2026-03-31 07:59:21 -07:00
|
|
|
|
2026-04-08 15:25:07 -07:00
|
|
|
# Step 1 — Rust build
|
|
|
|
|
_verify_step 1 6 "cargo build --workspace" \
|
|
|
|
|
_verify_run_in_dir "$SIMULATOR_DIR" cargo build --workspace
|
2026-03-31 22:47:32 -07:00
|
|
|
|
2026-04-08 15:25:07 -07:00
|
|
|
# Step 2 — Rust tests
|
|
|
|
|
_verify_step 2 6 "cargo test --workspace" \
|
|
|
|
|
_verify_run_in_dir "$SIMULATOR_DIR" cargo test --workspace
|
2026-03-31 22:47:32 -07:00
|
|
|
|
2026-04-08 15:25:07 -07:00
|
|
|
# Step 3 — Rust clippy
|
|
|
|
|
_verify_step 3 6 "cargo clippy --workspace -D warnings" \
|
|
|
|
|
_verify_run_in_dir "$SIMULATOR_DIR" cargo clippy --workspace -- -D warnings
|
2026-03-31 22:47:32 -07:00
|
|
|
|
2026-04-08 15:25:07 -07:00
|
|
|
# Step 4 — GDScript lint: engine/src/
|
|
|
|
|
_verify_step 4 6 "gdlint engine/src/" \
|
|
|
|
|
gdlint "$GAME_DIR/engine/src/"
|
2026-03-31 07:59:21 -07:00
|
|
|
|
2026-04-08 15:25:07 -07:00
|
|
|
# Step 5 — GDScript lint: scenes/tests/
|
|
|
|
|
_verify_step 5 6 "gdlint engine/scenes/tests/" \
|
|
|
|
|
gdlint "$GAME_DIR/engine/scenes/tests/"
|
2026-03-31 07:59:21 -07:00
|
|
|
|
2026-04-08 15:25:07 -07:00
|
|
|
# Step 6 — GDScript lint: tests/integration/
|
|
|
|
|
_verify_step 6 6 "gdlint engine/tests/integration/" \
|
|
|
|
|
gdlint "$GAME_DIR/engine/tests/integration/"
|
|
|
|
|
|
|
|
|
|
_verify_summary
|
|
|
|
|
return $overall_exit
|
2026-03-31 07:59:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cmd_screenshot() {
|
|
|
|
|
"$REPO_ROOT/tools/screenshot.sh" "$@"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cmd_guide() {
|
|
|
|
|
echo -e "${BLUE}Starting guide dev server (port 5800)...${NC}"
|
|
|
|
|
pnpm --prefix "$GUIDE_DIR" dev
|
|
|
|
|
}
|