diff --git a/docs/superpowers/specs/2026-08-03-cross-platform-jar-paths-design.md b/docs/superpowers/specs/2026-08-03-cross-platform-jar-paths-design.md new file mode 100644 index 0000000..c24ad5e --- /dev/null +++ b/docs/superpowers/specs/2026-08-03-cross-platform-jar-paths-design.md @@ -0,0 +1,84 @@ +# WorkUtils 跨平台 JAR 与路径设计 + +## 背景 + +WorkUtils 当前可以在 Windows 上运行,但构建和运行路径仍包含 Windows 假设:POM 将编译器固定到 `C:\Program Files\Java\jdk-17`,Launch4j 在所有平台参与 `package`,运行目录依赖散落的 `user.dir`,部分路径通过带 `/` 的字符串拼接,Git Review 默认只查找 Windows IDEA 命令。 + +这会造成两类问题:Maven 与编译器可能使用不同 JDK(当前基线中 Maven 由 Java 8 启动、源码由 JDK 17 编译,测试 JVM因此无法加载 class),以及同一 JAR 在 macOS/Linux 上启动时无法稳定找到数据、导出和配置目录。 + +## 目标与范围 + +- 使用标准 JDK 17 在 Windows、macOS、Linux 构建并运行 Spring Boot JAR。 +- 统一应用运行目录,数据、导出、历史记录和插件配置使用同一解析规则。 +- 将业务路径组合改为 `Path` 分段解析,支持空格、中文和平台分隔符。 +- Git Review 在三个桌面平台上提供合理的 IntelliJ IDEA 默认启动方式。 +- Windows 现有默认数据位置保持不变,不自动迁移用户数据。 + +明确不包含:手机 UI 自动化插件的兼容性修改、`.app`/`.dmg` 等原生安装包、数据迁移、Git 项目内容路径的语义变更。 + +## 运行目录 + +新增单一的运行目录解析组件 `ApplicationPaths`。应用根目录按以下优先级确定: + +1. JVM 参数 `-Dworkutils.home=`; +2. 环境变量 `WORKUTILS_HOME=`; +3. JVM `user.dir`。 + +空白值视为未设置。最终路径转换为绝对、规范化的 `Path`,但不要求目录预先存在,也不展开 `~`。`ApplicationPaths` 提供根目录及分段 `resolve(...)` 能力,使调用方不再自行读取系统属性或拼接分隔符。 + +`WorkUtilsProperties` 仍接受配置文件中的绝对路径;相对路径统一相对于应用根目录解析。未配置导出目录时使用 `/export`。`WorkUtilsApplication` 的启动诊断、Git Review 数据目录、历史记录和插件配置也从该入口获取路径。 + +默认回退仍是 `user.dir`,因此 Windows 用户未设置新参数时不会改变原有数据位置。实现不扫描或移动旧目录。 + +## 构建与启动 + +默认 Maven 构建要求运行 Maven 的 JVM 为 JDK 17,并使用 `maven-compiler-plugin` 的 `release=17`。删除硬编码 JDK 路径、外部 `javac`、编译器 fork 和冗余 compilerVersion,确保编译与测试使用同一 JDK。 + +Launch4j 和 `start.bat` 复制仅放入 Windows 自动激活 profile。普通 `mvn package` 在 macOS/Linux 上只生成可执行 Spring Boot JAR及通用启动脚本,不尝试生成 `.exe`。 + +新增 `scripts/start.sh`,脚本: + +- 从脚本自身位置定位发布根目录,而不是依赖调用者当前目录; +- 检查 `java` 可用且主版本至少为 17; +- 查找对应的 WorkUtils JAR并以参数数组启动,正确处理空格和中文路径; +- 显式传递 `-Dworkutils.home=<发布根目录>`,让脚本启动结果稳定; +- 将用户追加参数原样交给 Java 进程。 + +直接执行 `java -jar` 时仍按统一优先级解析根目录。 + +## 路径组合 + +运行路径不再使用 `String.format("%s/%s", ...)`、字符串 `+ "/..."` 或在一个 `resolve` 参数中嵌入平台分隔符。源码目录等固定层级使用 `Path.of("src", "main", "java")` 或连续 `resolve`。 + +仅修改实际文件系统操作。URL、正则表达式、展示文本以及手机 UI 自动化插件中的平台逻辑不在本次批量替换范围,避免改变业务语义。 + +## IntelliJ IDEA 启动 + +Git Review 将命令解析与进程执行分离,便于模拟操作系统测试。用户显式配置的 IDEA 命令始终优先,且通过 `ProcessBuilder` 参数列表执行,不拼 shell 字符串。 + +- Windows 默认依次尝试 `idea64.exe`、`idea.bat`、`idea`;批处理命令继续通过 `cmd.exe /c` 执行。 +- macOS 默认尝试 `idea`,不可用时回退 `open -a "IntelliJ IDEA" `。 +- Linux 默认尝试 `idea`。 + +界面默认文案不再固定显示 `idea64.exe`,改为平台中性的“自动检测”;现有已保存的自定义命令保持有效。 + +## 测试策略 + +先增加失败测试,再实施最小改动: + +- `ApplicationPaths` 覆盖 JVM 参数、环境变量、`user.dir` 的优先级、空白值、相对路径、空格和中文路径。 +- `WorkUtilsProperties` 验证所有相对数据/导出路径都基于统一根目录,绝对路径不被改写。 +- IDEA 命令解析测试模拟 Windows、macOS、Linux,验证自定义命令、默认候选和 macOS fallback。 +- 路径生成与固定源码目录测试验证使用平台 `Path` 后的结果。 +- 构建测试/检查验证默认 POM 不含 Windows JDK 路径,Launch4j 只属于 Windows profile,`start.sh` 被纳入发布产物。 + +最终运行聚焦测试、JDK 17 Maven 全量 `clean test`、`package`、`git diff --check`。当前环境只能实际执行 Windows 构建;macOS/Linux 行为由无平台副作用的命令解析和路径测试覆盖。 + +## 验收标准 + +- JDK 17 执行 `mvn clean package` 可生成并运行 Spring Boot JAR。 +- 非 Windows 默认构建不执行 Launch4j。 +- 应用根目录优先级明确,所有纳入范围的相对运行路径保持一致。 +- 路径包含空格、中文时不因字符串分隔符或 shell 拼接失败。 +- Git Review 在 macOS/Linux 不再默认依赖 `.exe`。 +- Mobile UI Automation 源码无改动,无 `.app`/`.dmg` 产物,无自动数据迁移。