-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwatch.sh
More file actions
executable file
Β·203 lines (172 loc) Β· 5.8 KB
/
Copy pathwatch.sh
File metadata and controls
executable file
Β·203 lines (172 loc) Β· 5.8 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
#!/bin/bash
set -e
# Configuration
LOG_FILE="/tmp/databricks-app-watch.log"
PID_FILE="/tmp/databricks-app-watch.pid"
# Parse command line arguments
PROD_MODE=false
if [[ "$1" == "--prod" ]]; then
PROD_MODE=true
echo "π Production mode enabled"
fi
# Kill any existing processes from previous watch.sh runs
echo "π§Ή Cleaning up any existing watch.sh processes..."
if [ -f "$PID_FILE" ]; then
OLD_PID=$(cat "$PID_FILE")
if ps -p $OLD_PID > /dev/null 2>&1; then
echo "Found old watch.sh process (PID: $OLD_PID), killing it..."
kill $OLD_PID 2>/dev/null || true
pkill -P $OLD_PID 2>/dev/null || true
sleep 2
fi
fi
# Create a new process group so killing this script kills all children
set -m
# Store this script's PID for cleanup
echo $$ > "$PID_FILE"
# Redirect all output to log file while still showing on terminal
exec > >(tee "$LOG_FILE") 2>&1
echo "Starting Databricks App development servers..."
echo "=============================================="
echo "Log file: $LOG_FILE"
echo "PID file: $PID_FILE"
# source .env and .env.local if they exist
if [ -f ".env" ]; then
echo "Loading .env"
export $(grep -v '^#' .env | xargs)
fi
if [ -f ".env.local" ]; then
echo "Loading .env.local"
export $(grep -v '^#' .env.local | xargs)
# Explicitly export Databricks variables for CLI
export DATABRICKS_HOST
export DATABRICKS_TOKEN
fi
# Check if already authenticated to avoid opening browser every time
check_auth() {
if [ ! -z "$DATABRICKS_CONFIG_PROFILE" ]; then
databricks auth describe --profile $DATABRICKS_CONFIG_PROFILE > /dev/null 2>&1
elif [ ! -z "$DATABRICKS_HOST" ]; then
databricks auth describe --host $DATABRICKS_HOST > /dev/null 2>&1
else
databricks auth describe > /dev/null 2>&1
fi
}
if command -v databricks >/dev/null 2>&1; then
if ! check_auth; then
echo "π Not authenticated, logging in..."
if [ ! -z "$DATABRICKS_CONFIG_PROFILE" ]; then
databricks auth login --profile $DATABRICKS_CONFIG_PROFILE
elif [ ! -z "$DATABRICKS_HOST" ]; then
databricks auth login --host $DATABRICKS_HOST
else
databricks auth login
fi
else
echo "β
Already authenticated"
fi
else
echo "β οΈ Databricks CLI not found, skipping authentication"
fi
# Generate TypeScript client
echo "π§ Generating TypeScript client..."
uv run python -m scripts.make_fastapi_client || echo "β οΈ Could not generate client (server may not be running yet)"
if [ "$PROD_MODE" = true ]; then
echo "Building frontend for production..."
pushd client && npm run build && popd
echo "β
Frontend built successfully"
# In production mode, only start backend (frontend served by FastAPI)
uv run uvicorn server.app:app --reload --reload-dir server --host 0.0.0.0 --port 8000 &
BACKEND_PID=$!
echo "Backend PID: $BACKEND_PID"
echo "Production mode: Frontend will be served by FastAPI at http://localhost:8000"
else
# Development mode: start both frontend and backend
echo "π Starting frontend development server..."
(cd client && BROWSER=none npm run dev) &
FRONTEND_PID=$!
echo "Frontend PID: $FRONTEND_PID"
echo "π₯οΈ Starting backend development server..."
uv run uvicorn server.app:app --reload --reload-dir server --host 0.0.0.0 --port 8000 &
BACKEND_PID=$!
echo "Backend PID: $BACKEND_PID"
fi
# Auto-regenerate client when server code changes
echo "π Setting up auto-client generation..."
uv run watchmedo auto-restart \
--patterns="*.py" \
--debounce-interval=1 \
--no-restart-on-command-exit \
--recursive \
--directory=server \
uv -- run python -m scripts.make_fastapi_client &
WATCHER_PID=$!
echo "Watcher PID: $WATCHER_PID"
# Give everything time to start
sleep 3
echo ""
echo "β
Development servers started!"
echo ""
echo "π Process Information:"
echo " Watch script PID: $$"
if [ "$PROD_MODE" = true ]; then
echo " Backend PID: $BACKEND_PID"
echo " Watcher PID: $WATCHER_PID"
echo ""
echo "App: http://localhost:8000"
else
echo " Frontend PID: $FRONTEND_PID"
echo " Backend PID: $BACKEND_PID"
echo " Watcher PID: $WATCHER_PID"
echo ""
# Detect the actual frontend port (default 5173, or next available)
FRONTEND_PORT=$(netstat -an | grep LISTEN | grep ':517[3-9]' | head -1 | sed 's/.*:\([0-9]*\).*/\1/' || echo "5173")
echo "Frontend: http://localhost:$FRONTEND_PORT"
echo "Backend: http://localhost:8000"
fi
echo "API Docs: http://localhost:8000/docs"
echo ""
echo "π Logs: tail -f $LOG_FILE"
echo "π Stop: kill \$(cat $PID_FILE) or pkill -f watch.sh"
echo ""
echo "Press Ctrl+C to stop all servers"
# Function to kill a process tree recursively
kill_tree() {
local pid=$1
local children=$(ps -o pid --no-headers --ppid $pid 2>/dev/null || true)
for child in $children; do
kill_tree $child
done
if ps -p $pid > /dev/null 2>&1; then
kill $pid 2>/dev/null || true
fi
}
# Function to cleanup processes
cleanup() {
echo ""
echo "π Stopping servers..."
# Kill each process tree we started
for pid in $FRONTEND_PID $BACKEND_PID $WATCHER_PID; do
if [ ! -z "$pid" ] && ps -p "$pid" > /dev/null 2>&1; then
echo "Killing process tree PID: $pid"
kill_tree "$pid"
fi
done
# Kill any remaining processes that are direct children of this script
pkill -P $$ 2>/dev/null || true
# Wait a moment for graceful shutdown
sleep 1
# As a final cleanup, kill any processes still using our ports
# (These should only be processes we started since we're in our own watch script)
echo "Final cleanup: killing any remaining processes on our ports..."
lsof -ti:5173 2>/dev/null | xargs -r kill 2>/dev/null || true
lsof -ti:8000 2>/dev/null | xargs -r kill 2>/dev/null || true
# Clean up PID file
rm -f "$PID_FILE"
echo "β
Cleanup complete"
exit 0
}
# Set trap to cleanup on exit
trap cleanup SIGINT SIGTERM EXIT
# Wait for processes
wait