From 950ec6ae55a601c3921e9146c7029d5fde9f3138 Mon Sep 17 00:00:00 2001 From: Kacper Date: Wed, 8 Apr 2026 06:14:06 -0400 Subject: [PATCH] Add app start script --- .gitignore | 2 ++ README.md | 22 +++++++++++++++ scripts/start.sh | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100755 scripts/start.sh diff --git a/.gitignore b/.gitignore index 4bbc897..0279cf6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ __pycache__/ .pytest_cache/ .ruff_cache/ +.env +.env.local frontend/node_modules/ frontend/dist/ frontend/.vite/ diff --git a/README.md b/README.md index 3f48de5..973bca0 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,22 @@ python3 -m venv .venv .venv/bin/python -m uvicorn app:app --reload ``` +### Start App + +Build the frontend and then serve the app from FastAPI: + +```bash +./scripts/start.sh +``` + +The script automatically loads `.env` and `.env.local` if present. + +Optional runtime overrides: + +```bash +HOST=0.0.0.0 PORT=8800 ./scripts/start.sh +``` + Optional live Forgejo configuration: ```bash @@ -27,6 +43,12 @@ export FORGEJO_TOKEN="your-forgejo-api-token" export CALENDAR_FEED_URLS="webcal://example.com/calendar.ics,https://example.com/other.ics" ``` +Or put those values in `.env`: + +```bash +cp .env.example .env +``` + ### Frontend ```bash diff --git a/scripts/start.sh b/scripts/start.sh new file mode 100755 index 0000000..1f7d8c7 --- /dev/null +++ b/scripts/start.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +set -euo pipefail + +root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +frontend_dir="${root_dir}/frontend" + +load_env_file() { + local env_file="$1" + [[ -f "${env_file}" ]] || return 0 + + while IFS= read -r line || [[ -n "${line}" ]]; do + line="${line#"${line%%[![:space:]]*}"}" + line="${line%"${line##*[![:space:]]}"}" + [[ -z "${line}" || "${line}" == \#* ]] && continue + + local key="${line%%=*}" + local value="${line#*=}" + key="${key%"${key##*[![:space:]]}"}" + key="${key#export }" + value="${value#"${value%%[![:space:]]*}"}" + value="${value%"${value##*[![:space:]]}"}" + if [[ "${value}" == \"*\" && "${value}" == *\" ]]; then + value="${value:1:-1}" + elif [[ "${value}" == \'*\' && "${value}" == *\' ]]; then + value="${value:1:-1}" + fi + + if [[ -z "${!key+x}" ]]; then + export "${key}=${value}" + fi + done < "${env_file}" +} + +load_env_file "${root_dir}/.env" +load_env_file "${root_dir}/.env.local" + +if [[ -x "${root_dir}/.venv/bin/python" ]]; then + python_cmd="${root_dir}/.venv/bin/python" +else + python_cmd="${PYTHON_BIN:-python3}" +fi + +if [[ -n "${BUN_BIN:-}" ]]; then + bun_cmd="${BUN_BIN}" +elif [[ -x "${HOME}/.bun/bin/bun" ]]; then + bun_cmd="${HOME}/.bun/bin/bun" +else + bun_cmd="bun" +fi + +host="${HOST:-0.0.0.0}" +port="${PORT:-8000}" + +if ! command -v "${python_cmd}" >/dev/null 2>&1; then + echo "Python runtime not found: ${python_cmd}" >&2 + exit 1 +fi + +if ! command -v "${bun_cmd}" >/dev/null 2>&1; then + echo "Bun runtime not found: ${bun_cmd}" >&2 + exit 1 +fi + +echo "==> Building frontend" +( + cd "${frontend_dir}" + "${bun_cmd}" run build +) + +echo "==> Starting backend on ${host}:${port}" +cd "${root_dir}" +exec "${python_cmd}" -m uvicorn app:app --host "${host}" --port "${port}"