179 lines
5.1 KiB
Bash
179 lines
5.1 KiB
Bash
#!/usr/bin/env bash
|
||
# ============================================================
|
||
# chanlun-py — 构建、安装、发布脚本
|
||
#
|
||
# 前置依赖:
|
||
# pip install maturin
|
||
# ============================================================
|
||
set -euo pipefail
|
||
|
||
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
cd "$PROJECT_DIR"
|
||
|
||
# 颜色输出
|
||
red() { echo -e "\033[31m$*\033[0m"; }
|
||
green() { echo -e "\033[32m$*\033[0m"; }
|
||
yellow() { echo -e "\033[33m$*\033[0m"; }
|
||
|
||
usage() {
|
||
cat <<'EOF'
|
||
用法: ./build.sh <命令>
|
||
|
||
命令:
|
||
build 开发模式编译(debug)
|
||
release 发布模式编译(release,带优化)
|
||
install 构建 wheel 并安装到当前 Python 环境
|
||
install-rel 同 install
|
||
develop 开发模式安装到 venv(需要激活虚拟环境)
|
||
test 运行集成测试
|
||
sdist 构建源码分发包
|
||
wheel 构建 wheel 包(release)
|
||
publish 发布至 PyPI(需先配置 TWINE_ 环境变量或 .pypirc)
|
||
clean 清理构建产物
|
||
bump 版本号自增(年月.次 → 2605.X)
|
||
check 检查 pyproject.toml 配置是否合法
|
||
|
||
PyPI 发布流程:
|
||
1. 确认 Cargo.toml 中 chanlun 依赖已切换为 crates.io 版本(非 path)
|
||
2. 更新版本号: pyproject.toml + Cargo.toml
|
||
3. ./build.sh check — 验证配置
|
||
4. ./build.sh publish — 构建并推送至 PyPI
|
||
|
||
环境变量:
|
||
TWINE_USERNAME — PyPI 用户名(或 __token__ 使用 API token)
|
||
TWINE_PASSWORD — PyPI 密码或 API token
|
||
或通过 twine 的 ~/.pypirc 配置
|
||
EOF
|
||
}
|
||
|
||
cmd_build() {
|
||
green "[build] 开发模式编译..."
|
||
cargo build
|
||
green "编译完成。使用 'maturin develop' 安装到 venv,或 './build.sh wheel' 构建 wheel"
|
||
}
|
||
|
||
cmd_release() {
|
||
green "[release] 发布模式编译..."
|
||
cargo build --release
|
||
}
|
||
|
||
cmd_bump() {
|
||
green "[bump] 版本号自增..."
|
||
python3 "$PROJECT_DIR/bump_version.py"
|
||
}
|
||
|
||
cmd_install() {
|
||
cmd_bump
|
||
green "[install] 构建 wheel 并安装..."
|
||
maturin build --release 2>&1 | tail -3
|
||
local wheel=$(ls -t target/wheels/*.whl 2>/dev/null | head -1)
|
||
if [ -z "$wheel" ]; then
|
||
red "未找到 wheel 文件"
|
||
exit 1
|
||
fi
|
||
pip install --force-reinstall "$wheel" 2>&1 | tail -3
|
||
green "安装完成!"
|
||
}
|
||
|
||
cmd_install_rel() {
|
||
cmd_install
|
||
}
|
||
|
||
cmd_develop() {
|
||
green "[develop] 开发模式安装(需要 venv)..."
|
||
maturin develop 2>&1 | tail -3
|
||
}
|
||
|
||
cmd_test() {
|
||
green "[test] 运行集成测试..."
|
||
# 确保已安装
|
||
python3 -c "import chanlun" 2>/dev/null || {
|
||
yellow "chanlun 未安装,正在构建并安装..."
|
||
maturin build --release 2>&1 | tail -3
|
||
local wheel=$(ls -t target/wheels/*.whl 2>/dev/null | head -1)
|
||
pip install --force-reinstall "$wheel" 2>&1 | tail -3
|
||
}
|
||
# 复制到临时目录运行,避免本地 chanlun/ 目录被优先导入
|
||
local tmp_dir=$(mktemp -d 2>/dev/null || echo "${TMPDIR:-/tmp}/chanlun-test-$$")
|
||
mkdir -p "$tmp_dir"
|
||
cp test_integration.py "$tmp_dir/test_integration.py"
|
||
CHANLUN_PROJECT_ROOT="$PROJECT_DIR/.." python3 "$tmp_dir/test_integration.py" "$@"
|
||
rm -rf "$tmp_dir"
|
||
}
|
||
|
||
cmd_sdist() {
|
||
green "[sdist] 构建源码分发包..."
|
||
maturin sdist
|
||
yellow "构建产物在: target/wheels/"
|
||
ls -lh target/wheels/*.tar.gz 2>/dev/null || true
|
||
}
|
||
|
||
cmd_wheel() {
|
||
cmd_bump
|
||
green "[wheel] 构建 wheel 包..."
|
||
maturin build --release
|
||
yellow "构建产物在: target/wheels/"
|
||
ls -lh target/wheels/*.whl 2>/dev/null || true
|
||
}
|
||
|
||
cmd_publish() {
|
||
cmd_bump
|
||
yellow "发布前请确认:"
|
||
yellow " 1. Cargo.toml 中 chanlun 依赖已切换为 crates.io 版本"
|
||
yellow " 2. 版本号已更新 (pyproject.toml + Cargo.toml)"
|
||
yellow " 3. git 工作区干净且已打 tag"
|
||
echo ""
|
||
read -rp "确认发布至 PyPI? [y/N] " confirm
|
||
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
|
||
red "已取消"
|
||
exit 0
|
||
fi
|
||
|
||
green "[publish] 构建并发布至 PyPI..."
|
||
maturin publish
|
||
|
||
green "发布完成!"
|
||
yellow "安装: pip install chanlun"
|
||
}
|
||
|
||
cmd_clean() {
|
||
green "[clean] 清理构建产物..."
|
||
cargo clean
|
||
rm -rf target/wheels/ dist/ build/ *.egg-info/
|
||
find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
||
green "清理完成"
|
||
}
|
||
|
||
cmd_check() {
|
||
green "[check] 验证 pyproject.toml..."
|
||
python3 -c "
|
||
import tomllib
|
||
with open('pyproject.toml', 'rb') as f:
|
||
data = tomllib.load(f)
|
||
print(' name:', data['project']['name'])
|
||
print(' version:', data['project']['version'])
|
||
print(' requires-python:', data['project']['requires-python'])
|
||
print(' build-backend:', data['build-system']['build-backend'])
|
||
print(' OK')
|
||
"
|
||
green "配置验证通过"
|
||
}
|
||
|
||
# --- main ---
|
||
case "${1:-}" in
|
||
build) cmd_build ;;
|
||
release) cmd_release ;;
|
||
install) cmd_install ;;
|
||
install-rel) cmd_install_rel ;;
|
||
develop) cmd_develop ;;
|
||
test) cmd_test ;;
|
||
sdist) cmd_sdist ;;
|
||
wheel) cmd_wheel ;;
|
||
publish) cmd_publish ;;
|
||
clean) cmd_clean ;;
|
||
bump) cmd_bump ;;
|
||
check) cmd_check ;;
|
||
-h|--help|help) usage ;;
|
||
*) red "未知命令: ${1:-}"; usage; exit 1 ;;
|
||
esac
|