Skip to content

Commit 23c9702

Browse files
committed
add unified cross-platform dev script
1 parent 802f4eb commit 23c9702

1 file changed

Lines changed: 378 additions & 0 deletions

File tree

scripts/dev-unified.sh

Lines changed: 378 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,378 @@
1+
#!/bin/bash
2+
# Unified cross-platform development script
3+
# Works on Unix/Linux/macOS and Windows (via Git Bash/WSL/MSYS2)
4+
5+
set -e
6+
7+
# Get script directory and project root
8+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
9+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
10+
11+
# Enhanced OS detection
12+
detect_os() {
13+
local os="unknown"
14+
local is_wsl=false
15+
local shell_env="unknown"
16+
17+
# Detect operating system
18+
case "$(uname -s)" in
19+
Linux*)
20+
if [[ -n "${WSL_DISTRO_NAME:-}" ]] || [[ "$(uname -r)" == *microsoft* ]]; then
21+
os="wsl"
22+
is_wsl=true
23+
else
24+
os="linux"
25+
fi
26+
;;
27+
Darwin*) os="macos";;
28+
CYGWIN*) os="windows-cygwin";;
29+
MINGW*) os="windows-mingw";;
30+
MSYS*) os="windows-msys";;
31+
*) os="unknown";;
32+
esac
33+
34+
# Detect shell environment
35+
if [[ -n "${BASH_VERSION:-}" ]]; then
36+
shell_env="bash"
37+
elif [[ -n "${ZSH_VERSION:-}" ]]; then
38+
shell_env="zsh"
39+
else
40+
shell_env="sh"
41+
fi
42+
43+
echo "$os|$is_wsl|$shell_env"
44+
}
45+
46+
# Parse OS detection
47+
OS_INFO=$(detect_os)
48+
OS=$(echo "$OS_INFO" | cut -d'|' -f1)
49+
IS_WSL=$(echo "$OS_INFO" | cut -d'|' -f2)
50+
SHELL_ENV=$(echo "$OS_INFO" | cut -d'|' -f3)
51+
52+
# Determine if we're on Windows-like environment
53+
case "$OS" in
54+
windows-*|wsl) IS_WINDOWS_LIKE=true;;
55+
*) IS_WINDOWS_LIKE=false;;
56+
esac
57+
58+
# Colors for output (with Windows compatibility)
59+
if [[ "$IS_WINDOWS_LIKE" == "true" ]] && [[ "$OS" != "wsl" ]]; then
60+
# Limited color support on Windows
61+
RED=""
62+
GREEN=""
63+
YELLOW=""
64+
NC=""
65+
else
66+
RED='\033[0;31m'
67+
GREEN='\033[0;32m'
68+
YELLOW='\033[1;33m'
69+
NC='\033[0m'
70+
fi
71+
72+
print_header() {
73+
echo -e "${GREEN}🚄 Hyperloop H10 Development Environment${NC}"
74+
echo -e "${GREEN}=======================================${NC}"
75+
echo -e "${YELLOW}OS: $OS${NC}"
76+
echo -e "${YELLOW}Shell: $SHELL_ENV${NC}"
77+
echo -e "${YELLOW}WSL: $IS_WSL${NC}"
78+
echo ""
79+
}
80+
81+
print_usage() {
82+
echo "Usage: $0 [command]"
83+
echo ""
84+
echo "Commands:"
85+
echo " setup - Install all dependencies"
86+
echo " backend - Run backend server"
87+
echo " ethernet - Run ethernet-view dev server"
88+
echo " control - Run control-station dev server"
89+
echo " packet - Run packet-sender"
90+
echo " all - Run all services"
91+
echo " test - Run all tests"
92+
echo " build - Build all components"
93+
echo ""
94+
echo "Platform Notes:"
95+
if [[ "$IS_WINDOWS_LIKE" == "true" ]]; then
96+
echo " - Windows detected: Services will run in parallel processes"
97+
echo " - Use Ctrl+C to stop all services when running 'all' command"
98+
else
99+
echo " - Unix-like system: 'all' command uses tmux if available"
100+
echo " - Install tmux for better multi-service management"
101+
fi
102+
echo ""
103+
}
104+
105+
check_dependencies() {
106+
local missing=()
107+
108+
command -v go >/dev/null 2>&1 || missing+=("go")
109+
command -v node >/dev/null 2>&1 || missing+=("node")
110+
command -v npm >/dev/null 2>&1 || missing+=("npm")
111+
112+
if [ ${#missing[@]} -ne 0 ]; then
113+
echo -e "${RED}Error: Missing required dependencies: ${missing[*]}${NC}"
114+
echo "Please install them before continuing."
115+
echo ""
116+
echo "Installation guides:"
117+
echo " Go: https://golang.org/doc/install"
118+
echo " Node.js: https://nodejs.org/"
119+
exit 1
120+
fi
121+
122+
echo -e "${GREEN}✅ All dependencies found${NC}"
123+
}
124+
125+
# Convert Windows paths if needed
126+
normalize_path() {
127+
local path="$1"
128+
if [[ "$IS_WINDOWS_LIKE" == "true" ]] && [[ "$OS" != "wsl" ]]; then
129+
echo "$path" | sed 's|/|\\|g'
130+
else
131+
echo "$path"
132+
fi
133+
}
134+
135+
# Cross-platform directory change
136+
safe_cd() {
137+
local target_dir="$1"
138+
local normalized_dir
139+
normalized_dir=$(normalize_path "$target_dir")
140+
141+
if ! cd "$normalized_dir" 2>/dev/null; then
142+
echo -e "${RED}Error: Cannot change to directory: $normalized_dir${NC}"
143+
exit 1
144+
fi
145+
}
146+
147+
setup_project() {
148+
echo -e "${YELLOW}Setting up project dependencies...${NC}"
149+
150+
safe_cd "$PROJECT_ROOT"
151+
152+
# Build common-front first
153+
echo "📦 Building common-front..."
154+
safe_cd "$PROJECT_ROOT/common-front"
155+
npm install
156+
npm run build
157+
158+
# Install ethernet-view dependencies
159+
echo "📦 Installing ethernet-view dependencies..."
160+
safe_cd "$PROJECT_ROOT/ethernet-view"
161+
npm install
162+
163+
# Install control-station dependencies
164+
echo "📦 Installing control-station dependencies..."
165+
safe_cd "$PROJECT_ROOT/control-station"
166+
npm install
167+
168+
# Download Go dependencies
169+
echo "📦 Downloading Go dependencies..."
170+
safe_cd "$PROJECT_ROOT/backend"
171+
go mod download
172+
173+
safe_cd "$PROJECT_ROOT/packet-sender"
174+
go mod download
175+
176+
echo -e "${GREEN}✅ Setup complete!${NC}"
177+
}
178+
179+
run_backend() {
180+
safe_cd "$PROJECT_ROOT/backend/cmd"
181+
echo -e "${YELLOW}Starting backend server...${NC}"
182+
go run .
183+
}
184+
185+
run_ethernet_view() {
186+
safe_cd "$PROJECT_ROOT/ethernet-view"
187+
echo -e "${YELLOW}Starting ethernet-view dev server...${NC}"
188+
npm run dev
189+
}
190+
191+
run_control_station() {
192+
safe_cd "$PROJECT_ROOT/control-station"
193+
echo -e "${YELLOW}Starting control-station dev server...${NC}"
194+
npm run dev
195+
}
196+
197+
run_packet_sender() {
198+
safe_cd "$PROJECT_ROOT/packet-sender"
199+
echo -e "${YELLOW}Starting packet-sender...${NC}"
200+
go run .
201+
}
202+
203+
run_all_services() {
204+
if [[ "$IS_WINDOWS_LIKE" == "true" ]] && [[ "$OS" != "wsl" ]]; then
205+
echo -e "${YELLOW}Running all services in parallel (Windows mode)...${NC}"
206+
echo -e "${YELLOW}Use Ctrl+C to stop all services${NC}"
207+
echo ""
208+
209+
# Start all services in background
210+
(safe_cd "$PROJECT_ROOT/backend/cmd" && go run .) &
211+
PID_BACKEND=$!
212+
213+
(safe_cd "$PROJECT_ROOT/ethernet-view" && npm run dev) &
214+
PID_ETHERNET=$!
215+
216+
(safe_cd "$PROJECT_ROOT/control-station" && npm run dev) &
217+
PID_CONTROL=$!
218+
219+
(safe_cd "$PROJECT_ROOT/packet-sender" && go run .) &
220+
PID_PACKET=$!
221+
222+
echo -e "${GREEN}All services started. PIDs: Backend=$PID_BACKEND, Ethernet=$PID_ETHERNET, Control=$PID_CONTROL, Packet=$PID_PACKET${NC}"
223+
224+
# Function to cleanup on exit
225+
cleanup() {
226+
echo -e "${YELLOW}Stopping all services...${NC}"
227+
kill $PID_BACKEND $PID_ETHERNET $PID_CONTROL $PID_PACKET 2>/dev/null || true
228+
exit
229+
}
230+
231+
# Set trap for cleanup
232+
trap cleanup SIGINT SIGTERM
233+
234+
# Wait for any process to exit
235+
wait
236+
237+
else
238+
# Unix-like system - prefer tmux if available
239+
if command -v tmux >/dev/null 2>&1; then
240+
run_all_tmux
241+
else
242+
echo -e "${YELLOW}tmux not found. Running services in parallel...${NC}"
243+
echo -e "${YELLOW}Use Ctrl+C to stop all services${NC}"
244+
echo ""
245+
246+
# Fallback to background processes
247+
(safe_cd "$PROJECT_ROOT/backend/cmd" && go run .) &
248+
PID_BACKEND=$!
249+
250+
(safe_cd "$PROJECT_ROOT/ethernet-view" && npm run dev) &
251+
PID_ETHERNET=$!
252+
253+
(safe_cd "$PROJECT_ROOT/control-station" && npm run dev) &
254+
PID_CONTROL=$!
255+
256+
(safe_cd "$PROJECT_ROOT/packet-sender" && go run .) &
257+
PID_PACKET=$!
258+
259+
echo -e "${GREEN}All services started. PIDs: Backend=$PID_BACKEND, Ethernet=$PID_ETHERNET, Control=$PID_CONTROL, Packet=$PID_PACKET${NC}"
260+
echo -e "${YELLOW}Tip: Install tmux for better session management${NC}"
261+
262+
# Function to cleanup on exit
263+
cleanup() {
264+
echo -e "${YELLOW}Stopping all services...${NC}"
265+
kill $PID_BACKEND $PID_ETHERNET $PID_CONTROL $PID_PACKET 2>/dev/null || true
266+
exit
267+
}
268+
269+
# Set trap for cleanup
270+
trap cleanup SIGINT SIGTERM
271+
272+
# Wait for any process to exit
273+
wait
274+
fi
275+
fi
276+
}
277+
278+
run_all_tmux() {
279+
SESSION="hyperloop-dev"
280+
281+
# Kill existing session if it exists
282+
tmux kill-session -t $SESSION 2>/dev/null || true
283+
284+
# Create new session with backend
285+
tmux new-session -d -s $SESSION -n backend "cd '$PROJECT_ROOT/backend/cmd' && go run ."
286+
287+
# Create windows for other services
288+
tmux new-window -t $SESSION -n ethernet-view "cd '$PROJECT_ROOT/ethernet-view' && npm run dev"
289+
tmux new-window -t $SESSION -n control-station "cd '$PROJECT_ROOT/control-station' && npm run dev"
290+
tmux new-window -t $SESSION -n packet-sender "cd '$PROJECT_ROOT/packet-sender' && go run ."
291+
292+
# Attach to session
293+
echo -e "${GREEN}Starting all services in tmux session '$SESSION'${NC}"
294+
echo -e "${YELLOW}Use 'tmux attach -t $SESSION' to reconnect${NC}"
295+
tmux attach-session -t $SESSION
296+
}
297+
298+
run_tests() {
299+
echo -e "${YELLOW}Running tests...${NC}"
300+
301+
safe_cd "$PROJECT_ROOT/backend"
302+
echo "🧪 Running backend tests..."
303+
go test -v ./...
304+
305+
echo -e "${GREEN}✅ All tests completed${NC}"
306+
}
307+
308+
build_all() {
309+
safe_cd "$PROJECT_ROOT"
310+
echo -e "${YELLOW}Building all components...${NC}"
311+
312+
# Check if make is available
313+
if command -v make >/dev/null 2>&1; then
314+
make all
315+
else
316+
echo -e "${YELLOW}Make not found, building components individually...${NC}"
317+
318+
# Build backend
319+
echo "Building backend..."
320+
safe_cd "$PROJECT_ROOT/backend"
321+
go build -o backend cmd/main.go cmd/config.go cmd/pid.go cmd/trace.go
322+
323+
# Build common-front
324+
echo "Building common-front..."
325+
safe_cd "$PROJECT_ROOT/common-front"
326+
npm run build
327+
328+
# Build other frontends
329+
echo "Building ethernet-view..."
330+
safe_cd "$PROJECT_ROOT/ethernet-view"
331+
npm run build
332+
333+
echo "Building control-station..."
334+
safe_cd "$PROJECT_ROOT/control-station"
335+
npm run build
336+
fi
337+
338+
echo -e "${GREEN}✅ Build complete!${NC}"
339+
}
340+
341+
# Main script logic
342+
print_header
343+
check_dependencies
344+
345+
case "${1:-}" in
346+
setup)
347+
setup_project
348+
;;
349+
backend)
350+
run_backend
351+
;;
352+
ethernet)
353+
run_ethernet_view
354+
;;
355+
control)
356+
run_control_station
357+
;;
358+
packet)
359+
run_packet_sender
360+
;;
361+
all)
362+
run_all_services
363+
;;
364+
test)
365+
run_tests
366+
;;
367+
build)
368+
build_all
369+
;;
370+
"")
371+
print_usage
372+
;;
373+
*)
374+
echo -e "${RED}Unknown command: $1${NC}"
375+
print_usage
376+
exit 1
377+
;;
378+
esac

0 commit comments

Comments
 (0)