mirror of
https://github.com/gtsteffaniak/filebrowser.git
synced 2026-11-04 08:42:06 -05:00
Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Graham Steffaniak <gtsteffaniak@users.noreply.github.com>
126 lines
3.3 KiB
Bash
Executable File
126 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
VITE_PORT="${VITE_DEV_PORT:-5173}"
|
|
BACKEND_CONFIG="${BACKEND_CONFIG:-$ROOT/backend/test_config.yaml}"
|
|
|
|
# Browser talks to the Go server (which reverse-proxies /__vite/). Keep Vite's
|
|
# server.origin + HMR clientPort in sync with that listen port so modules/HMR
|
|
# stay same-origin instead of defaulting to :8080 while Air uses test_config.
|
|
backend_http_port() {
|
|
local config=$1
|
|
local port=""
|
|
if [[ -f "$config" ]]; then
|
|
port="$(
|
|
awk '
|
|
/^[[:space:]]*http:[[:space:]]*(#.*)?$/ { in_http=1; next }
|
|
in_http && /^[^[:space:]#]/ { in_http=0 }
|
|
in_http && /^[[:space:]]*port:[[:space:]]*[0-9]+/ {
|
|
gsub(/[^0-9]/, "", $2)
|
|
print $2
|
|
exit
|
|
}
|
|
' "$config"
|
|
)"
|
|
fi
|
|
if [[ -z "$port" ]]; then
|
|
port=8080
|
|
fi
|
|
printf '%s' "$port"
|
|
}
|
|
|
|
BACKEND_PORT="$(backend_http_port "$BACKEND_CONFIG")"
|
|
VITE_ORIGIN="${VITE_DEV_ORIGIN:-http://localhost:${BACKEND_PORT}}"
|
|
VITE_CLIENT_PORT="${VITE_DEV_CLIENT_PORT:-${BACKEND_PORT}}"
|
|
READY_URL="http://127.0.0.1:${VITE_PORT}/__vite/@vite/client"
|
|
WAIT_SECONDS="${VITE_READY_TIMEOUT:-60}"
|
|
|
|
stop_listeners_on_port() {
|
|
local port=$1
|
|
if command -v fuser >/dev/null 2>&1; then
|
|
fuser -k "${port}/tcp" 2>/dev/null || true
|
|
elif command -v lsof >/dev/null 2>&1; then
|
|
local pids
|
|
pids="$(lsof -ti :"${port}" 2>/dev/null || true)"
|
|
if [[ -n "$pids" ]]; then
|
|
kill -TERM $pids 2>/dev/null || true
|
|
fi
|
|
elif command -v ss >/dev/null 2>&1; then
|
|
local pid
|
|
pid="$(ss -tlnp 2>/dev/null | sed -n "s/.*:${port} .*pid=\\([0-9]*\\).*/\\1/p" | head -n1)"
|
|
if [[ -n "$pid" ]]; then
|
|
kill -TERM "$pid" 2>/dev/null || true
|
|
fi
|
|
fi
|
|
sleep 0.3
|
|
}
|
|
|
|
cleanup() {
|
|
local status=$?
|
|
trap - EXIT INT TERM
|
|
if [[ -n "${AIR_PID:-}" ]] && kill -0 "$AIR_PID" 2>/dev/null; then
|
|
kill -TERM "$AIR_PID" 2>/dev/null || true
|
|
fi
|
|
if [[ -n "${VITE_PID:-}" ]] && kill -0 "$VITE_PID" 2>/dev/null; then
|
|
kill -TERM "$VITE_PID" 2>/dev/null || true
|
|
fi
|
|
if [[ -n "${AIR_PID:-}" ]]; then
|
|
wait "$AIR_PID" 2>/dev/null || true
|
|
fi
|
|
wait "$VITE_PID" 2>/dev/null || true
|
|
exit "$status"
|
|
}
|
|
|
|
wait_for_vite() {
|
|
local elapsed=0
|
|
while (( elapsed < WAIT_SECONDS )); do
|
|
if curl -fsS -o /dev/null "$READY_URL" 2>/dev/null; then
|
|
return 0
|
|
fi
|
|
if ! kill -0 "$VITE_PID" 2>/dev/null; then
|
|
echo "Vite dev server exited before becoming ready." >&2
|
|
return 1
|
|
fi
|
|
sleep 1
|
|
elapsed=$((elapsed + 1))
|
|
done
|
|
echo "Timed out waiting for Vite at ${READY_URL}" >&2
|
|
return 1
|
|
}
|
|
|
|
trap cleanup EXIT INT TERM
|
|
|
|
if curl -fsS -o /dev/null "$READY_URL" 2>/dev/null || ss -tln 2>/dev/null | grep -q ":${VITE_PORT} "; then
|
|
echo "Clearing stale listener on port ${VITE_PORT}..."
|
|
stop_listeners_on_port "$VITE_PORT"
|
|
fi
|
|
|
|
echo "Starting Vite dev server on 127.0.0.1:${VITE_PORT} (browser origin ${VITE_ORIGIN}, HMR clientPort ${VITE_CLIENT_PORT})..."
|
|
(
|
|
cd "$ROOT/frontend"
|
|
export VITE_DEV_ORIGIN="$VITE_ORIGIN"
|
|
export VITE_DEV_PORT="$VITE_PORT"
|
|
export VITE_DEV_CLIENT_PORT="$VITE_CLIENT_PORT"
|
|
exec npm run dev
|
|
) &
|
|
VITE_PID=$!
|
|
|
|
wait_for_vite
|
|
echo "Vite is ready. Starting Air..."
|
|
|
|
(
|
|
cd "$ROOT/backend"
|
|
export FILEBROWSER_DEVMODE=true
|
|
AIR_BIN="$(cd build && go tool -n air)"
|
|
exec "$AIR_BIN"
|
|
) &
|
|
AIR_PID=$!
|
|
|
|
# wait -n needs Bash 4.3+ (macOS /bin/bash is 3.2)
|
|
while kill -0 "$VITE_PID" 2>/dev/null && kill -0 "$AIR_PID" 2>/dev/null; do
|
|
sleep 1
|
|
done
|
|
echo "A dev process exited; stopping the other..." >&2
|
|
exit 1
|