This should have been committed 100 years ago
This commit is contained in:
parent
e57323ff3f
commit
a102c96bb4
1 changed files with 365 additions and 0 deletions
365
run-dev.sh
Executable file
365
run-dev.sh
Executable file
|
|
@ -0,0 +1,365 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Run Chattyness servers in development mode
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Constants
|
||||||
|
# =============================================================================
|
||||||
|
readonly APP_PORT=3000
|
||||||
|
readonly OWNER_PORT=3001
|
||||||
|
readonly LOCKFILE=".run-dev.lock"
|
||||||
|
|
||||||
|
# Process IDs (set during runtime)
|
||||||
|
OWNER_PID=""
|
||||||
|
APP_PID=""
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Helper Functions
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $0 [build|watch] [--user-app|--owner-app|--both] [-f|-k|-s|-r]
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
build Build and run servers (default)
|
||||||
|
watch Watch mode with hot reload
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--user-app Run only the user app (port $APP_PORT)
|
||||||
|
--owner-app Run only the owner admin (port $OWNER_PORT)
|
||||||
|
--both Run both servers (default)
|
||||||
|
-f, --force Kill existing instance and start new one
|
||||||
|
-k, --kill Kill existing instance and exit
|
||||||
|
-s, --status Check if an instance is running
|
||||||
|
-r, --release Build and run in release mode
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
$0 # Build and run both
|
||||||
|
$0 watch # Watch mode for both
|
||||||
|
$0 --owner-app # Build and run owner only
|
||||||
|
$0 watch --user-app # Watch mode for user app only
|
||||||
|
$0 -f watch # Kill existing, then watch mode
|
||||||
|
$0 -k # Kill existing instance
|
||||||
|
$0 -s # Check status
|
||||||
|
$0 -r # Build and run in release mode
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Target helper functions
|
||||||
|
run_owner() { [ "$TARGET" = "both" ] || [ "$TARGET" = "owner" ]; }
|
||||||
|
run_app() { [ "$TARGET" = "both" ] || [ "$TARGET" = "app" ]; }
|
||||||
|
|
||||||
|
# Cleanup function - kills child processes and removes lock file
|
||||||
|
cleanup() {
|
||||||
|
echo ""
|
||||||
|
echo "Shutting down..."
|
||||||
|
[ -n "$OWNER_PID" ] && kill "$OWNER_PID" 2>/dev/null || true
|
||||||
|
[ -n "$APP_PID" ] && kill "$APP_PID" 2>/dev/null || true
|
||||||
|
[ -n "$OWNER_PID" ] && wait "$OWNER_PID" 2>/dev/null || true
|
||||||
|
[ -n "$APP_PID" ] && wait "$APP_PID" 2>/dev/null || true
|
||||||
|
rm -f "$LOCKFILE"
|
||||||
|
echo "Done."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print server URLs based on what's running
|
||||||
|
print_server_info() {
|
||||||
|
local mode="$1"
|
||||||
|
local build_type="Debug"
|
||||||
|
[ "$RELEASE" = "true" ] && build_type="Release"
|
||||||
|
echo ""
|
||||||
|
echo "========================================"
|
||||||
|
echo " Chattyness Development ($mode - $build_type)"
|
||||||
|
echo "========================================"
|
||||||
|
echo ""
|
||||||
|
if run_owner; then
|
||||||
|
echo " Owner Admin: http://127.0.0.1:$OWNER_PORT"
|
||||||
|
fi
|
||||||
|
if run_app; then
|
||||||
|
echo " User App: http://127.0.0.1:$APP_PORT"
|
||||||
|
echo " Realm Admin: http://127.0.0.1:$APP_PORT/admin"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
if [ "$TARGET" = "both" ]; then
|
||||||
|
echo "Admin CSS lazy-loaded via symlink from owner build."
|
||||||
|
fi
|
||||||
|
echo "Press Ctrl+C to stop"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wait for running child processes
|
||||||
|
wait_for_processes() {
|
||||||
|
if [ "$TARGET" = "both" ]; then
|
||||||
|
wait "$OWNER_PID" "$APP_PID"
|
||||||
|
elif [ "$TARGET" = "owner" ]; then
|
||||||
|
wait "$OWNER_PID"
|
||||||
|
else
|
||||||
|
wait "$APP_PID"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create symlink for admin CSS (user app loads admin CSS from owner build)
|
||||||
|
setup_admin_css_symlink() {
|
||||||
|
mkdir -p apps/chattyness-app/public
|
||||||
|
local target="../../../target/site-owner/static/chattyness-owner.css"
|
||||||
|
local link="apps/chattyness-app/public/admin.css"
|
||||||
|
if [ ! -L "$link" ]; then
|
||||||
|
ln -sf "$target" "$link"
|
||||||
|
echo "Created symlink: $link -> $target"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load environment variables from .env file
|
||||||
|
load_env() {
|
||||||
|
if [ -f .env ]; then
|
||||||
|
set -a
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
source .env
|
||||||
|
set +a
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Validate required environment variables
|
||||||
|
check_env() {
|
||||||
|
if [ -z "${DB_CHATTYNESS_OWNER:-}" ]; then
|
||||||
|
echo "Error: DB_CHATTYNESS_OWNER not set"
|
||||||
|
echo "Create a .env file with DB_CHATTYNESS_OWNER=your_password"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${DB_CHATTYNESS_APP:-}" ]; then
|
||||||
|
echo "Error: DB_CHATTYNESS_APP not set"
|
||||||
|
echo "Create a .env file with DB_CHATTYNESS_APP=your_password"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Lock File Management
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Check if another instance is running (returns PID or empty)
|
||||||
|
get_running_pid() {
|
||||||
|
if [ -f "$LOCKFILE" ]; then
|
||||||
|
local pid
|
||||||
|
pid=$(cat "$LOCKFILE" 2>/dev/null)
|
||||||
|
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
||||||
|
echo "$pid"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Handle --status flag
|
||||||
|
handle_status() {
|
||||||
|
local pid
|
||||||
|
pid=$(get_running_pid)
|
||||||
|
if [ -n "$pid" ]; then
|
||||||
|
echo "Running (PID: $pid)"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Not running"
|
||||||
|
[ -f "$LOCKFILE" ] && rm -f "$LOCKFILE" # Clean stale lock
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Kill any running instance (shared by -k and -f)
|
||||||
|
kill_running_instance() {
|
||||||
|
local pid
|
||||||
|
pid=$(get_running_pid)
|
||||||
|
if [ -n "$pid" ]; then
|
||||||
|
echo "Killing existing run-dev.sh (PID: $pid)..."
|
||||||
|
kill "$pid"
|
||||||
|
else
|
||||||
|
echo "No running instance found."
|
||||||
|
[ -f "$LOCKFILE" ] && rm -f "$LOCKFILE" # Clean stale lock
|
||||||
|
fi
|
||||||
|
echo "Killing chattyness processes..."
|
||||||
|
killall -9 chattyness-app 2>/dev/null || true
|
||||||
|
killall -9 chattyness-owner 2>/dev/null || true
|
||||||
|
echo "Done."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Handle --kill flag
|
||||||
|
handle_kill() {
|
||||||
|
kill_running_instance
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Handle --force flag (kill existing, then continue)
|
||||||
|
handle_force() {
|
||||||
|
kill_running_instance
|
||||||
|
sleep 1 # Allow lock release
|
||||||
|
}
|
||||||
|
|
||||||
|
# Acquire exclusive lock
|
||||||
|
acquire_lock() {
|
||||||
|
exec 200>"$LOCKFILE"
|
||||||
|
if ! flock -n 200; then
|
||||||
|
local pid
|
||||||
|
pid=$(cat "$LOCKFILE" 2>/dev/null)
|
||||||
|
echo ""
|
||||||
|
echo "ERROR: Another run-dev.sh instance is already running (PID: $pid)"
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " $0 -k Kill the existing instance"
|
||||||
|
echo " $0 -f [args...] Kill existing and start new instance"
|
||||||
|
echo " $0 -s Check status"
|
||||||
|
echo ""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo $$ >"$LOCKFILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Main Commands
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
do_watch() {
|
||||||
|
echo "Starting watch mode..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
local release_flag=""
|
||||||
|
[ "$RELEASE" = "true" ] && release_flag="--release"
|
||||||
|
|
||||||
|
# Build owner first to create CSS (needed if user app needs admin CSS)
|
||||||
|
if run_owner; then
|
||||||
|
echo "Building owner app first (for admin CSS)..."
|
||||||
|
cargo leptos build -p chattyness-owner $release_flag
|
||||||
|
setup_admin_css_symlink
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start watch processes
|
||||||
|
if run_owner; then
|
||||||
|
cargo leptos watch -p chattyness-owner $release_flag &
|
||||||
|
OWNER_PID=$!
|
||||||
|
fi
|
||||||
|
|
||||||
|
if run_app; then
|
||||||
|
cargo leptos watch -p chattyness-app --split $release_flag &
|
||||||
|
APP_PID=$!
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_server_info "Watch Mode"
|
||||||
|
wait_for_processes
|
||||||
|
}
|
||||||
|
|
||||||
|
do_build() {
|
||||||
|
local release_flag=""
|
||||||
|
local target_dir="debug"
|
||||||
|
if [ "$RELEASE" = "true" ]; then
|
||||||
|
release_flag="--release"
|
||||||
|
target_dir="release"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build phase
|
||||||
|
if run_owner; then
|
||||||
|
echo "Running: cargo leptos build -p chattyness-owner $release_flag"
|
||||||
|
cargo leptos build -p chattyness-owner $release_flag
|
||||||
|
setup_admin_css_symlink
|
||||||
|
fi
|
||||||
|
|
||||||
|
if run_app; then
|
||||||
|
echo ""
|
||||||
|
echo "Running: cargo leptos build -p chattyness-app --split $release_flag"
|
||||||
|
cargo leptos build -p chattyness-app --split $release_flag
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify binaries exist
|
||||||
|
if run_owner && [ ! -x "./target/$target_dir/chattyness-owner" ]; then
|
||||||
|
echo "Error: ./target/$target_dir/chattyness-owner not found or not executable"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if run_app && [ ! -x "./target/$target_dir/chattyness-app" ]; then
|
||||||
|
echo "Error: ./target/$target_dir/chattyness-app not found or not executable"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start servers
|
||||||
|
if run_owner; then
|
||||||
|
echo "Starting Owner Server on :$OWNER_PORT..."
|
||||||
|
./target/$target_dir/chattyness-owner &
|
||||||
|
OWNER_PID=$!
|
||||||
|
fi
|
||||||
|
|
||||||
|
if run_app; then
|
||||||
|
echo "Starting App Server on :$APP_PORT..."
|
||||||
|
./target/$target_dir/chattyness-app &
|
||||||
|
APP_PID=$!
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_server_info "Servers"
|
||||||
|
wait_for_processes
|
||||||
|
}
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Main Entry Point
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
LEPTOS_CMD="build"
|
||||||
|
TARGET="both"
|
||||||
|
FORCE="false"
|
||||||
|
KILL_EXISTING="false"
|
||||||
|
CHECK_STATUS="false"
|
||||||
|
RELEASE="false"
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
case $arg in
|
||||||
|
build | watch)
|
||||||
|
LEPTOS_CMD="$arg"
|
||||||
|
;;
|
||||||
|
--user-app)
|
||||||
|
TARGET="app"
|
||||||
|
;;
|
||||||
|
--owner-app)
|
||||||
|
TARGET="owner"
|
||||||
|
;;
|
||||||
|
--both)
|
||||||
|
TARGET="both"
|
||||||
|
;;
|
||||||
|
-f | --force)
|
||||||
|
FORCE="true"
|
||||||
|
;;
|
||||||
|
-k | --kill)
|
||||||
|
KILL_EXISTING="true"
|
||||||
|
;;
|
||||||
|
-s | --status)
|
||||||
|
CHECK_STATUS="true"
|
||||||
|
;;
|
||||||
|
-r | --release)
|
||||||
|
RELEASE="true"
|
||||||
|
;;
|
||||||
|
--help | -h)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option: $arg"
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Handle special flags first (before acquiring lock)
|
||||||
|
[ "$CHECK_STATUS" = "true" ] && handle_status
|
||||||
|
[ "$KILL_EXISTING" = "true" ] && handle_kill
|
||||||
|
[ "$FORCE" = "true" ] && handle_force
|
||||||
|
|
||||||
|
# Acquire lock and store PID
|
||||||
|
acquire_lock
|
||||||
|
|
||||||
|
# Set up cleanup trap
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
|
# Load and validate environment
|
||||||
|
load_env
|
||||||
|
check_env
|
||||||
|
|
||||||
|
# Run the requested command
|
||||||
|
case "$LEPTOS_CMD" in
|
||||||
|
watch) do_watch ;;
|
||||||
|
build) do_build ;;
|
||||||
|
esac
|
||||||
Loading…
Add table
Add a link
Reference in a new issue