Constraint: macOS double-click launch must keep one Terminal window alive Rejected: LaunchAgent | hides process ownership and complicates safe cleanup Confidence: high Scope-risk: narrow Directive: Keep cleanup scoped to processes started by run.command Tested: Spec self-review for placeholders, contradictions, ambiguity, and scope Not-tested: Launcher implementation pending written-spec review
4.6 KiB
4.6 KiB
run.command 一键启动器设计
日期:2026-07-15
状态:用户已确认设计方向,等待书面规格复核
目标
在 macOS Finder 中双击项目根目录的 run.command,用一个持续打开的终端窗口启动并监督当前 ERP 主链路:
- Spring Boot 单体应用监听
8091,同时提供 Vue 前端和/api/oa/*后端。 - ngrok 固定域名
https://resonant-elated-launder.ngrok-free.dev转发到8091。 - 两项服务就绪后自动打开公网地址。
- 用户按
Ctrl+C或关闭终端时,只停止本次脚本启动的进程。
不启动已弃用的 OFBiz、独立 Vite 开发服务器、PostgreSQL 或 nginx;当前可交付预览已包含在 Spring Boot JAR 中。
启动体验
- 脚本以自身所在目录作为项目根目录,不依赖 Finder/Terminal 的当前工作目录。
- 终端逐步显示“环境检查、后端启动、ngrok 启动、公网验证、运行中”。
- 后端通常约 15 秒就绪;脚本按真实 HTTP 状态等待,不使用固定时长假定成功。
- 成功后显示本地地址、公网地址、日志路径和停止方法,并调用 macOS
open打开公网地址。 - 终端保持运行并监控服务;任一由脚本启动的子进程意外退出时,脚本报告错误并输出对应日志末尾。
组件与流程
1. 环境与路径
- 项目根目录:由
run.command的绝对路径推导。 - 后端工作目录:固定为
<项目>/oa-backend,确保相对数据源./data/oa.db始终指向oa-backend/data/oa.db。 - Java:优先使用项目内
.jdks/jdk-17.0.19+10/Contents/Home/bin/java。 - JAR:
oa-backend/build/libs/oa-backend-0.1.0.jar。 - ngrok:优先使用
$HOME/bin/ngrok,否则回退到PATH中的ngrok。 - 日志:写入
${TMPDIR:-/tmp}/kaidi-erp-run/,不污染 Git 工作区。
缺少 Java、JAR、ngrok、curl、lsof 或 python3 时立即给出可操作错误并退出。
2. 后端复用与启动
- 若
8091无监听进程,脚本从oa-backend目录启动 Java,并记录为“本脚本拥有”。 - 若
8091已监听,脚本请求根路径并核对页面标题“凯迪协同办公平台”:匹配则复用;不匹配则报端口冲突,不杀进程。 - 启动后最多等待 60 秒,要求首页 HTTP 200 且登录接口能返回标准 JSON;超时或进程提前退出时显示后端日志末尾。
3. ngrok 复用与启动
- 查询本地 ngrok API
127.0.0.1:4040/api/tunnels。 - 若已有固定公网域名且目标为
http://localhost:8091,直接复用,不再启动第二个 ngrok。 - 若
4040被占用但不存在正确隧道,安全报错,不覆盖现有隧道。 - 否则启动
ngrok http --url=resonant-elated-launder.ngrok-free.dev 8091,记录为“本脚本拥有”,最多等待 30 秒确认隧道登记成功。
4. 公网验证与浏览器
- 使用
ngrok-skip-browser-warning: true请求公网首页,必须返回 HTTP 200 且标题正确。 - 验证成功后自动打开公网地址。
- 环境变量
ERP_RUN_NO_OPEN=1可禁止自动打开,供测试或无界面环境使用。
5. 生命周期与清理
INT、TERM、EXIT使用同一清理函数。- 只向脚本保存的 Java/ngrok PID 发送
TERM,等待短时间后才对仍未退出的自有 PID 使用KILL。 - 复用的既有服务 PID 不写入“自有 PID”,因此
Ctrl+C不会误杀它们。 - 运行阶段周期性检查本地首页和公网隧道;异常时提示并保留日志证据。
可测试性
脚本使用 Bash 函数组织,并仅在直接执行时进入 main;测试可 source run.command 后单独验证函数。
新增 tests/run-command.test.sh,覆盖:
bash -n run.command语法检查。- 脚本从任意当前目录都能解析正确项目根目录。
- 已存在且健康的
8091服务会被复用。 - 非本项目进程占用
8091时返回错误且不会发送终止信号。 - 清理函数只停止记录为本脚本启动的 PID,不停止外部 PID。
ERP_RUN_NO_OPEN=1时不调用浏览器。- 实机冒烟:运行启动器,确认本地首页、公网首页、登录和受保护业务接口均成功;随后
Ctrl+C验证自有进程退出。
验收标准
- Finder 双击一次即可完成后端、ngrok、公网验证和浏览器打开。
- 重复双击不会产生第二个 Java/ngrok,也不会杀死已运行实例。
- 成功路径明确显示两个地址和
Ctrl+C停止说明。 - 失败路径在 60 秒内结束等待,说明失败阶段并展示相关日志。
run.command与测试脚本具有可执行权限,Shell 回归测试全部通过。