Files
FinDataHub/Scripts/bundle-python.sh
T
FinDataHub 11d36d1c1e fix(repo): 修正 Scripts 目录索引大小写并补齐未入库脚本
问题
- 索引中该目录记为小写 `scripts/`,工作区实为 `Scripts/`。因 core.ignorecase=true,
  本地 `git diff -- Scripts/bin/x.py` 会**静默返回空**(看似无改动),
  且在大小写敏感环境(Linux CI / Docker 挂载)会检出 `scripts/`,
  与全仓所有 `Scripts/...` 引用不匹配。
- 该目录此前 10 个脚本(check_python_version.py、perf_snapshot.py、
  install_collector_launchd.py、mysql_toggle.sh 等)从未入库,
  而 CI 第 31 行正调用 `Scripts/bin/check_python_version.py --strict` ——
  全新检出必然失败。

改动
- 索引路径统一为 `Scripts/`(工作区文件未移动,仅索引改名)。
- 补齐上述 10 个未跟踪脚本及其测试。

影响
- 修正前索引 35 条(全为小写路径),修正后 45 条。
2026-09-18 22:37:32 +08:00

104 lines
3.6 KiB
Bash

#!/bin/bash
# ==============================================================
# bundle-python.sh — 将 Python 运行时 + akshare-fetcher 打包进 .app
# ==============================================================
set -e
APP_DIR="${1:-.build/FinDataHub.app}"
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
# 数据源项目路径可通过环境变量覆盖
AKSHARE_SRC="${AKSHARE_SRC:-${PROJECT_ROOT}/Services/akshare_fetcher}"
FRAMEWORKS_DIR="${APP_DIR}/Contents/Frameworks"
RESOURCES_DIR="${APP_DIR}/Contents/Resources"
VENV_DIR="${FRAMEWORKS_DIR}/akshare-venv"
AKSHARE_DST="${RESOURCES_DIR}/akshare_fetcher"
echo "=== 打包 Python 运行时 ==="
echo " .app: ${APP_DIR}"
echo ""
# ---------- 1. 创建 venv ----------
if [ -d "${VENV_DIR}/bin" ]; then
echo "[1/3] 虚拟环境已存在,跳过创建"
else
echo "[1/3] 创建 Python 虚拟环境..."
mkdir -p "${FRAMEWORKS_DIR}"
cd "${PROJECT_ROOT}"
# uv venv 创建独立虚拟环境(与 bundle 内实际运行时保持一致)
uv venv --python 3.14 "${VENV_DIR}" 2>&1 | tail -3
echo " ✅ 虚拟环境已创建"
fi
source "${VENV_DIR}/bin/activate"
echo " Python: $(python3 --version)"
# ---------- 2. 安装依赖 ----------
echo "[2/3] 安装 akshare-fetcher 依赖..."
cd "${AKSHARE_SRC}"
# 从 pyproject.toml 安装依赖(版本约束由 pyproject.toml 管理,避免无版本锁定)
pip install --quiet --upgrade pip 2>/dev/null || true
install_time=$(date +%s)
# 以可编辑模式安装项目,读取 pyproject.toml 中声明的依赖及版本约束
pip install --quiet -e "${AKSHARE_SRC}" 2>&1 | tail -3
# 验证
python3 -c "import akshare; print(f' ✅ akshare {akshare.__version__} 可导入')" 2>&1
python3 -c "import pandas; print(f' ✅ pandas {pandas.__version__}')" 2>&1
python3 -c "import numpy; print(f' ✅ numpy {numpy.__version__}')" 2>&1
du -sh "${VENV_DIR}"
echo ""
# ---------- 3. 复制项目代码 ----------
echo "[3/3] 部署 akshare-fetcher 项目代码..."
mkdir -p "${AKSHARE_DST}"
rsync -a --delete \
--exclude='.venv' \
--exclude='.git' \
--exclude='__pycache__' \
--exclude='*.pyc' \
--exclude='*.pyo' \
--exclude='.DS_Store' \
--exclude='uv.lock' \
"${AKSHARE_SRC}/" "${AKSHARE_DST}/"
echo " ✅ 项目代码已部署 (${AKSHARE_DST})"
# ---------- 4. 创建入口脚本 ----------
echo " 创建入口脚本..."
mkdir -p "${RESOURCES_DIR}/bin"
cat > "${RESOURCES_DIR}/bin/akshare-fetcher.sh" << 'SCRIPT'
#!/bin/bash
# FinDataHub 内置 akshare-fetcher 入口
# 使用捆绑的虚拟环境
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
APP_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)"
VENV_PYTHON="${APP_DIR}/Contents/Frameworks/akshare-venv/bin/python3"
PROJECT_DIR="${APP_DIR}/Contents/Resources/akshare_fetcher"
export PYTHONUNBUFFERED=1
export AKSHARE_HOME="${PROJECT_DIR}"
export PYTHONPATH="${PROJECT_DIR}/src"
cd "${PROJECT_DIR}"
exec "${VENV_PYTHON}" -m akshare_fetcher "$@"
SCRIPT
chmod +x "${RESOURCES_DIR}/bin/akshare-fetcher.sh"
# 同时创建快捷入口: akshare-fetcher → 直接调项目源码
cat > "${AKSHARE_DST}/run_bundled.sh" << 'SCRIPT'
#!/bin/bash
# 捆绑环境入口 — 使用 FinDataHub 内建的 venv
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
VENV_PYTHON="${SCRIPT_DIR}/../../Frameworks/akshare-venv/bin/python3"
export PYTHONPATH="${SCRIPT_DIR}/src"
cd "${SCRIPT_DIR}"
exec "${VENV_PYTHON}" -m akshare_fetcher "$@"
SCRIPT
chmod +x "${AKSHARE_DST}/run_bundled.sh"
echo ""
echo "=== Python 运行时打包完成 ==="
du -sh "${VENV_DIR}" "${AKSHARE_DST}" 2>/dev/null
echo ""
echo "总大小:"
du -sh "${FRAMEWORKS_DIR}" "${RESOURCES_DIR}" 2>/dev/null