sdkvm 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +444 -0
- package/dist/index.js +1828 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 jvm contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# sdkvm
|
|
4
|
+
|
|
5
|
+
**简单、跨平台的多语言 SDK 版本管理器**
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/sdkvm)
|
|
8
|
+
[](https://github.com/QInJ1995/sdkvm/actions/workflows/ci.yml)
|
|
9
|
+
[](./LICENSE)
|
|
10
|
+
[](./package.json)
|
|
11
|
+
[](#系统要求)
|
|
12
|
+
|
|
13
|
+
像 [nvm](https://github.com/nvm-sh/nvm) 管理 Node.js 一样管理 **Java JDK**、**Go 工具链** 与 **Flutter SDK**。
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 目录
|
|
20
|
+
|
|
21
|
+
- [简介](#简介)
|
|
22
|
+
- [从 easy-jvm 升级](#从-easy-jvm-升级)
|
|
23
|
+
- [系统要求](#系统要求)
|
|
24
|
+
- [安装](#安装)
|
|
25
|
+
- [快速开始](#快速开始)
|
|
26
|
+
- [命令参考](#命令参考)
|
|
27
|
+
- [版本语法](#版本语法)
|
|
28
|
+
- [工作原理](#工作原理)
|
|
29
|
+
- [配置](#配置)
|
|
30
|
+
- [镜像加速(国内用户)](#镜像加速国内用户)
|
|
31
|
+
- [安全性](#安全性)
|
|
32
|
+
- [常见问题](#常见问题)
|
|
33
|
+
- [卸载](#卸载)
|
|
34
|
+
- [开发](#开发)
|
|
35
|
+
- [许可证](#许可证)
|
|
36
|
+
|
|
37
|
+
## 简介
|
|
38
|
+
|
|
39
|
+
`sdkvm` 是一个用 Node.js 编写的命令行工具,提供多种语言 SDK 的**安装、切换、卸载**能力:
|
|
40
|
+
|
|
41
|
+
- **Java**:内置 [Adoptium Temurin](https://adoptium.net/)、[Azul Zulu](https://www.azul.com/downloads/)、[Amazon Corretto](https://aws.amazon.com/corretto/) 三个主流发行版,支持 `lts` 语义(当前 LTS:8 / 11 / 17 / 21 / 25)
|
|
42
|
+
- **Go**:官方 [go.dev](https://go.dev/dl/) 源,全历史稳定版可装
|
|
43
|
+
- **Flutter**:官方发布清单(stable / beta 通道),macOS 双架构、Linux / Windows x64
|
|
44
|
+
- **多平台**:macOS(Apple Silicon / Intel)、Linux、Windows 10+
|
|
45
|
+
- **开箱即用**:仅依赖 Node.js 与系统自带的 tar / PowerShell,各 SDK 完全隔离,`JAVA_HOME` / `GOROOT` / `FLUTTER_ROOT` 并存互不干扰
|
|
46
|
+
- **秒级切换**:`use` 只更新一个符号链接(Windows 为 junction),不搬移文件、不改全局环境
|
|
47
|
+
- **官方源直连**:下载地址一律经官方 API 解析;Go 与 Flutter 的官方清单内联 SHA-256,**强制校验**,其余源尽力校验
|
|
48
|
+
- **镜像支持**:Temurin、Go、Flutter 均可配置国内镜像加速下载(校验和仍取自官方,镜像文件被交叉验证)
|
|
49
|
+
- **可扩展**:SDK 类型抽象(`src/sdk/`)之上新增语言只需实现一个厂商模块(见[开发](#开发))
|
|
50
|
+
|
|
51
|
+
## 从 easy-jvm 升级
|
|
52
|
+
|
|
53
|
+
`sdkvm` 是 `easy-jvm` 的更名升级版(原工具只管理 JDK)。已装用户:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
npm uninstall -g easy-jvm # 先卸载旧包,避免残留的 jvm 命令重建空 ~/.jvm
|
|
57
|
+
npm install -g sdkvm
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
首次运行任意命令时,`~/.jvm/` 会**自动整体迁移**为 `~/.sdkvm/`:
|
|
61
|
+
|
|
62
|
+
- 迁移是一次**原子目录改名**(同卷 `rename`,无中间失败窗口),已装 JDK 原样保留,无需重装
|
|
63
|
+
- 随后自动改写:`current` 链接(更名为 `current-java`,绝对目标同步指向新路径)、Windows 注册表 `JAVA_HOME` 字面值、shell 配置文件中的旧 `# >>> jvm init >>>` 标记块
|
|
64
|
+
- 幂等:迁移过一次后再运行不会重复动作;`~/.sdkvm/` 已存在时不自动合并,仅提示手动处理
|
|
65
|
+
- 旧的 `JVM_HOME` / `JVM_MIRROR` / `JVM_QUIET` 环境变量**永久作为别名**继续识别
|
|
66
|
+
|
|
67
|
+
## 系统要求
|
|
68
|
+
|
|
69
|
+
| 依赖 | 版本 | 说明 |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| Node.js | >= 18.15 | 唯一运行时依赖(CLI 本身另需 commander / picocolors,随包安装) |
|
|
72
|
+
| 操作系统 | — | macOS(Apple Silicon / Intel)/ 主流 Linux 发行版 / Windows 10+ |
|
|
73
|
+
| 解压工具 | 系统自带 | macOS/Linux 用 `tar`;Windows 用系统自带 bsdtar,缺失时回退 PowerShell `Expand-Archive` |
|
|
74
|
+
|
|
75
|
+
> **平台差异须知**
|
|
76
|
+
>
|
|
77
|
+
> - Linux 解压 Flutter 归档(`.tar.xz`)需系统装有 `xz`(`xz-utils`);主流发行版默认自带
|
|
78
|
+
> - Flutter 官方在 Linux / Windows 只发布 **x64** 归档;ARM Linux / ARM Windows 无法安装(macOS 两种架构均支持)
|
|
79
|
+
> - `flutter` 命令首次运行会做内部初始化(构建 cache),耗时较久属正常现象
|
|
80
|
+
|
|
81
|
+
## 安装
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
npm install -g sdkvm
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
安装完成后即可使用 `sdkvm` 命令。验证:
|
|
88
|
+
|
|
89
|
+
```console
|
|
90
|
+
$ sdkvm version
|
|
91
|
+
1.0.0
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## 快速开始
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
# Java(裸命令 = java,与 easy-jvm 时代用法完全一致)
|
|
98
|
+
sdkvm install lts # 安装最新 LTS(当前为 Temurin 25)
|
|
99
|
+
sdkvm use 25 # 切换到该版本
|
|
100
|
+
java -version # 验证生效(可能需要重开终端)
|
|
101
|
+
|
|
102
|
+
# Go(go 子命令组)
|
|
103
|
+
sdkvm go install 1.24 # 安装 Go 1.24 线最新补丁版
|
|
104
|
+
sdkvm go use 1.24 # 切换(更新 GOROOT / PATH)
|
|
105
|
+
go version
|
|
106
|
+
|
|
107
|
+
# Flutter(flutter 子命令组)
|
|
108
|
+
sdkvm flutter install 3.47 # 安装 3.47 线最新补丁版(stable 通道)
|
|
109
|
+
sdkvm flutter use 3.47 # 切换(更新 FLUTTER_ROOT / PATH)
|
|
110
|
+
flutter --version
|
|
111
|
+
|
|
112
|
+
# 混合使用
|
|
113
|
+
sdkvm current # 同时显示 java / go / flutter 的当前版本
|
|
114
|
+
sdkvm java install 21 --vendor zulu
|
|
115
|
+
sdkvm java use zulu-21
|
|
116
|
+
sdkvm ls # 已装的 Java
|
|
117
|
+
sdkvm go ls # 已装的 Go
|
|
118
|
+
sdkvm flutter ls # 已装的 Flutter
|
|
119
|
+
sdkvm uninstall zulu-21
|
|
120
|
+
sdkvm go uninstall 1.24
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## 命令参考
|
|
124
|
+
|
|
125
|
+
Java 用裸命令(`sdkvm install …`)或 `sdkvm java …` 子命令组,两者完全等价;Go / Flutter 用 `sdkvm go …` / `sdkvm flutter …`。
|
|
126
|
+
|
|
127
|
+
### 命令速查
|
|
128
|
+
|
|
129
|
+
| 命令 | 作用 |
|
|
130
|
+
|---|---|
|
|
131
|
+
| `sdkvm install <version>` | 安装 Java 版本(= `sdkvm java install`) |
|
|
132
|
+
| `sdkvm use <version>` | 切换当前 Java 版本 |
|
|
133
|
+
| `sdkvm ls` / `sdkvm ls -r` | 列出已装版本 / 可安装版本线 |
|
|
134
|
+
| `sdkvm current` | 显示全部 SDK 类型的当前版本 |
|
|
135
|
+
| `sdkvm uninstall <version>` | 卸载一个版本 |
|
|
136
|
+
| `sdkvm mirror show·set·unset` | 管理下载镜像 |
|
|
137
|
+
| `sdkvm java · go · flutter …` | 各 SDK 类型的完整命令组 |
|
|
138
|
+
| `sdkvm version` | 打印 CLI 版本号 |
|
|
139
|
+
|
|
140
|
+
各类型的版本语法速查:
|
|
141
|
+
|
|
142
|
+
```sh
|
|
143
|
+
sdkvm java install lts | 21 | 21.0.5 | 21.0.5+11 | zulu-21
|
|
144
|
+
sdkvm go install latest | 1.24 | 1.24.5 | golang-1.24
|
|
145
|
+
sdkvm flutter install latest | 3.47 | 3.47.5 | 3.49.0-0.1.pre | flutter-3.47
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### `sdkvm install <version>`
|
|
149
|
+
|
|
150
|
+
解析 → 下载(实时进度、边下边算 sha256)→ 校验 → 解压到临时目录 → 原子落位:
|
|
151
|
+
|
|
152
|
+
```console
|
|
153
|
+
$ sdkvm install 21
|
|
154
|
+
sdkvm resolving Adoptium Temurin 21 for mac/aarch64 ...
|
|
155
|
+
sdkvm downloading https://github.com/adoptium/temurin21-binaries/releases/...
|
|
156
|
+
↓ Temurin 21.0.12.1 160.2MB / 200.4MB
|
|
157
|
+
sdkvm installed Temurin 21.0.12.1 → ~/.sdkvm/jdks/temurin-21.0.12.1
|
|
158
|
+
sdkvm switch to it: sdkvm use 21
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
| 选项 | 说明 |
|
|
162
|
+
|---|---|
|
|
163
|
+
| `--vendor <id>` | 指定发行版:`temurin`(默认)/ `zulu` / `corretto`;Go 只有 `golang`,Flutter 只有 `flutter` |
|
|
164
|
+
| `--force` | 已安装时移除重装(默认跳过已装版本) |
|
|
165
|
+
|
|
166
|
+
失败行为:校验不过 / 解压异常会自动清理半成品目录与缓存,不留脏状态;下载采用 60 秒**空闲超时**(60s 无数据才中止,大文件不会被总时长掐断)。
|
|
167
|
+
|
|
168
|
+
### `sdkvm use <version>`
|
|
169
|
+
|
|
170
|
+
切换当前版本:更新 `current` 链接与 `JAVA_HOME`(或 `GOROOT` / `FLUTTER_ROOT`)/ `PATH`。版本语法与 `install` 相同,在**已安装**范围内匹配:
|
|
171
|
+
|
|
172
|
+
```sh
|
|
173
|
+
sdkvm use 21 # 切换到已安装的 21 最新补丁版
|
|
174
|
+
sdkvm use temurin-21.0.5+11 # 切换到精确版本
|
|
175
|
+
sdkvm go use 1.24.5 # Go 精确版本
|
|
176
|
+
sdkvm flutter use 3.47.5 # Flutter 精确版本
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
> macOS / Linux 下首次 `use` 会在 shell 配置文件中追加初始化代码块,**重开终端(或 `source ~/.zshrc`)后生效**;之后每次切换只动链接,新终端即时生效。IDE(IntelliJ / VS Code 等)需要重启才会读到新的环境变量。详见[切换机制](#切换机制)。
|
|
180
|
+
|
|
181
|
+
### `sdkvm ls` / `sdkvm list`
|
|
182
|
+
|
|
183
|
+
列出已安装的版本,`→` 标记当前版本:
|
|
184
|
+
|
|
185
|
+
```console
|
|
186
|
+
$ sdkvm go ls
|
|
187
|
+
→ golang-1.24.5
|
|
188
|
+
golang-1.23.9
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### `sdkvm ls -r` / `sdkvm ls --remote`
|
|
192
|
+
|
|
193
|
+
并行拉取该类型全部厂商的可安装版本线。每行名称带厂商前缀,**可直接复制给 `install`**(默认展示最近 12 条线,更老的版本可按精确名称安装):
|
|
194
|
+
|
|
195
|
+
```console
|
|
196
|
+
$ sdkvm flutter ls -r
|
|
197
|
+
|
|
198
|
+
# Flutter (official)
|
|
199
|
+
flutter-3.47 latest: flutter-3.47.5
|
|
200
|
+
flutter-3.44 latest: flutter-3.44.9
|
|
201
|
+
...
|
|
202
|
+
|
|
203
|
+
# install with: sdkvm flutter install <name>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
| 选项 | 说明 |
|
|
207
|
+
|---|---|
|
|
208
|
+
| `--vendor <id>` | 只列出指定厂商 |
|
|
209
|
+
|
|
210
|
+
### `sdkvm current`
|
|
211
|
+
|
|
212
|
+
显示全部 SDK 类型的当前版本及其环境变量路径(未安装的类型不显示):
|
|
213
|
+
|
|
214
|
+
```console
|
|
215
|
+
$ sdkvm current
|
|
216
|
+
java: temurin-21.0.12.1
|
|
217
|
+
JAVA_HOME → ~/.sdkvm/jdks/temurin-21.0.12.1
|
|
218
|
+
go: golang-1.24.5
|
|
219
|
+
GOROOT → ~/.sdkvm/gos/golang-1.24.5
|
|
220
|
+
flutter: flutter-3.47.5
|
|
221
|
+
FLUTTER_ROOT → ~/.sdkvm/flutters/flutter-3.47.5
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### `sdkvm uninstall <version>`
|
|
225
|
+
|
|
226
|
+
卸载已安装的版本,语法与 `use` 相同。卸载当前版本时会自动清空对应 `current` 链接并提示另选版本;不影响其他已装版本。
|
|
227
|
+
|
|
228
|
+
### `sdkvm mirror <action> [vendor] [url]`
|
|
229
|
+
|
|
230
|
+
管理下载镜像,详见[镜像加速](#镜像加速国内用户)。Java / Go / Flutter 分别用 `sdkvm mirror …`、`sdkvm go mirror …`、`sdkvm flutter mirror …`:
|
|
231
|
+
|
|
232
|
+
| Action | 说明 |
|
|
233
|
+
|---|---|
|
|
234
|
+
| `show` | 查看当前镜像配置(含推荐值) |
|
|
235
|
+
| `set <vendor> <url>` | 设置镜像,写入配置文件 |
|
|
236
|
+
| `unset <vendor>` | 恢复官方源 |
|
|
237
|
+
|
|
238
|
+
### `sdkvm version`
|
|
239
|
+
|
|
240
|
+
打印 CLI 版本号(等同于 `sdkvm --version`)。
|
|
241
|
+
|
|
242
|
+
## 版本语法
|
|
243
|
+
|
|
244
|
+
`install` / `use` / `uninstall` 共用版本语法,按 SDK 类型区分:
|
|
245
|
+
|
|
246
|
+
| 语法 | Java 含义 | Go 含义 | Flutter 含义 | 示例 |
|
|
247
|
+
|---|---|---|---|---|
|
|
248
|
+
| `<major>` | 该大版本最新补丁版(`21`) | — | —(裸大版本拒绝,建议 `latest`) | `21` |
|
|
249
|
+
| `<major.minor>` | — | 该 minor 线最新补丁版 | 该 minor 线最新补丁版(stable 通道) | `1.24`、`3.47` |
|
|
250
|
+
| `lts` | 最新 LTS 大版本 | —(无 LTS) | —(无 LTS) | `lts` |
|
|
251
|
+
| `latest` | — | 全局最新稳定版 | stable 通道最新(不追 beta) | `latest` |
|
|
252
|
+
| `<full-version>` | 精确版本 / 前缀匹配 | 精确版本 | 精确版本,可带 prerelease 段装 beta | `21.0.5+11`、`1.24.5`、`3.49.0-0.1.pre` |
|
|
253
|
+
| `<vendor>-…` | 加厂商前缀限定发行版 | 同左 | 同左 | `zulu-21`、`golang-1.24`、`flutter-3.47` |
|
|
254
|
+
|
|
255
|
+
匹配规则:
|
|
256
|
+
|
|
257
|
+
- `21` 匹配该大版本下**已安装/可安装的最新补丁版**;`1.24`、`3.47` 同理匹配该线最新补丁版
|
|
258
|
+
- Java 的 `21.0.5` 做前缀匹配,可命中 `21.0.5+11`;Go / Flutter 的精确版本为全串匹配
|
|
259
|
+
- Flutter 的 `latest` / `3.47` 只在 **stable** 通道解析;装 beta 需给完整 prerelease 版本号(如 `3.49.0-0.1.pre`)
|
|
260
|
+
- Java 的 `lts` 当前指 8 / 11 / 17 / 21 / 25(与 Adoptium LTS 列表对齐)
|
|
261
|
+
- 不带厂商前缀时使用默认发行版(仅 Java 可配,见[配置文件](#配置文件);Go / Flutter 各只有一个官方源)
|
|
262
|
+
|
|
263
|
+
## 工作原理
|
|
264
|
+
|
|
265
|
+
### 目录布局
|
|
266
|
+
|
|
267
|
+
所有数据位于 `~/.sdkvm/`(Windows 为 `%USERPROFILE%\.sdkvm`;可用 `SDKVM_HOME` 覆盖,旧名 `JVM_HOME` 仍识别):
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
~/.sdkvm/
|
|
271
|
+
├── jdks/ # Java:<vendor>-<version>,如 temurin-21.0.12.1
|
|
272
|
+
├── gos/ # Go:golang-<version>,如 golang-1.24.5
|
|
273
|
+
├── flutters/ # Flutter:flutter-<version>,如 flutter-3.47.5
|
|
274
|
+
├── current-java # 指向当前 JAVA_HOME 的链接(Windows 上为 junction)
|
|
275
|
+
├── current-go # 指向当前 GOROOT 的链接
|
|
276
|
+
├── current-flutter # 指向当前 FLUTTER_ROOT 的链接
|
|
277
|
+
├── config.json # CLI 配置(见「配置」)
|
|
278
|
+
├── cache/ # 下载中转(安装成功后自动清理,不做长期缓存)
|
|
279
|
+
└── tmp/ # 解压临时目录(同样自动清理)
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
各版本的磁盘量级(解压后,供规划空间参考):Java 每版本约 300 MB,Go 约 250 MB,Flutter 数 GB(压缩包本身 1–2.2 GB)。
|
|
283
|
+
|
|
284
|
+
### 切换机制
|
|
285
|
+
|
|
286
|
+
**macOS / Linux**
|
|
287
|
+
|
|
288
|
+
`current-java` / `current-go` / `current-flutter` 是指向当前版本目录的符号链接。首次 `use` 会在 shell 配置文件(zsh → `~/.zshrc`;bash → `~/.bash_profile` / `~/.bashrc`)追加一段带标记的初始化代码块,三种 SDK 各一块、互不干扰:
|
|
289
|
+
|
|
290
|
+
```sh
|
|
291
|
+
# >>> sdkvm java init >>>
|
|
292
|
+
export JAVA_HOME="$HOME/.sdkvm/current-java"
|
|
293
|
+
case ":$PATH:" in *":$JAVA_HOME/bin:"*) ;; *) export PATH="$JAVA_HOME/bin:$PATH";; esac
|
|
294
|
+
# <<< sdkvm java init <<<
|
|
295
|
+
|
|
296
|
+
# >>> sdkvm go init >>>
|
|
297
|
+
export GOROOT="$HOME/.sdkvm/current-go"
|
|
298
|
+
case ":$PATH:" in *":$GOROOT/bin:"*) ;; *) export PATH="$GOROOT/bin:$PATH";; esac
|
|
299
|
+
# <<< sdkvm go init <<<
|
|
300
|
+
|
|
301
|
+
# >>> sdkvm flutter init >>>
|
|
302
|
+
export FLUTTER_ROOT="$HOME/.sdkvm/current-flutter"
|
|
303
|
+
case ":$PATH:" in *":$FLUTTER_ROOT/bin:"*) ;; *) export PATH="$FLUTTER_ROOT/bin:$PATH";; esac
|
|
304
|
+
# <<< sdkvm flutter init <<<
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
环境变量指向**链接**而非具体版本目录,因此之后每次 `use` 只改链接指向,已开的终端在下一次 `source` rc 或新开终端时读到新值。
|
|
308
|
+
|
|
309
|
+
**Windows**
|
|
310
|
+
|
|
311
|
+
`%USERPROFILE%\.sdkvm\current-java` / `current-go` / `current-flutter` 为 junction;`use` 写入用户级 `JAVA_HOME` / `GOROOT` / `FLUTTER_ROOT`,并把 `%JAVA_HOME%\bin`、`%GOROOT%\bin`、`%FLUTTER_ROOT%\bin` 追加到用户 PATH。通过注册表 API 操作并原样保留 `REG_EXPAND_SZ` 类型与 `%VAR%` 引用,避免 `setx` 的 1024 字符截断问题。需要**重开终端**(或重启 IDE)生效。
|
|
312
|
+
|
|
313
|
+
### 数据迁移
|
|
314
|
+
|
|
315
|
+
首次运行时检测旧版 `~/.jvm/`:存在且 `~/.sdkvm/` 尚未创建时,执行一次原子目录改名,随后重写 `current` 链接(更名为 `current-java`,绝对目标同步改指新路径)、Windows 注册表 `JAVA_HOME` 字面值、shell 配置文件中的旧标记块。`~/.sdkvm/` 已存在时**不自动合并**,仅提示手动处理。详见[从 easy-jvm 升级](#从-easy-jvm-升级)。
|
|
316
|
+
|
|
317
|
+
## 配置
|
|
318
|
+
|
|
319
|
+
### 配置文件
|
|
320
|
+
|
|
321
|
+
`~/.sdkvm/config.json`:
|
|
322
|
+
|
|
323
|
+
```json
|
|
324
|
+
{
|
|
325
|
+
"version": 1,
|
|
326
|
+
"defaultVendor": "temurin",
|
|
327
|
+
"mirror": {
|
|
328
|
+
"temurin": "https://mirrors.nju.edu.cn/adoptium",
|
|
329
|
+
"golang": "https://golang.google.cn/dl",
|
|
330
|
+
"flutter": "https://mirror.nju.edu.cn/flutter/flutter_infra_release"
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
| 字段 | 说明 | 默认值 |
|
|
336
|
+
|---|---|---|
|
|
337
|
+
| `version` | 配置 schema 版本 | `1` |
|
|
338
|
+
| `defaultVendor` | Java 不带厂商前缀时的默认发行版 | `"temurin"` |
|
|
339
|
+
| `mirror` | 各厂商的镜像 URL(键为全局唯一的厂商 id,跨 SDK 类型) | `{}`(官方源) |
|
|
340
|
+
|
|
341
|
+
配置文件损坏时自动备份为 `config.json.bak` 并回退默认值。
|
|
342
|
+
|
|
343
|
+
### 环境变量
|
|
344
|
+
|
|
345
|
+
| 变量 | 旧名别名 | 说明 |
|
|
346
|
+
|---|---|---|
|
|
347
|
+
| `SDKVM_HOME` | `JVM_HOME` | 覆盖数据根目录(默认 `~/.sdkvm`) |
|
|
348
|
+
| `SDKVM_MIRROR` | `JVM_MIRROR` | 临时指定下载镜像,**优先级高于配置文件**(不写入) |
|
|
349
|
+
| `SDKVM_QUIET` | `JVM_QUIET` | 设为非空时抑制 info/warn 日志输出 |
|
|
350
|
+
|
|
351
|
+
镜像解析优先级:`SDKVM_MIRROR` 环境变量 > `config.mirror[<vendor>]` > 官方源。
|
|
352
|
+
|
|
353
|
+
## 镜像加速(国内用户)
|
|
354
|
+
|
|
355
|
+
Temurin 默认从 GitHub 下载、Go 默认从 go.dev 下载、Flutter 默认从 storage.googleapis.com 下载,国内网络建议切换到镜像:
|
|
356
|
+
|
|
357
|
+
```sh
|
|
358
|
+
sdkvm mirror set temurin https://mirrors.nju.edu.cn/adoptium # Java
|
|
359
|
+
sdkvm go mirror set golang https://golang.google.cn/dl # Go
|
|
360
|
+
sdkvm flutter mirror set flutter https://mirror.nju.edu.cn/flutter/flutter_infra_release # Flutter
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
也可以用环境变量临时指定(不写入配置):
|
|
364
|
+
|
|
365
|
+
```sh
|
|
366
|
+
SDKVM_MIRROR=https://golang.google.cn/dl sdkvm go install 1.24
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
> 镜像仅替换 tarball 下载地址,版本元数据与校验和**始终走官方 API**——即使文件来自镜像,sha256 仍与官方清单核对。Go 镜像根 URL 兼容 `https://golang.google.cn/dl`(官方中国站)与 `https://mirrors.aliyun.com/golang`(文件名直接拼接);Flutter 镜像为桶前缀替换(已验证 [NJU](https://mirror.nju.edu.cn/flutter/flutter_infra_release);`storage.flutter-io.cn` 不含发布清单,勿用);Zulu 与 Corretto 由官方 CDN 直接分发,暂不支持镜像。
|
|
370
|
+
|
|
371
|
+
## 安全性
|
|
372
|
+
|
|
373
|
+
- 下载地址通过**官方 API** 解析(Adoptium API / Azul Metadata API / Corretto 官方分发 / go.dev/dl JSON API / Flutter releases 清单),不做任何搜索页抓取
|
|
374
|
+
- tarball 做逐块流式 **SHA-256 校验**:Go 与 Flutter 的校验和内联于官方 API,**强制校验**;Java 各源尽力校验,校验源不可达时警告放行
|
|
375
|
+
- 解压前校验归档结构(单根目录、可执行文件存在),且只解压到全新空目录,防止路径穿越
|
|
376
|
+
- 安装全程持有文件锁(`~/.sdkvm/.lock`),避免并发安装互相踩踏
|
|
377
|
+
|
|
378
|
+
## 常见问题
|
|
379
|
+
|
|
380
|
+
**Q:`use` 之后 `java -version` 还是旧版本?**
|
|
381
|
+
rc 代码块只在**新终端**(或 `source ~/.zshrc`)时生效;IDE 需重启。可先 `sdkvm current` 确认链接已切换,再重开终端。Windows 同理:注册表已更新,但已开的终端读不到新值。
|
|
382
|
+
|
|
383
|
+
**Q:我用 fish / nushell,rc 探测不到怎么办?**
|
|
384
|
+
当前自动写入仅支持 zsh / bash。手工把[切换机制](#切换机制)中的代码块翻译到你的 shell 即可(fish 语法:`set -gx JAVA_HOME $HOME/.sdkvm/current-java; fish_add_path $JAVA_HOME/bin`)。
|
|
385
|
+
|
|
386
|
+
**Q:Flutter 下载太慢或中断?**
|
|
387
|
+
配置镜像(见上文 NJU 命令)。sdkvm 的下载超时是「60 秒无数据」而非总时长,稳定慢速不会中断;真中断直接重跑 `install`,无残留状态。
|
|
388
|
+
|
|
389
|
+
**Q:怎么安装 Flutter beta?**
|
|
390
|
+
给完整 prerelease 版本号:`sdkvm flutter install 3.49.0-0.1.pre`。`latest` 与版本线(`3.47`)只解析 stable 通道。
|
|
391
|
+
|
|
392
|
+
**Q:公司网络走代理,能用吗?**
|
|
393
|
+
当前版本未内置 HTTP 代理支持(Node fetch 不读 `HTTPS_PROXY`)。可用系统级透明代理,或关注后续版本。
|
|
394
|
+
|
|
395
|
+
**Q:装回 easy-jvm 会怎样?**
|
|
396
|
+
easy-jvm 使用独立的 `~/.jvm`,二者互不破坏,但版本各装各的。建议只用 sdkvm(`~/.jvm` 若再出现,检查是否残留旧全局包)。
|
|
397
|
+
|
|
398
|
+
**Q:sdkvm 自身怎么升级?**
|
|
399
|
+
`sdkvm` 由 npm 分发:`npm update -g sdkvm`。数据目录(`~/.sdkvm`)与 CLI 升级无关。
|
|
400
|
+
|
|
401
|
+
**Q:CI / 多用户环境想隔离数据?**
|
|
402
|
+
设 `SDKVM_HOME=/path/to/dir` 即可整体重定向(安装、链接、配置全部跟随)。
|
|
403
|
+
|
|
404
|
+
## 卸载
|
|
405
|
+
|
|
406
|
+
```sh
|
|
407
|
+
npm uninstall -g sdkvm
|
|
408
|
+
rm -rf ~/.sdkvm # 删除 SDK 数据目录(会删掉所有已装版本,先确认)
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
并删除 shell 配置文件中 `>>> sdkvm java init >>>`、`>>> sdkvm go init >>>`、`>>> sdkvm flutter init >>>` 各自到 `<<< … <<<` 之间的标记块。
|
|
412
|
+
|
|
413
|
+
Windows 用户额外需要:在系统设置中删除 `JAVA_HOME` / `GOROOT` / `FLUTTER_ROOT`,并从用户 PATH 移除 `%JAVA_HOME%\bin`、`%GOROOT%\bin`、`%FLUTTER_ROOT%\bin`。
|
|
414
|
+
|
|
415
|
+
## 开发
|
|
416
|
+
|
|
417
|
+
```sh
|
|
418
|
+
git clone https://github.com/QInJ1995/sdkvm.git && cd sdkvm
|
|
419
|
+
npm install
|
|
420
|
+
|
|
421
|
+
npm test # vitest 单元 + 集成测试
|
|
422
|
+
npm run typecheck # tsc --noEmit
|
|
423
|
+
npm run build # tsup → dist/index.js(本地试用:node dist/index.js …)
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
项目结构:
|
|
427
|
+
|
|
428
|
+
```
|
|
429
|
+
src/
|
|
430
|
+
├── cli/ # 命令实现(install / use / ls / uninstall / mirror …)
|
|
431
|
+
├── core/ # 版本解析、安装注册表、配置、迁移、文件锁
|
|
432
|
+
├── sdk/ # SDK 类型描述(java / go / flutter:目录名、环境变量、版本语法)
|
|
433
|
+
├── vendor/ # 发行版适配(temurin / zulu / corretto / golang / flutter)+ 镜像改写
|
|
434
|
+
├── fs/ # 下载 / 校验 / 解压 / 归一化 / 链接
|
|
435
|
+
├── shell/ # rc 探测与写入、Windows 注册表环境变量
|
|
436
|
+
├── net/ # fetch 封装(重试、超时)、流式下载
|
|
437
|
+
└── ui/ # 日志、进度条
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
新增一种语言 SDK:在 `src/vendor/` 实现一个厂商模块(`listMajors` + `resolve` 两个方法),在 `src/sdk/` 加一个类型描述(安装目录名、current 链接名、环境变量、版本语法、二进制探测路径),注册进 `sdk/index.ts` 后即获得完整的 install / use / ls / uninstall / mirror 命令组——CLI、切换机制、rc / 注册表写入全部自动泛化。
|
|
441
|
+
|
|
442
|
+
## 许可证
|
|
443
|
+
|
|
444
|
+
[MIT](./LICENSE) © QINJIN
|