netrans/setup.sh

374 lines
11 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Netrans 安装脚本(增量安装)
# 功能:
# 1. 对比安装状态快照,只执行必要的步骤
# 2. 安装 Python 依赖(仅在 requirements.txt 变化时)
# 3. 安装 acuity仅在 vendor 变化时)
# 4. 安装 netranspip install -e几乎零开销
# 5. 配置环境变量 PATH、VIV_SDK_PATH 和 NETRANS_PYTHON
set -e
# ── 前置检查Python 版本和系统架构 ──────────────────────
PYTHON_CMD="python3"
PIP_CMD="$PYTHON_CMD -m pip"
python_version=$($PYTHON_CMD -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
NETRANS_PYTHON=$($PYTHON_CMD -c 'import sys; print(sys.executable)')
required_version="3.10"
if [ "$(printf '%s\n' "$required_version" "$python_version" | sort -V | head -n1)" != "$required_version" ]; then
echo "错误: Python版本需要 >= $required_version,当前版本: $python_version"
exit 1
fi
arch=$(uname -m)
if [ "$arch" != "x86_64" ]; then
echo "错误: Netrans 仅支持 x86_64 架构,当前架构: $arch"
exit 1
fi
echo "✓ 前置检查通过: Python $python_version, $arch"
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT_DIR="$CURRENT_DIR/script"
INSTALL_STATE="$CURRENT_DIR/.install_state"
VIV_SDK_PATH="$CURRENT_DIR/vendor/viv_sdk/VivanteIDE5.8.2/cmdtools"
BASHRC="$HOME/.bashrc"
require_file() {
local file="$1"
local name="$2"
if [ ! -f "$file" ]; then
echo "错误: 缺少 ${name}: $file"
exit 1
fi
}
require_dir() {
local dir="$1"
local name="$2"
if [ ! -d "$dir" ]; then
echo "错误: 缺少 ${name}: $dir"
exit 1
fi
}
hash_files_under() {
local dir="$1"
if [ ! -d "$dir" ]; then
echo "missing"
return
fi
find "$dir" -type f \
! -path "*/__pycache__/*" \
! -name "*.pyc" \
! -name "*.pyo" \
-print0 2>/dev/null \
| sort -z \
| xargs -0 -r md5sum 2>/dev/null \
| md5sum \
| cut -d' ' -f1
}
hash_tree_metadata() {
local dir="$1"
if [ ! -d "$dir" ]; then
echo "missing"
return
fi
find "$dir" -type f \
! -path "*/__pycache__/*" \
! -name "*.pyc" \
! -name "*.pyo" \
-printf "%P %s %T@\n" 2>/dev/null \
| sort \
| md5sum \
| cut -d' ' -f1
}
find_acuity_whl() {
find "$CURRENT_DIR/vendor" -maxdepth 1 -type f -name "acuity-*.whl" 2>/dev/null \
| sort \
| head -1
}
hash_files() {
local files=()
local file
for file in "$@"; do
if [ -f "$file" ]; then
files+=("$file")
fi
done
if [ ${#files[@]} -eq 0 ]; then
echo "missing"
return
fi
md5sum "${files[@]}" | sort | md5sum | cut -d' ' -f1
}
load_install_state() {
local file="$1"
local key
local value
installed_version=""
vendor_state=""
requirements_hash=""
setup_hash=""
if [ ! -f "$file" ]; then
return 1
fi
while IFS='=' read -r key value; do
case "$key" in
""|\#*) continue ;;
esac
value=$(printf '%s' "$value" | tr -d '[:space:]')
case "$key" in
installed_version)
if [[ "$value" =~ ^[A-Za-z0-9._+-]+$ ]]; then
installed_version="$value"
fi
;;
vendor_state)
if [[ "$value" =~ ^([A-Fa-f0-9]+|missing)$ ]]; then
vendor_state="$value"
fi
;;
requirements_hash)
if [[ "$value" =~ ^([A-Fa-f0-9]+|missing)$ ]]; then
requirements_hash="$value"
fi
;;
setup_hash)
if [[ "$value" =~ ^([A-Fa-f0-9]+|missing)$ ]]; then
setup_hash="$value"
fi
;;
esac
done < "$file"
return 0
}
read_version_meta() {
local key="$1"
local file="$CURRENT_DIR/VERSION"
if [ ! -f "$file" ]; then
return
fi
local value
value=$(grep -E "^${key}=" "$file" | head -1 | cut -d'=' -f2- | tr -d '[:space:]')
if [ -n "$value" ]; then
echo "$value"
return
fi
# Backward compatibility with the old single-line VERSION format.
if [ "$key" = "VERSION" ]; then
head -1 "$file" | tr -d '[:space:]'
fi
}
write_shell_env() {
local rc_file="$1"
local tmp_file
mkdir -p "$(dirname "$rc_file")"
touch "$rc_file"
tmp_file=$(mktemp)
awk '
/^# >>> Netrans environment >>>$/ { skip=1; next }
/^# <<< Netrans environment <<<$/{ skip=0; next }
skip { next }
/^# Netrans 命令行工具路径$/ { skip_next=1; next }
/^# Netrans Vivante SDK 路径$/ { skip_next=1; next }
/^# Netrans Python 解释器$/ { skip_next=1; next }
skip_next && /^export PATH=.*\/script"/ { skip_next=0; next }
skip_next && /^export VIV_SDK_PATH="/ { skip_next=0; next }
skip_next && /^export NETRANS_PYTHON="/ { skip_next=0; next }
{ skip_next=0; print }
' "$rc_file" > "$tmp_file"
cat >> "$tmp_file" << EOF
# >>> Netrans environment >>>
export PATH="\$PATH:$SCRIPT_DIR"
export VIV_SDK_PATH="$VIV_SDK_PATH"
export NETRANS_PYTHON="$NETRANS_PYTHON"
# <<< Netrans environment <<<
EOF
mv "$tmp_file" "$rc_file"
}
echo "========================================"
echo " Netrans 安装脚本"
echo "========================================"
# ── 检查源码目录结构 ──────────────────────────────────
require_file "$CURRENT_DIR/VERSION" "版本文件"
require_file "$CURRENT_DIR/requirements.txt" "依赖清单"
require_file "$CURRENT_DIR/setup.py" "Python 包配置"
require_dir "$CURRENT_DIR/src/netrans" "netrans 源码目录"
require_dir "$SCRIPT_DIR" "脚本目录"
require_dir "$CURRENT_DIR/vendor" "vendor 目录"
require_dir "$VIV_SDK_PATH" "Vivante SDK cmdtools 目录"
ACUITY_WHL=$(find_acuity_whl)
if [ -z "$ACUITY_WHL" ]; then
echo "错误: 未找到 acuity whl 文件: $CURRENT_DIR/vendor/acuity-*.whl"
exit 1
fi
# ── 读取上次安装状态 ──────────────────────────────────
if load_install_state "$INSTALL_STATE"; then
echo ""
echo "[预检] 上次安装版本: ${installed_version:-未知}"
else
echo ""
echo "[预检] 首次安装,将执行全量安装"
installed_version=""
vendor_state=""
requirements_hash=""
setup_hash=""
fi
# ── 读取强制重装门禁 ──────────────────────────────────
force_since=""
force_since=$(read_version_meta "FORCE_REINSTALL_SINCE")
# ── 读取当前版本 ──────────────────────────────────────
current_version=""
current_version=$(read_version_meta "VERSION")
if [ -z "$current_version" ]; then
echo "错误: VERSION 文件中未找到 VERSION"
exit 1
fi
# ── 计算当前指纹 ──────────────────────────────────────
current_vendor_state=$(hash_tree_metadata "$CURRENT_DIR/vendor")
current_requirements_hash=$(md5sum "$CURRENT_DIR/requirements.txt" 2>/dev/null | cut -d' ' -f1)
current_setup_hash=$( (hash_files_under "$CURRENT_DIR/script"; hash_files "$CURRENT_DIR/setup.sh"; printf '%s\n%s\n%s\n' "$SCRIPT_DIR" "$VIV_SDK_PATH" "$NETRANS_PYTHON") | md5sum | cut -d' ' -f1)
# ── 判断是否需要全量重装 ──────────────────────────────
need_full_reinstall=false
if [ -z "$installed_version" ]; then
need_full_reinstall=true
elif [ -n "$force_since" ] && [ "$installed_version" != "$force_since" ]; then
# 版本比较:如果 installed_version < force_since需要全量重装
# 使用 sort -V 做版本号排序比较
if printf '%s\n%s\n' "$installed_version" "$force_since" | sort -V | head -1 | grep -q "^$installed_version$" && \
[ "$installed_version" != "$force_since" ]; then
echo ""
echo "⚠ 当前版本 $installed_version < 强制重装门禁 $force_since,将执行全量安装"
need_full_reinstall=true
fi
fi
if $need_full_reinstall; then
# 重置所有指纹,强制全量安装
vendor_state=""
requirements_hash=""
setup_hash=""
fi
# ── 判断各部件的安装需求 ──────────────────────────────
need_deps=false
need_acuity=false
need_setup_config=false
if [ "$vendor_state" != "$current_vendor_state" ]; then
need_acuity=true
fi
if [ "$requirements_hash" != "$current_requirements_hash" ]; then
need_deps=true
fi
if [ "$setup_hash" != "$current_setup_hash" ]; then
need_setup_config=true
fi
# ── 步骤 1: 安装 Python 依赖 ──────────────────────────
echo ""
if $need_deps || $need_full_reinstall; then
echo "[1/4] 安装 Python 依赖..."
$PIP_CMD install -r "$CURRENT_DIR/requirements.txt"
echo "✓ 依赖安装完成"
else
echo "[1/4] Python 依赖 (跳过,无变化)"
fi
# ── 步骤 2: 安装 acuity ───────────────────────────────
echo ""
if $need_acuity || $need_full_reinstall; then
echo "[2/4] 安装 acuity..."
if [ -n "$ACUITY_WHL" ] && [ -f "$ACUITY_WHL" ]; then
$PIP_CMD install "$ACUITY_WHL" --no-deps --force-reinstall
echo "✓ acuity 安装完成"
else
echo "✗ 未找到 acuity whl 文件: $CURRENT_DIR/vendor/acuity-*.whl"
exit 1
fi
else
echo "[2/4] acuity (跳过vendor 无变化)"
fi
# ── 步骤 3: 安装 netrans ──────────────────────────────
echo ""
echo "[3/4] 安装 netrans (pip install -e)..."
$PIP_CMD install -e "$CURRENT_DIR"
echo "✓ netrans 安装完成"
# ── 步骤 4: 配置环境变量 ──────────────────────────────
echo ""
if $need_setup_config || $need_full_reinstall; then
echo "[4/4] 配置环境变量..."
write_shell_env "$BASHRC"
echo " ✓ PATH、VIV_SDK_PATH 和 NETRANS_PYTHON 已写入 $BASHRC"
else
echo "[4/4] 环境变量 (跳过,无变化)"
fi
# ── 写入安装状态快照 ──────────────────────────────────
cat > "$INSTALL_STATE" << EOF
# Netrans 安装状态快照(自动生成,勿手动编辑)
installed_version=$current_version
vendor_state=$current_vendor_state
requirements_hash=$current_requirements_hash
setup_hash=$current_setup_hash
EOF
echo ""
echo "========================================"
echo " 安装完成!"
echo "========================================"
echo ""
if $need_setup_config || $need_full_reinstall; then
echo "请执行以下命令使配置生效:"
echo " source ~/.bashrc"
echo ""
fi
echo "验证安装:"
echo " python -c \"import netrans; print(netrans.__version__)\""
echo " netrans --help"