fix(server): worktree 启动时 ECAT_DIR 回指主检出 tools/ecat
从 .worktrees/<slug> 跑 esp32_server 时 join(BASE_DIR,'..','ecat') 会拼成 .worktrees/ecat,找不到 ecat_native.exe。先走出 .worktrees 再取兄弟目录。
This commit is contained in:
+15
-1
@@ -157,7 +157,21 @@ g_ecat_port = None # 记住上次探到的端口, 避免每次请求都从 809
|
||||
# 2) 拉起时**必须带 --parent-pid**: 让 native 在本服务退出后自我了断,
|
||||
# 不留孤儿进程占着 Npcap 适配器和端口。
|
||||
# 3) 不再需要 venv/pythonw —— 单文件 exe, 无 Python 运行时依赖。
|
||||
ECAT_DIR = os.path.normpath(os.path.join(BASE_DIR, "..", "ecat"))
|
||||
def _resolve_ecat_dir(base_dir):
|
||||
"""定位 tools/ecat(ecat_native.exe 的仓库,与本仓库平级)。
|
||||
|
||||
从 git worktree(.../tools/ESP32/.worktrees/<slug>)启动时,BASE_DIR 的
|
||||
上一级是 .worktrees 而不是 tools,直接 join("..","ecat") 会拼成
|
||||
.../ESP32/.worktrees/ecat,找不到 exe。先走回主检出再取兄弟目录。
|
||||
"""
|
||||
d = os.path.abspath(base_dir)
|
||||
parent = os.path.dirname(d)
|
||||
if os.path.basename(parent) == ".worktrees":
|
||||
d = os.path.dirname(parent) # → .../tools/ESP32 主检出
|
||||
return os.path.normpath(os.path.join(d, "..", "ecat"))
|
||||
|
||||
|
||||
ECAT_DIR = _resolve_ecat_dir(BASE_DIR)
|
||||
ECAT_NATIVE_EXE = os.path.join(ECAT_DIR, "build_native", "ecat_native.exe")
|
||||
g_ecat_child = None # 由本服务拉起的 ecat 服务子进程(复用已有实例时为 None)
|
||||
g_ecat_log_fp = None # native stdout 落盘句柄(见 _ecat_autostart 内注释)
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 从 git worktree 启动 esp32_server 时,ECAT_DIR 必须指回主检出的
|
||||
* tools/ecat,而不是 .../ESP32/.worktrees/ecat。
|
||||
* 复刻 _resolve_ecat_dir 的纯路径逻辑(无 DOM/无网络)。
|
||||
*/
|
||||
import assert from "node:assert/strict";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
/** 与 esp32_server._resolve_ecat_dir 同构(JS 侧只测路径形状)。 */
|
||||
function resolveEcatDir(baseDir) {
|
||||
let d = path.resolve(baseDir);
|
||||
const parent = path.dirname(d);
|
||||
if (path.basename(parent) === ".worktrees") {
|
||||
d = path.dirname(parent);
|
||||
}
|
||||
return path.normalize(path.join(d, "..", "ecat"));
|
||||
}
|
||||
|
||||
let failed = 0;
|
||||
function check(name, fn) {
|
||||
try {
|
||||
fn();
|
||||
console.log(" ✓", name);
|
||||
} catch (e) {
|
||||
failed++;
|
||||
console.log(" ✗", name, "—", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("[worktree ECAT_DIR]");
|
||||
|
||||
check("主检出 BASE_DIR → 兄弟 tools/ecat", () => {
|
||||
const base = path.resolve("G:/Robot_v2/DCU/tools/ESP32");
|
||||
const got = resolveEcatDir(base);
|
||||
assert.equal(got, path.resolve("G:/Robot_v2/DCU/tools/ecat"), got);
|
||||
});
|
||||
|
||||
check("worktree BASE_DIR → 仍指主检出的 tools/ecat", () => {
|
||||
const base = path.resolve("G:/Robot_v2/DCU/tools/ESP32/.worktrees/device-link");
|
||||
const got = resolveEcatDir(base);
|
||||
assert.equal(got, path.resolve("G:/Robot_v2/DCU/tools/ecat"), got);
|
||||
});
|
||||
|
||||
check("嵌套 slug 也走 .worktrees 父级", () => {
|
||||
const base = path.resolve("G:/x/tools/ESP32/.worktrees/foo-bar");
|
||||
const got = resolveEcatDir(base);
|
||||
assert.equal(got, path.resolve("G:/x/tools/ecat"), got);
|
||||
});
|
||||
|
||||
/* BASE_DIR 恒为 esp32_server.py 所在目录;普通主检出已在第一项覆盖。 */
|
||||
|
||||
if (failed) {
|
||||
console.log(`失败 ${failed} 项`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log("通过 3 项,失败 0 项");
|
||||
Reference in New Issue
Block a user