nex_math/scripts/init.sh

113 lines
4.2 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
# 初始化本机运行环境:Python 虚拟环境 + 后端依赖 + 种子数据(+ 前端依赖)。
#
# ./scripts/init.sh 准备后端与前端环境
# ./scripts/init.sh --no-web 只准备后端
#
# 可用环境变量:
# PIP_INDEX_URL 指定 pip/uv 的包源(默认走官方源,失败自动改用清华镜像)
# NPM_REGISTRY 指定 npm 包源(失败自动改用 npmmirror)
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"
mkdir -p data
WITH_WEB=1
for arg in "$@"; do
case "$arg" in
--no-web) WITH_WEB=0 ;;
--web) WITH_WEB=1 ;;
-h|--help) sed -n '1,12p' "$0"; exit 0 ;;
*) echo "[init] 未知参数:$arg(可用:--no-web / --web)" >&2; exit 2 ;;
esac
done
# ---------- 1. 定位 uv(PATH → ~/.local/bin → ~/.cargo/bin) ----------
UV=""
for cand in uv "$HOME/.local/bin/uv" "$HOME/.cargo/bin/uv"; do
if command -v "$cand" >/dev/null 2>&1; then
UV="$(command -v "$cand")"
break
fi
done
# ---------- 2. 定位 Python 3.10+(系统 python3 常常太旧,优先带版本号的解释器) ----------
py_ok() { "$1" -c 'import sys; sys.exit(0 if sys.version_info >= (3, 10) else 1)' >/dev/null 2>&1; }
pick_python() {
for p in python3.13 python3.12 python3.11 python3.10 python3; do
if command -v "$p" >/dev/null 2>&1 && py_ok "$p"; then command -v "$p"; return 0; fi
done
for p in /opt/homebrew/bin/python3.1* /usr/local/bin/python3.1*; do
if [ -x "$p" ] && py_ok "$p"; then echo "$p"; return 0; fi
done
return 1
}
# ---------- 3. 虚拟环境 ----------
if [ -x backend/.venv/bin/python ]; then
echo "[init] 复用已有虚拟环境 backend/.venv($(backend/.venv/bin/python -V 2>&1))"
elif [ -n "$UV" ]; then
echo "[init] 使用 uv($UV)创建虚拟环境,优先 CPython 3.12…"
(cd backend && "$UV" venv .venv --python 3.12) 2>/dev/null || (cd backend && "$UV" venv .venv)
else
PY="$(pick_python || true)"
if [ -z "$PY" ]; then
echo "[init] 未找到 Python 3.10+(系统自带的 python3 版本过低)。推荐安装 uv 后重试:" >&2
echo " curl -LsSf https://astral.sh/uv/install.sh | sh" >&2
echo " 或 brew install python@3.12" >&2
exit 1
fi
echo "[init] 使用 $("$PY" -V 2>&1)($PY)创建虚拟环境…"
"$PY" -m venv backend/.venv
fi
# ---------- 4. 后端依赖(默认源失败后自动改用国内镜像) ----------
install_backend() {
if [ -n "$UV" ]; then
(cd backend && "$UV" pip install --python .venv/bin/python ${1:+--index-url "$1"} -r requirements.txt)
else
(cd backend && .venv/bin/pip install ${1:+-i "$1"} -r requirements.txt)
fi
}
if ! install_backend "${PIP_INDEX_URL:-}"; then
echo "[init] 默认包源安装失败,改用清华镜像重试…" >&2
install_backend https://pypi.tuna.tsinghua.edu.cn/simple
fi
# ---------- 5. 种子数据 ----------
if [ -f data/math.db ]; then
echo "[init] data/math.db 已存在,跳过种子数据(重建:cd backend && .venv/bin/python -m seed --force)"
else
(cd backend && .venv/bin/python -m seed)
fi
# ---------- 6. 前端依赖 ----------
if [ "$WITH_WEB" -eq 1 ]; then
if ! command -v node >/dev/null 2>&1; then
echo "[init] 未找到 Node.js,前端跳过。请安装 Node 20.19+ 或 22.12+ 后执行:cd frontend && npm install" >&2
else
if [ "$(node -p 'process.versions.node.split(".")[0]')" -lt 20 ]; then
echo "[init] 当前 Node $(node -v) 过低,Vite 8 需要 Node 20.19+ / 22.12+,前端可能无法启动。" >&2
fi
npm_install() {
if [ -n "${1:-}" ]; then (cd frontend && npm install --registry "$1"); else (cd frontend && npm install); fi
}
if [ -d frontend/node_modules ]; then
echo "[init] 前端依赖已存在,跳过 npm install"
elif ! npm_install "${NPM_REGISTRY:-}"; then
echo "[init] 默认 npm 源安装失败,改用 npmmirror 重试…" >&2
npm_install https://registry.npmmirror.com
fi
fi
fi
echo
echo "[init] 环境就绪:"
echo " Python $(backend/.venv/bin/python -V 2>&1) → backend/.venv"
echo " Node $(node -v 2>/dev/null || echo '未安装')"
echo " 数据库 $ROOT_DIR/data/math.db"
echo "[init] 启动:./scripts/start.sh → http://localhost:5173"