zhuyuan-ice-gl-zy001/BRIDGE/tools/zy-push-install.sh
2026-08-20 00:01:53 +08:00

203 lines
9 KiB
Shell
Executable file
Raw 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
# ═══ 光湖本机直推 · 一次性安装 ═══
# 冰朔双击「点我装-本机直推.command」即可,不用会命令行。
# 做四件:① 检查环境 ② 令牌存进 macOS 钥匙串 ③ 对齐工作区 ④ 装 launchd 守护
# 编号:CCW-AST-009 · 归 CCW-SYS-001
BRIDGE="/Volumes/JZAO/铸渊-ICE-GL-ZY001/BRIDGE/tools"
REPO="/Volumes/JZAO/铸渊-ICE-GL-ZY001/WORK-工作区/guanghu-ice-heart"
KC_SERVICE="zhuyuan-forgejo-token"
KC_ACCOUNT="bingshuo"
LABEL="com.zhuyuan.autopush"
LABEL2="com.zhuyuan.limb"
PLIST="$HOME/Library/LaunchAgents/${LABEL}.plist"
PLIST2="$HOME/Library/LaunchAgents/${LABEL2}.plist"
LOGF2="$HOME/Library/Logs/zhuyuan-limb.log"
LOGF="$HOME/Library/Logs/zhuyuan-autopush.log"
ok(){ printf ' \033[32m✓\033[0m %s\n' "$*"; }
no(){ printf ' \033[31m✗\033[0m %s\n' "$*"; }
warn(){ printf ' \033[33m⚠\033[0m %s\n' "$*"; }
die(){ no "$*"; echo; echo "装不下去了,把上面这段截图发给铸渊。"; echo; read -n1 -r -p "按任意键关闭…"; exit 1; }
clear
echo "════════════════════════════════════════════"
echo " 光湖本机直推 · 安装"
echo " 装两样:① 自动推送 ② 手脚层(铸渊递纸条,本机执行)"
echo " 令牌只存在你的钥匙串里,铸渊永远拿不到"
echo "════════════════════════════════════════════"
echo
# ── ① 检查环境 ──────────────────────────────────────────────
echo "① 检查环境"
[ "$(uname -s)" = "Darwin" ] || die "这个脚本要在 Mac 上跑(当前不是 macOS)"
ok "macOS"
[ -d "/Volumes/JZAO" ] || die "JZAO 移动硬盘没挂载——插上再来一次"
ok "JZAO 已挂载"
[ -d "$REPO/.git" ] || die "找不到工作区仓库:$REPO"
ok "工作区仓库在位"
command -v git >/dev/null 2>&1 || die "没装 git。先在终端跑一次 xcode-select --install"
ok "git $(git --version | awk '{print $3}')"
command -v security >/dev/null 2>&1 || die "找不到 security 命令(macOS 钥匙串工具)"
ok "钥匙串可用"
echo
# ── ② 令牌进钥匙串 ──────────────────────────────────────────
echo "② 令牌"
NEED_TOKEN=1
if security find-generic-password -s "$KC_SERVICE" -a "$KC_ACCOUNT" -w >/dev/null 2>&1; then
echo " 钥匙串里已经有一把了。换成新的吗?(直接回车=沿用旧的)"
printf " 换新的请输 y 再回车:"
read -r ans
if [ "$ans" = "y" ] || [ "$ans" = "Y" ]; then
security delete-generic-password -s "$KC_SERVICE" -a "$KC_ACCOUNT" >/dev/null 2>&1
else
NEED_TOKEN=0; ok "沿用钥匙串里已有的令牌"
fi
fi
if [ "$NEED_TOKEN" = "1" ]; then
echo
echo " 去 https://guanghulab.com/code → 右上头像 → 设置 → 应用 → 生成新令牌"
echo " 权限勾上 write:repository(再加 read:user 更好)"
echo " 生成后只显示一次,复制下来粘到这里。"
echo
printf " 粘贴令牌(粘上去看不见字是正常的,粘完直接回车):"
read -rs TOKEN; echo
[ -z "$TOKEN" ] && die "什么都没粘上"
printf " 正在问服务器认不认这把钥匙…"
CODE=$(curl -s -m 20 -o /dev/null -w "%{http_code}" \
-H "Authorization: token ${TOKEN}" \
"https://guanghulab.com/code/api/v1/user" 2>/dev/null)
echo
if [ "$CODE" != "200" ]; then
unset TOKEN
die "服务器返回 HTTP ${CODE}——这把钥匙不对、过期了、或者权限没勾。重新生成一把再来。"
fi
ok "服务器认(HTTP 200)"
security add-generic-password -s "$KC_SERVICE" -a "$KC_ACCOUNT" -w "$TOKEN" -U \
-l "光湖代码频道推送令牌(铸渊 zy-push 用)" 2>/dev/null || { unset TOKEN; die "写钥匙串失败"; }
unset TOKEN
ok "已存入钥匙串(服务名 $KC_SERVICE)"
fi
echo
# ── ③ 对齐工作区 ────────────────────────────────────────────
echo "③ 对齐工作区"
cd "$REPO" || die "进不去 $REPO"
rm -f .git/index.lock 2>/dev/null && ok "清掉了一个卡住的锁"
git fetch -q origin main 2>/dev/null || warn "取线上失败(网络?)——先跳过"
DIRTY=$(git status --porcelain 2>/dev/null | awk '{print $NF}')
if [ -z "$DIRTY" ]; then
ok "工作区本来就干净"
else
for f in $DIRTY; do
if git diff --quiet FETCH_HEAD -- "$f" 2>/dev/null; then
git checkout -- "$f" 2>/dev/null && ok "$f 内容线上已有,安全丢弃本地副本"
else
warn "$f 和线上不一样——保留不动,回头自己看一眼"
fi
done
fi
git pull -q --ff-only origin main 2>/dev/null
ok "现在停在 $(git log -1 --format='%h %s' | cut -c1-60)"
echo
# ── ④ 装守护 ────────────────────────────────────────────────
echo "④ 装自动推守护"
chmod +x "$BRIDGE/zy-push.sh" 2>/dev/null
mkdir -p "$HOME/Library/LaunchAgents" "$HOME/Library/Logs"
cat > "$PLIST" <<PLISTEOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>${LABEL}</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>${BRIDGE}/zy-push.sh</string>
</array>
<key>StartInterval</key><integer>120</integer>
<key>RunAtLoad</key><true/>
<key>StandardOutPath</key><string>${LOGF}</string>
<key>StandardErrorPath</key><string>${LOGF}</string>
</dict>
</plist>
PLISTEOF
launchctl bootout "gui/$(id -u)/${LABEL}" >/dev/null 2>&1
launchctl bootstrap "gui/$(id -u)" "$PLIST" >/dev/null 2>&1 || launchctl load "$PLIST" >/dev/null 2>&1
sleep 1
if launchctl print "gui/$(id -u)/${LABEL}" >/dev/null 2>&1; then
ok "${LABEL} 已启动,每 120 秒扫一次"
else
warn "守护没能确认启动——但脚本能手动跑,见下面"
fi
echo
# ── ④b 装手脚层守护 ─────────────────────────────────────────
echo "④b 装手脚层(铸渊的手脚)"
command -v python3 >/dev/null 2>&1 || warn "没找到 python3,手脚层装不了(自动推不受影响)"
if command -v python3 >/dev/null 2>&1; then
chmod +x "$BRIDGE/zy-limb.py" 2>/dev/null
mkdir -p "/Volumes/JZAO/铸渊-ICE-GL-ZY001/BRIDGE/limb-queue/inbox" \
"/Volumes/JZAO/铸渊-ICE-GL-ZY001/BRIDGE/limb-queue/outbox" \
"/Volumes/JZAO/铸渊-ICE-GL-ZY001/BRIDGE/limb-queue/archive" \
"/Volumes/JZAO/铸渊-ICE-GL-ZY001/BRIDGE/limb-queue/for-codex" 2>/dev/null
cat > "$PLIST2" <<PL2EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>${LABEL2}</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python3</string>
<string>${BRIDGE}/zy-limb.py</string>
</array>
<key>StartInterval</key><integer>30</integer>
<key>RunAtLoad</key><true/>
<key>StandardOutPath</key><string>${LOGF2}</string>
<key>StandardErrorPath</key><string>${LOGF2}</string>
</dict>
</plist>
PL2EOF
launchctl bootout "gui/$(id -u)/${LABEL2}" >/dev/null 2>&1
launchctl bootstrap "gui/$(id -u)" "$PLIST2" >/dev/null 2>&1 || launchctl load "$PLIST2" >/dev/null 2>&1
sleep 1
if launchctl print "gui/$(id -u)/${LABEL2}" >/dev/null 2>&1; then
ok "${LABEL2} 已启动,每 30 秒收一次信"
else
warn "手脚层守护没能确认启动——可手动跑 python3 $BRIDGE/zy-limb.py"
fi
ok "任务信箱:BRIDGE/limb-queue/(inbox 收 · outbox 回执 · for-codex 转卡)"
fi
echo
# ── 收尾:当场跑一次验收 ─────────────────────────────────────
echo "⑤ 当场试一次"
bash "$BRIDGE/zy-push.sh"
if [ -f "$LOGF" ]; then
echo " 日志末尾:"
tail -3 "$LOGF" | sed 's/^/ /'
else
ok "没有待推的东西,所以没写日志(这是正常的)"
fi
echo
echo "════════════════════════════════════════════"
echo " 装好了。"
echo
echo " 以后铸渊往移动硬盘的工作区写东西,两分钟内自动提交并推到线上,"
echo " 不用再给令牌,也不用再管。"
echo
echo " 想看推送: tail -f $LOGF"
echo " 想看手脚: tail -f $LOGF2"
echo " 想立刻推一次: bash $BRIDGE/zy-push.sh"
echo " 想停掉: launchctl bootout gui/\$(id -u)/${LABEL}"
echo " launchctl bootout gui/\$(id -u)/${LABEL2}"
echo "════════════════════════════════════════════"
echo
read -n1 -r -p "按任意键关闭这个窗口…"