Add Sdkman module for Java/Maven version management#602
Merged
xpf0000 merged 1 commit intoxpf0000:masterfrom Mar 27, 2026
Merged
Add Sdkman module for Java/Maven version management#602xpf0000 merged 1 commit intoxpf0000:masterfrom
xpf0000 merged 1 commit intoxpf0000:masterfrom
Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
sdkman-source - SDKMAN 渠道源集成
需求概述
参考 Homebrew 和 MacPorts 的渠道源实现模式, 新增 SDKMAN (https://sdkman.io) 作为第四个安装渠道源.
SDKMAN 是 JVM 生态专用的版本管理工具, 支持 macOS 和 Linux, 主要为 Java 和 Maven 提供版本安装/卸载/切换能力.
与 brew/port 相比, SDKMAN 不需要 sudo, 安装在用户目录
~/.sdkman/下, Java 支持多 Vendor (Corretto/Temurin/Zulu 等).现状分析
渠道源架构 (brew/port/static)
当前系统支持三种渠道源, 实现模式如下:
Fork 层 (后端):
src/fork/module/<Name>/index.ts中实现brewinfo()/portinfo()方法src/fork/util/Version.ts提供brewInfoJson()/portSearch()/brewSearch()通用函数src/fork/module/Brew/index.ts和MacPorts/index.ts管理 brew/port 自身 (换源/扩展等)src/fork/BaseManager.ts通过 switch-case 注册模块, 动态导入主进程:
src/main/Application.ts的checkBrewOrPort()检测 brew/port 安装状态src/global.d.ts定义ServerType包含BrewCellar,MacPorts等属性global.Server传递给渲染进程渲染进程核心:
src/render/core/Module/Module.ts: 核心类, 包含brew[],port[],static[]三组数据 +fetchBrew/fetchPort/fetchStatic方法src/render/core/Module/ModuleHomebrewItem.ts/ModuleMacportsItem.ts/ModuleStaticItem.ts: 渠道项模型src/render/util/Brew.ts:brewInfo()/portInfo()IPC 桥接函数src/render/store/brew.ts: BrewStore,LibUse管理渠道选择,modules管理模块实例UI 组件:
src/render/components/VersionManager/: 包含 brew/port/static/local 四个子目录index.vue(列表 UI) +setup.ts(组合式 API)setup.ts/setupAll.ts: 管理 libSrc 切换 ('brew' | 'port' | 'static' | 'local')index.vue/all.vue: 顶层组件, 渲染 radio-group 切换和对应子组件Java/Maven 模块当前实现
Java (
src/fork/module/Java/index.ts):brewinfo(): 通过brew search+brewInfoJson获取 jdk/openjdk 列表portinfo(): 通过portSearch搜索^((open)?)jdk([\d\.]*)$fetchAllOnlineVersion(): 从远端获取静态版本列表/Library/Java/JavaVirtualMachines/<name>/Contents/Home/bin/javaMaven (
src/fork/module/Maven/index.ts):brewinfo(): 固定搜索['maven']portinfo(): 搜索^maven\d*$fetchAllOnlineVersion(): 从远端获取静态版本列表AppDir/maven-<version>/bin/mvnJava 页面 (
src/render/components/Java/Index.vue):VersionManager/index.vue, 支持 brew/port/staticVersionManager/all.vue, 支持 local/brew/port/staticSDKMAN 特性 (研究结果)
环境信息:
~/.sdkman/source ~/.sdkman/bin/sdkman-init.sh~/.sdkman/etc/config~/.sdkman/candidates/<candidate>/<version>/~/.sdkman/candidates/<candidate>/current(符号链接)Java 版本列表格式 (
sdk list java):<version>-<dist>, 如21.0.10-tem>>>表示当前使用Maven 版本列表格式 (
sdk list maven):*= 已安装,>= 当前使用安装路径:
~/.sdkman/candidates/java/<identifier>/bin/java~/.sdkman/candidates/maven/<version>/bin/mvn实现方案
推荐方案: CLI 解析 + XTerm 执行
与 brew/port 完全一致的实现模式:
sdk list命令获取版本列表, 解析 CLI 输出sdk install/sdk uninstallsource ~/.sdkman/bin/sdkman-init.sh初始化环境优势: 与现有架构完全一致, 开发成本可控
劣势: CLI 输出解析比 JSON 脆弱, 但 SDKMAN 输出格式已稳定多年
备选方案: REST API
SDKMAN 提供 REST API (
https://api.sdkman.io/2/candidates/java/<platform>/versions/list), 可获取版本列表.但 API 无法反映本地已安装状态, 仍需 CLI 补充. 增加复杂度, 不推荐.
缺失清单
已确认事项
跨平台策略 (参考 Homebrew)
Homebrew 在 Windows 上的三层隔离机制
主进程检测层:
checkBrewOrPort()仅在isMacOS()/isLinux()分支执行global.Server.BrewCellar永远是undefinedisMacOS()分支UI 模板层:
VersionManager/index.vue和all.vue按平台分三个v-if分支static + brew + port(由showBrewLib/showPortLibprops 控制)static + brew(没有 port)title + StaticVM(无 radio-group)Props 控制层: 各模块页面通过
show-brew-lib/show-port-lib控制显示show-brew-lib=true, show-port-lib=trueshow-brew-lib=false, show-port-lib=false(仅 static)SDKMAN 跨平台策略 (对齐 Homebrew)
SDKMAN 支持 macOS + Linux, 不支持 Windows. 与 Homebrew 一致, 但比 MacPorts (仅 macOS) 更广:
主进程检测层:
checkBrewOrPort()在 macOS/Linux 分支添加 SDKMAN 检测~/.sdkman/bin/sdkman-init.sh是否存在global.Server.SdkmanHomeUI 模板层: macOS/Linux 模板分支中添加 SDKMAN radio-button
static + brew + port + sdkmanstatic + brew + sdkmanProps 控制层: 新增
showSdkmanLibprop (默认 false):show-sdkman-lib="true"数据层:
checkSdkmancomputed 依赖window.Server.SdkmanHomecheckBrew逻辑一致)开发步骤
1. 类型定义与检测基础
src/global.d.ts: ServerType 添加SdkmanHome?: string属性src/main/Application.ts:checkBrewOrPort()中添加 SDKMAN 检测逻辑isMacOS()和isLinux()分支内检测~/.sdkman/bin/sdkman-init.shglobal.Server.SdkmanHome = join(homedir, '.sdkman')2. Fork 层 - SDKMAN 管理模块
src/fork/module/Sdkman/index.ts: 新建, 继承 BasecheckInstalled(): 检测 SDKMAN 是否安装listJava(): 执行sdk list java, 解析版本列表listMaven(): 执行sdk list maven, 解析版本列表source ~/.sdkman/bin/sdkman-init.shsrc/fork/util/Version.ts: 添加sdkmanSearch()通用函数*/>标记)src/fork/Fn.ts: 导出sdkmanSearch函数src/fork/BaseManager.ts: 注册 sdkman 模块 (添加Sdkman属性和 switch-case)3. Fork 层 - Java/Maven 添加 sdkmaninfo
src/fork/module/Java/index.ts: 添加sdkmaninfo()方法listJava()或直接解析sdk list java{ name, version, installed, flag: 'sdkman', vendor?, identifier? }~/.sdkman/candidates/java/<identifier>/bin/javasrc/fork/module/Maven/index.ts: 添加sdkmaninfo()方法sdk list maven输出~/.sdkman/candidates/maven/<version>/bin/mvn4. 渲染进程核心 - 数据模型
src/render/core/Module/ModuleSdkmanItem.ts: 新建 SDKMAN 项模型ModuleHomebrewItem.ts结构fetchCommand(): 返回sdk install java <identifier>或sdk uninstall java <identifier>copyCommand(): 复制命令到剪贴板runCommand(dom): XTerm 执行安装/卸载source ~/.sdkman/bin/sdkman-init.sh && sdk install/uninstall <candidate> <identifier>src/render/core/Module/Module.ts:sdkman: ModuleSdkmanItem[]数据数组sdkmanFetching: boolean状态fetchSdkman()方法, 参考fetchBrew()/fetchPort()模式src/render/util/Brew.ts: 添加sdkmanInfo(flag)IPC 桥接函数IPC.send('app-fork:<flag>', 'sdkmaninfo', flag)获取版本列表5. 渲染进程 Store
src/render/store/brew.ts:LibUse类型: 添加'sdkman'选项module()action: 添加module.fetchSdkman = module.fetchSdkman.bind(module)6. UI 组件 - SDKMAN 版本管理
src/render/components/VersionManager/sdkman/setup.ts: 新建port/setup.ts结构SdkmanSetupreactive 状态 (installing, installEnd, xterm, checkSdkman, reFetch)Setup(typeFlag)组合式函数checkSdkmancomputed: 检测window.Server.SdkmanHomehandleVersion: XTerm 执行 sdk install/uninstalltableData: 版本列表排序src/render/components/VersionManager/sdkman/index.vue: 新建port/index.vue结构7. UI 组件 - 集成到 VersionManager (跨平台)
src/render/components/VersionManager/setup.ts:'sdkman'选项src/render/components/VersionManager/setupAll.ts: 同上src/render/components/VersionManager/index.vue:showSdkmanLibprop (默认 false)v-if="showSdkmanLib !== false"的 SDKMAN radio-buttonv-if="libSrc === 'sdkman'"-><SdkmanVM />src/render/components/VersionManager/all.vue: 同上src/render/components/Java/Index.vue::show-sdkman-lib="true":show-sdkman-lib="true"文件变更清单
src/global.d.tssrc/main/Application.tssrc/fork/module/Sdkman/index.tssrc/fork/util/Version.tssrc/fork/Fn.tssrc/fork/BaseManager.tssrc/fork/module/Java/index.tssrc/fork/module/Maven/index.tssrc/render/core/Module/ModuleSdkmanItem.tssrc/render/core/Module/Module.tssrc/render/util/Brew.tssrc/render/store/brew.tssrc/render/components/VersionManager/sdkman/setup.tssrc/render/components/VersionManager/sdkman/index.vuesrc/render/components/VersionManager/setup.tssrc/render/components/VersionManager/setupAll.tssrc/render/components/VersionManager/index.vuesrc/render/components/VersionManager/all.vue新建 4 个文件, 修改 14 个文件. 预估 ~800 行新增代码.