Files
gplan-2/tools/gate_platform.sh

98 lines
4.1 KiB
Bash
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.
#!/usr/bin/env bash
# 闸件跨平台件——平台探测/路径形式/带超时执行/Godot 孤儿清杀,Git Bash 与 macOS/Linux 双栖。
# 单点定义:run_all_gates.sh / probe_gate.sh / render_gate.sh / golden_baseline_refresh.sh 共用(source 引入)。
# 纪律:闸脚本禁裸调 coreutils timeout 与 Windows 专用件(taskkill/PowerShell/ps -W/tasklist/cygpath)——
# 一律走本件封装;macOS 为 BSD 工具链(无 coreutils timeout,sed/stat 语义不同),裸调必断
# (2026-11-03 远端 CI 迁移裁决:runner=Mac 本机 host 模式,禁再增 Windows 专用直调)。
# 平台判定以 uname 为准(Git Bash=MINGW*,macOS=Darwin,Linux=Linux)。
gate_is_win() {
case "$(uname -s 2>/dev/null)" in
MINGW*|MSYS*|CYGWIN*|Windows_NT) return 0 ;;
*) return 1 ;;
esac
}
# Godot --path 接受的项目路径形式:Windows 需 cygpath -m 混合斜杠,其他平台原样。
gate_game_path() {
if gate_is_win; then cygpath -m "$1"; else printf '%s' "$1"; fi
}
# 杀整棵进程树(<pid>)——递归杀子进程后杀本进程。macOS/Linux 走 pgrep -P;
# Windows 侧 MSYS kill 对其可见进程有效,带 wrapper 树的场景仍由调用方原 taskkill /T 逻辑负责。
gate_kill_tree() {
local p c
kill -9 "$1" 2>/dev/null
for c in $(pgrep -P "$1" 2>/dev/null); do gate_kill_tree "$c"; done
}
# 带超时执行(coreutils timeout 的纯 bash 替代,双平台同语义):
# gate_run_timeout <秒> <日志路径> <命令...>
# 命令输出重定向到日志;退出码=命令退出码,超时=124(与 coreutils 语义一致,判据与既有闸一致)。
# 实现=后台启动+守卫落标志文件(probe_gate run_suite 同款手法:taskkill 强杀后 wait 报 0 的
# 假绿以标志文件纠偏);超时先杀整树再回 124。
gate_run_timeout() {
local t="$1" log="$2"; shift 2
local kf
kf="$(mktemp "${TMPDIR:-/tmp}/gatetime_XXXXXX")"
"$@" >"$log" 2>&1 &
local pid=$!
( sleep "$t" 2>/dev/null
touch "$kf"
gate_kill_tree "$pid"
true ) &
local guard=$!
wait "$pid"; local st=$?
kill "$guard" 2>/dev/null; wait "$guard" 2>/dev/null
if [ -f "$kf" ]; then
gate_kill_tree "$pid"
st=124
fi
rm -f "$kf"
return "$st"
}
# 列命令行含 <game路径> 的 Godot 进程 PID(孤儿清杀与批末残留清点共用)。
# Windows:PowerShell WMI 按进程名+命令行匹配(console wrapper+真引擎都算);
# macOS/Linux:ps 全表按「可执行含 godot+命令行含本 game 路径」过滤(ps 两平台同形)。
gate_orphans() {
local gp="$1"
if gate_is_win; then
local tmpd tmpf
tmpd="$(mktemp -d "${TMPDIR:-/tmp}/gateorph_XXXXXX")" # macOS BSD mktemp 禁 X 后带后缀(本分支 Windows 专用,模板统一防复用)
tmpf="$tmpd/k.ps1"
local gp_win
gp_win="$(cygpath -m "$gp")"
printf "Get-CimInstance Win32_Process -Filter \"Name like 'Godot%%'\" | Where-Object { \$_.CommandLine -like '*%s*' } | ForEach-Object { \$_.ProcessId }\n" "$gp_win" > "$tmpf"
powershell -NoProfile -ExecutionPolicy Bypass -File "$(cygpath -w "$tmpf")" 2>/dev/null | tr -d '\r'
rm -rf "$tmpd"
else
ps -axo pid=,command= 2>/dev/null | awk -v g="$gp" 'tolower($0) ~ /godot/ && index($0, g) {print $1}'
fi
}
gate_kill_orphans() { # gate_kill_orphans <game路径>
local p
for p in $(gate_orphans "$1"); do
if gate_is_win; then taskkill //F //PID "$p" >/dev/null 2>&1
else kill -9 "$p" 2>/dev/null; fi
done
}
# 全局 Godot 进程计数(其他会话的仅报数不算账——批末残留清点的对照面)。
gate_godot_count_all() {
if gate_is_win; then tasklist 2>/dev/null | grep -ci '^Godot' || true
else ps -axo comm= 2>/dev/null | grep -ci 'godot' || true
fi
}
# golden 基线平台子目录名——渲染基线按平台各存一份(Windows 显卡字形/抗锯齿与 macOS CoreText
# 差异使跨平台逐像素比对必失配,2026-11-03 用户裁:按平台各存基线,平台内部照常严格比对)。
gate_platform_id() {
case "$(uname -s 2>/dev/null)" in
MINGW*|MSYS*|CYGWIN*|Windows_NT) echo "windows" ;;
Darwin) echo "mac" ;;
*) echo "linux" ;;
esac
}