#!/usr/bin/env bash REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" GIT_DIR_PATH="$(git rev-parse --git-dir 2>/dev/null)" GIT_COMMON_PATH="$(git rev-parse --git-common-dir 2>/dev/null)" # Linked worktrees get their own runtime state and port range. if [ -n "$GIT_COMMON_PATH" ] \ && [ "$GIT_DIR_PATH" != "$GIT_COMMON_PATH" ]; then IS_WORKTREE=1 MAIN_REPO_ROOT="$(cd "$GIT_COMMON_PATH/.." && pwd)" else IS_WORKTREE=0 MAIN_REPO_ROOT="$REPO_ROOT" fi if [ "$IS_WORKTREE" = 1 ]; then if [ -n "$PORT_OFFSET" ]; then OFFSET="$PORT_OFFSET" else PORT_HASH="$(printf '%s' "$REPO_ROOT" | cksum | cut -d' ' -f1)" OFFSET=$(( (PORT_HASH % 49 + 1) * 100 )) fi else OFFSET=0 fi export CADDY_PORT=$((8000 + OFFSET)) export BACKEND_PORT=$((8001 + OFFSET)) export VITE_PORT=$((5173 + OFFSET)) export MAILPIT_SMTP_PORT=$((2525 + OFFSET)) export MAILPIT_UI_PORT=$((8025 + OFFSET)) export PC_PORT_NUM=$((8080 + OFFSET)) export PGDATA="$REPO_ROOT/.postgres" export PGHOST="$PGDATA" export PGUSER="postgres" export PGDATABASE="postgres" DEV_APP_URL="https://localhost:$CADDY_PORT" DEV_FRONTEND_URL="https://localhost:$VITE_PORT" DEV_DB_CONNECTION="pgsql" DEV_DB_HOST="$PGHOST" DEV_DB_PORT="5432" DEV_DB_DATABASE="$PGDATABASE" DEV_DB_USERNAME="$PGUSER" DEV_DB_PASSWORD="" DEV_MAIL_MAILER="smtp" DEV_MAIL_HOST="127.0.0.1" DEV_MAIL_PORT="$MAILPIT_SMTP_PORT" if [ ! -d "$PGDATA" ]; then echo "[pg] initializing cluster at $PGDATA" initdb --auth=trust --username="$PGUSER" --no-locale --encoding=UTF8 >/dev/null { echo "listen_addresses = ''" echo "unix_socket_directories = '$PGDATA'" } >> "$PGDATA/postgresql.conf" fi # Worktrees share host-independent localhost certificates with the main checkout. MAIN_CERT_ROOT="$MAIN_REPO_ROOT/.cert" if [ ! -d "$MAIN_CERT_ROOT" ]; then echo "[cert] installing local CA + generating TLS certs in $MAIN_CERT_ROOT" mkcert -install mkdir -p "$MAIN_CERT_ROOT" mkcert \ -key-file "$MAIN_CERT_ROOT/localhost-key.pem" \ -cert-file "$MAIN_CERT_ROOT/localhost.pem" \ localhost 127.0.0.1 ::1 fi if [ "$IS_WORKTREE" = 1 ] \ && [ ! -e "$REPO_ROOT/.cert" ] \ && [ ! -L "$REPO_ROOT/.cert" ]; then ln -s "$MAIN_CERT_ROOT" "$REPO_ROOT/.cert" fi ENV_FILE="$REPO_ROOT/backend/.env" if [ ! -f "$ENV_FILE" ]; then if [ "$IS_WORKTREE" = 1 ] && [ -f "$MAIN_REPO_ROOT/backend/.env" ]; then cp "$MAIN_REPO_ROOT/backend/.env" "$ENV_FILE" else cp "$REPO_ROOT/backend/.env.example" "$ENV_FILE" fi fi set_env_value() { local env_key="$1" local env_value="$2" local escaped_value escaped_value="$(printf '%s' "$env_value" | sed 's/[&|\\]/\\&/g')" if grep -q "^${env_key}=" "$ENV_FILE"; then sed -i "s|^${env_key}=.*|${env_key}=${escaped_value}|" "$ENV_FILE" else printf '%s=%s\n' "$env_key" "$env_value" >> "$ENV_FILE" fi } set_env_value APP_URL "$DEV_APP_URL" set_env_value FRONTEND_URL "$DEV_FRONTEND_URL" set_env_value DB_CONNECTION "$DEV_DB_CONNECTION" set_env_value DB_HOST "$DEV_DB_HOST" set_env_value DB_PORT "$DEV_DB_PORT" set_env_value DB_DATABASE "$DEV_DB_DATABASE" set_env_value DB_USERNAME "$DEV_DB_USERNAME" set_env_value DB_PASSWORD "$DEV_DB_PASSWORD" set_env_value MAIL_MAILER "$DEV_MAIL_MAILER" set_env_value MAIL_HOST "$DEV_MAIL_HOST" set_env_value MAIL_PORT "$DEV_MAIL_PORT" FRONTEND_ENV_FILE="$REPO_ROOT/frontend/website/.env.local" FRONTEND_API_URL="VITE_API_URL=$DEV_APP_URL" if [ ! -f "$FRONTEND_ENV_FILE" ] \ || [ "$(cat "$FRONTEND_ENV_FILE")" != "$FRONTEND_API_URL" ]; then printf '%s\n' "$FRONTEND_API_URL" > "$FRONTEND_ENV_FILE" fi if [ ! -d "$REPO_ROOT/backend/vendor" ]; then echo "[composer] installing backend dependencies" (cd "$REPO_ROOT/backend" && composer install) fi if grep -q '^APP_KEY=$' "$ENV_FILE"; then echo "[laravel] generating application key" (cd "$REPO_ROOT/backend" && php artisan key:generate) fi if [ ! -e "$REPO_ROOT/backend/public/storage" ]; then echo "[laravel] linking public storage" (cd "$REPO_ROOT/backend" && php artisan storage:link) fi echo "[dev] run 'process-compose up' to start:" \ "postgres + mailpit + backend + caddy + frontend"