This repository was archived by the owner on Nov 5, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdev.sh
More file actions
executable file
·144 lines (124 loc) · 6.02 KB
/
dev.sh
File metadata and controls
executable file
·144 lines (124 loc) · 6.02 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
#!/usr/bin/env bash
# Multi-service launcher: FastAPI + pnpm + Capacitor (optional USB Android)
# Works with direnv/nix and Kitty terminal
set -euo pipefail
# ──────────────────────────────────────────────
# Helpers
# ──────────────────────────────────────────────
log() { echo -e "\033[1;34m[dev]\033[0m $*"; }
warn() { echo -e "\033[1;33m[warn]\033[0m $*"; }
err() { echo -e "\033[1;31m[err]\033[0m $*" >&2; }
pause_on_exit() { echo "[$1 exited — press ENTER to close]"; read; }
launch_chromium() {
echo 'Waiting for mobile:hot-reload (port 8082)...'
elapsed=0
while ! nc -z localhost 8082 2>/dev/null; do
sleep 2
elapsed=$((elapsed+2))
if [ \$elapsed -ge 40 ]; then
echo 'mobile:hot-reload not ready after \$elapsed seconds.'
exit 1
fi
done
echo 'mobile:hot-reload ready — launching Chromium.'
chromium-browser http://localhost:8082/
}
export -f launch_chromium
# ──────────────────────────────────────────────
# Kitty tab helper — keep tab open on crash
# ──────────────────────────────────────────────
tabrun() {
local title=$1 cmd=$2
local pause_on_exit='echo "['"$title"' exited — press ENTER to close]"; read'
echo -e "new_tab ${title}\nlaunch zsh -ic '${cmd}; $pause_on_exit'"
}
# ──────────────────────────────────────────────
# 1. Load direnv/nix environment
# ──────────────────────────────────────────────
if ! command -v direnv &>/dev/null; then
err "direnv not found. Please install or activate manually."
exit 1
fi
if [[ -z "${DIRENV_DIR:-}" ]]; then
warn "direnv not loaded — attempting to load..."
eval "$(direnv export bash)" || { err "Run 'direnv allow' first."; exit 1; }
else
log "direnv environment detected."
fi
# ──────────────────────────────────────────────
# 2. Check required tools
# ──────────────────────────────────────────────
for cmd in fastapi pnpm npx; do
if ! command -v "$cmd" &>/dev/null; then
err "Missing $cmd — verify your flake setup."
exit 1
fi
done
# ──────────────────────────────────────────────
# 3. Dependency setup (first-time only)
# ──────────────────────────────────────────────
if [[ ! -d front/node_modules ]]; then
log "Installing frontend deps with pnpm..."
pnpm --dir front install
fi
# ──────────────────────────────────────────────
# 4. Check for connected Android device
# ──────────────────────────────────────────────
HAS_DEVICE=false
if command -v adb &>/dev/null; then
if adb get-state 2>/dev/null | grep -q "device"; then
HAS_DEVICE=true
log "Android device detected via USB."
else
warn "No Android device detected — skipping mobile build and hot reload."
fi
else
warn "adb not found — skipping Android tasks."
fi
# ──────────────────────────────────────────────
# 5. If device connected → build & install APK
# ──────────────────────────────────────────────
if [[ "$HAS_DEVICE" == true ]]; then
APK="front/android/app/build/outputs/apk/debug/app-debug.apk"
log "Syncing Capacitor Android project..."
(cd front && npx cap sync android)
if [[ ! -f $APK || $(find front/src -newer "$APK" | wc -l) -gt 0 ]]; then
log "Building fresh debug APK..."
(cd front/android && ./gradlew assembleDebug)
else
log "APK is up-to-date."
fi
log "Installing APK on device..."
(cd front && adb install -r "$APK" >/dev/null || warn "Install may have failed if app already running.")
fi
# ──────────────────────────────────────────────
# 6. Free ports (8080, 8081, 8082)
# ──────────────────────────────────────────────
log "Checking and freeing ports 8080, 8081, 8082..."
for port in 8080 8081 8082; do
pids=$(lsof -ti :"$port" || true)
if [[ -n "$pids" ]]; then
warn "Port $port is in use by PID(s): $pids — killing..."
kill -9 $pids 2>/dev/null || warn "Failed to kill process on port $port"
log "Freed port $port."
else
log "Port $port is free."
fi
done
# ──────────────────────────────────────────────
# 7. Launch Kitty multi-tab session
# ──────────────────────────────────────────────
log "Launching Kitty tabs..."
SESSION=$(cat <<EOF
$(tabrun "backend" "cd back && fastapi dev --port 8080")
$(tabrun "frontend:web" "pnpm --dir front dev:web")
EOF
)
if [[ "$HAS_DEVICE" == true ]]; then
SESSION+="
$(tabrun "frontend:mobile" "pnpm --dir front dev:mobile")
$(tabrun "mobile:hot-reload" "cd front && npx cap run android -l --port 8082")
"
fi
kitty --session <(echo -e "$SESSION") & disown
log "Tabs launched — backend & web ready${HAS_DEVICE:+ (mobile included)}!"