sipracd / dev.sh
Guilherme Silberfarb Costa
Deploy current SIPRAC app snapshot
7fabf33
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BACKEND_DIR="$ROOT_DIR/backend"
FRONTEND_DIR="$ROOT_DIR/frontend"
BACKEND_VENV="${BACKEND_VENV:-$BACKEND_DIR/.venv313}"
BACKEND_PORT="${BACKEND_PORT:-8000}"
FRONTEND_PORT="${FRONTEND_PORT:-5173}"
PYTHON_BIN="${PYTHON_BIN:-python3.13}"
BACKEND_PID=""
cleanup() {
if [[ -n "$BACKEND_PID" ]] && kill -0 "$BACKEND_PID" >/dev/null 2>&1; then
echo ""
echo "Encerrando backend..."
kill "$BACKEND_PID" >/dev/null 2>&1 || true
wait "$BACKEND_PID" 2>/dev/null || true
fi
}
trap cleanup EXIT INT TERM
require_command() {
local command_name="$1"
if ! command -v "$command_name" >/dev/null 2>&1; then
echo "Comando obrigatório não encontrado: $command_name" >&2
exit 1
fi
}
port_in_use() {
local port="$1"
lsof -nP -iTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1
}
pick_available_port() {
local port="$1"
while port_in_use "$port"; do
port=$((port + 1))
done
echo "$port"
}
python_version_of_venv() {
local venv_dir="$1"
if [[ -x "$venv_dir/bin/python" ]]; then
"$venv_dir/bin/python" -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")'
fi
}
ensure_backend_env() {
require_command "$PYTHON_BIN"
local desired_version
desired_version="$("$PYTHON_BIN" -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')"
if [[ ! -d "$BACKEND_VENV" ]]; then
echo "Criando ambiente virtual do backend com $PYTHON_BIN..."
"$PYTHON_BIN" -m venv "$BACKEND_VENV"
else
local current_version
current_version="$(python_version_of_venv "$BACKEND_VENV")"
if [[ "$current_version" != "$desired_version" ]]; then
echo "A venv em $BACKEND_VENV usa Python $current_version, mas o script espera Python $desired_version." >&2
echo "Apague essa venv ou rode com BACKEND_VENV apontando para outra pasta." >&2
echo "Sugestão segura:" >&2
echo " mv \"$BACKEND_VENV\" \"${BACKEND_VENV}.old\"" >&2
echo "Depois rode novamente ./dev.sh" >&2
exit 1
fi
fi
echo "Instalando/verificando dependências do backend..."
# shellcheck disable=SC1091
source "$BACKEND_VENV/bin/activate"
pip install -r "$BACKEND_DIR/requirements.txt" >/dev/null
}
ensure_frontend_env() {
require_command npm
if [[ ! -d "$FRONTEND_DIR/node_modules" ]] || [[ ! -x "$FRONTEND_DIR/node_modules/.bin/vite" ]]; then
echo "Instalando dependências do frontend..."
(cd "$FRONTEND_DIR" && npm install)
fi
}
prepare_ports() {
if port_in_use "$BACKEND_PORT"; then
local requested_port="$BACKEND_PORT"
BACKEND_PORT="$(pick_available_port "$BACKEND_PORT")"
echo "Porta $requested_port já está em uso no backend. Usando $BACKEND_PORT."
fi
if port_in_use "$FRONTEND_PORT"; then
local requested_port="$FRONTEND_PORT"
FRONTEND_PORT="$(pick_available_port "$FRONTEND_PORT")"
echo "Porta $requested_port já está em uso no frontend. Usando $FRONTEND_PORT."
fi
}
start_backend() {
echo "Subindo backend em http://127.0.0.1:$BACKEND_PORT ..."
(
cd "$BACKEND_DIR"
# shellcheck disable=SC1091
source "$BACKEND_VENV/bin/activate"
uvicorn app.main:app --reload --host 127.0.0.1 --port "$BACKEND_PORT"
) &
BACKEND_PID=$!
}
start_frontend() {
echo "Subindo frontend em http://127.0.0.1:$FRONTEND_PORT ..."
cd "$FRONTEND_DIR"
VITE_API_BASE_URL="http://127.0.0.1:$BACKEND_PORT" npm run dev -- --host 127.0.0.1 --port "$FRONTEND_PORT"
}
echo "Preparando ambiente de desenvolvimento..."
ensure_backend_env
ensure_frontend_env
prepare_ports
start_backend
start_frontend