#!/usr/bin/env bash # local_test.sh —— 一键构建并运行【release】版 macOS 客户端,连真实节点做端到端验证。 # # 用真正的 release 包(不是 dev 模拟),前台运行以便直接看内核(sing-box)日志。 # 改完代码直接跑此脚本即可。 # # bash scripts/local_test.sh # 构建 release 并运行 # bash scripts/local_test.sh --no-build # 跳过构建,直接跑上次的产物(快速重跑) # # 可选环境变量: # PANGOLIN_API_URL 控制面地址(默认连 racknerd 节点) # SINGBOX_BIN sing-box 路径(默认 brew 的 /opt/homebrew/bin/sing-box) # # 前置:flutter、sing-box(brew install sing-box)、已在 Xcode 配好签名团队。 # TUN 需 root → 脚本会装一条 NOPASSWD sudoers(一次性,可能让你输一次电脑密码)。 # 正式版会用 SMJobBless 特权 Helper 取代 sudo(BACKLOG-11D-HELPER)。 set -euo pipefail REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" CLIENT="$REPO_ROOT/client" API_URL="${PANGOLIN_API_URL:-http://107.172.55.251:8080}" SINGBOX="${SINGBOX_BIN:-/opt/homebrew/bin/sing-box}" NO_BUILD=0 [ "${1:-}" = "--no-build" ] && NO_BUILD=1 command -v flutter >/dev/null 2>&1 || { echo "✗ 需要 flutter"; exit 1; } [ -x "$SINGBOX" ] || { echo "✗ 找不到 sing-box: $SINGBOX(brew install sing-box,或设 SINGBOX_BIN)"; exit 1; } # ── 1. TUN 免密 sudoers(已生效则跳过,避免反复要密码)───────────────────────── echo "==> [1/3] sing-box 免密 sudo(TUN 需 root)" if sudo -n "$SINGBOX" version >/dev/null 2>&1; then echo " 已生效,跳过(无需密码)" else SUDO_FILE=/etc/sudoers.d/pangolin-singbox WANT="$(whoami) ALL=(root) NOPASSWD: $SINGBOX" TMP="$(mktemp)" printf '%s\n' "$WANT" > "$TMP" if sudo visudo -cf "$TMP" >/dev/null 2>&1; then sudo install -m 440 -o root -g wheel "$TMP" "$SUDO_FILE" echo " 已写入 $SUDO_FILE: $WANT" else echo "✗ sudoers 语法校验失败"; rm -f "$TMP"; exit 1 fi rm -f "$TMP" fi # ── 2. 构建 release(--no-build 跳过,直接跑上次产物)───────────────────────── if [ "$NO_BUILD" = "1" ]; then echo "==> [2/3] 跳过构建(--no-build)" else echo "==> [2/3] flutter build macos --release (API=$API_URL)" ( cd "$CLIENT" && flutter build macos --release --dart-define=PANGOLIN_API_URL="$API_URL" ) fi APP="$(ls -d "$CLIENT"/build/macos/Build/Products/Release/*.app 2>/dev/null | head -1)" [ -n "$APP" ] || { echo "✗ 未找到构建产物 .app"; exit 1; } EXE="$APP/Contents/MacOS/$(basename "$APP" .app)" # ── 3. 前台运行(日志直出)──────────────────────────────────────────────────── echo "==> [3/3] 运行 release 包(前台,日志直出;Ctrl+C 退出)" echo " app : $APP" echo " 内核: 客户端会解析到 $SINGBOX(已加进默认查找路径)" echo " 连上后另开终端验证出口: curl https://api.ipify.org → 期望 ${API_URL#http://}" echo "------------------------------------------------------------------" exec "$EXE"