Files
homeutils/docs/superpowers/specs/2026-08-03-cross-platform-jar-paths-design.md
T
2026-08-03 14:47:04 +08:00

85 lines
5.4 KiB
Markdown
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.
# 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=<path>`;
2. 环境变量 `WORKUTILS_HOME=<path>`;
3. JVM `user.dir`。
空白值视为未设置。最终路径转换为绝对、规范化的 `Path`,但不要求目录预先存在,也不展开 `~`。`ApplicationPaths` 提供根目录及分段 `resolve(...)` 能力,使调用方不再自行读取系统属性或拼接分隔符。
`WorkUtilsProperties` 仍接受配置文件中的绝对路径;相对路径统一相对于应用根目录解析。未配置导出目录时使用 `<home>/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" <project>`。
- 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` 产物,无自动数据迁移。