vscode-offline 0.1.4__tar.gz → 0.1.5__tar.gz
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.
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.editorconfig +1 -1
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.gitignore +1 -1
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/PKG-INFO +16 -14
- vscode_offline-0.1.5/README.md +60 -0
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/src/vscode_offline/app.py +101 -48
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/src/vscode_offline/download.py +41 -27
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/src/vscode_offline/install.py +32 -14
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/src/vscode_offline/utils.py +12 -9
- vscode_offline-0.1.5/tests/test_install.py +27 -0
- vscode_offline-0.1.4/README.md +0 -58
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.github/workflows/publish.yml +0 -0
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.github/workflows/test.yml +0 -0
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.python-version +0 -0
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.vscode/extensions.json +0 -0
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.vscode/settings.json +0 -0
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/LICENSE +0 -0
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/lefthook.yml +0 -0
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/pyproject.toml +0 -0
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/pyrightconfig.json +0 -0
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/src/vscode_offline/__init__.py +0 -0
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/src/vscode_offline/loggers.py +0 -0
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/tests/test_utils.py +0 -0
- {vscode_offline-0.1.4 → vscode_offline-0.1.5}/uv.lock +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: vscode-offline
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.5
|
4
4
|
Summary: Download and install VS Code Server for offline environments
|
5
5
|
Project-URL: Homepage, https://github.com/fanck0605/vscode-offline
|
6
6
|
Author-email: Chuck Fan <fanck0605@qq.com>
|
@@ -36,38 +36,40 @@ pip install -U vscode-offline
|
|
36
36
|
1. 自动识别并下载所有 `.vsix` 文件(包括间接依赖)
|
37
37
|
2. 一键安装 VS Code Server 以及所有插件
|
38
38
|
|
39
|
-
## VS Code
|
39
|
+
## VS Code 离线安装
|
40
40
|
|
41
|
-
(1)在联网环境安装好
|
41
|
+
(1)在联网环境安装好 VS Code 和你需要的插件,如 [Remote - SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh), [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) 等。
|
42
42
|
|
43
|
-
(2
|
43
|
+
(2)执行如下命令,下载 VS Code 安装包,和目前安装的所有的插件
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
```shell
|
46
|
+
vscode-offline download-all --installer ./vscode-offline-installer
|
47
|
+
```
|
48
|
+
|
49
|
+
(3)复制 `./vscode-offline-installer` 到内网 Windows 机器,安装 `client-<version>` 下的 VS Code,然后执行如下命令安装所有插件
|
48
50
|
|
49
51
|
```shell
|
50
|
-
vscode-offline
|
52
|
+
vscode-offline install-extensions --installer ./vscode-offline-installer
|
51
53
|
```
|
52
54
|
|
53
|
-
(
|
55
|
+
(4)复制 `./vscode-offline-installer` 到内网 Linux 服务器,执行如下命令安装 VS Code Server 和所有插件
|
54
56
|
|
55
57
|
```shell
|
56
58
|
vscode-offline install-server --installer ./vscode-offline-installer
|
57
59
|
```
|
58
60
|
|
59
|
-
## VS Code
|
61
|
+
## 指定 VS Code 版本号
|
60
62
|
|
61
|
-
|
63
|
+
如果你想下载或安装指定版本的 VS Code,可以先通过 `code --version` 获取当前版本,然后通过 --code-version 参数指定版本号,例如:
|
62
64
|
|
63
65
|
```shell
|
64
|
-
vscode-offline download-
|
66
|
+
vscode-offline download-all --code-version 1.104.3
|
65
67
|
```
|
66
68
|
|
67
|
-
|
69
|
+
也支持使用 commit hash 作为版本号,例如:
|
68
70
|
|
69
71
|
```shell
|
70
|
-
vscode-offline
|
72
|
+
vscode-offline download-all --code-version commit:385651c938df8a906869babee516bffd0ddb9829
|
71
73
|
```
|
72
74
|
|
73
75
|
## 贡献
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# vscode-offline
|
2
|
+
|
3
|
+
vscode-offline 主要用于在无网环境下安装 VS Code Server,方便使用 *Remote - SSH* 插件进行远程开发。
|
4
|
+
|
5
|
+
## 安装
|
6
|
+
|
7
|
+
```shell
|
8
|
+
pip install -U vscode-offline
|
9
|
+
```
|
10
|
+
|
11
|
+
## 优势
|
12
|
+
|
13
|
+
1. 自动识别并下载所有 `.vsix` 文件(包括间接依赖)
|
14
|
+
2. 一键安装 VS Code Server 以及所有插件
|
15
|
+
|
16
|
+
## VS Code 离线安装
|
17
|
+
|
18
|
+
(1)在联网环境安装好 VS Code 和你需要的插件,如 [Remote - SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh), [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) 等。
|
19
|
+
|
20
|
+
(2)执行如下命令,下载 VS Code 安装包,和目前安装的所有的插件
|
21
|
+
|
22
|
+
```shell
|
23
|
+
vscode-offline download-all --installer ./vscode-offline-installer
|
24
|
+
```
|
25
|
+
|
26
|
+
(3)复制 `./vscode-offline-installer` 到内网 Windows 机器,安装 `client-<version>` 下的 VS Code,然后执行如下命令安装所有插件
|
27
|
+
|
28
|
+
```shell
|
29
|
+
vscode-offline install-extensions --installer ./vscode-offline-installer
|
30
|
+
```
|
31
|
+
|
32
|
+
(4)复制 `./vscode-offline-installer` 到内网 Linux 服务器,执行如下命令安装 VS Code Server 和所有插件
|
33
|
+
|
34
|
+
```shell
|
35
|
+
vscode-offline install-server --installer ./vscode-offline-installer
|
36
|
+
```
|
37
|
+
|
38
|
+
## 指定 VS Code 版本号
|
39
|
+
|
40
|
+
如果你想下载或安装指定版本的 VS Code,可以先通过 `code --version` 获取当前版本,然后通过 --code-version 参数指定版本号,例如:
|
41
|
+
|
42
|
+
```shell
|
43
|
+
vscode-offline download-all --code-version 1.104.3
|
44
|
+
```
|
45
|
+
|
46
|
+
也支持使用 commit hash 作为版本号,例如:
|
47
|
+
|
48
|
+
```shell
|
49
|
+
vscode-offline download-all --code-version commit:385651c938df8a906869babee516bffd0ddb9829
|
50
|
+
```
|
51
|
+
|
52
|
+
## 贡献
|
53
|
+
|
54
|
+
欢迎提交 Issue 和 PR 改进本项目。
|
55
|
+
|
56
|
+
## License
|
57
|
+
|
58
|
+
Copyright (c) 2025 Chuck Fan.
|
59
|
+
|
60
|
+
Distributed under the terms of the [MIT License](https://github.com/fanck0605/vscode-offline/blob/master/LICENSE).
|
@@ -1,7 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import logging
|
4
|
-
import os
|
5
4
|
from argparse import ArgumentParser, Namespace
|
6
5
|
from pathlib import Path
|
7
6
|
|
@@ -15,56 +14,51 @@ from vscode_offline.install import (
|
|
15
14
|
install_vscode_extensions,
|
16
15
|
install_vscode_server,
|
17
16
|
)
|
18
|
-
from vscode_offline.loggers import logger
|
19
17
|
from vscode_offline.utils import (
|
18
|
+
get_default_code_version,
|
20
19
|
get_host_platform,
|
21
|
-
get_vscode_cli_bin,
|
22
|
-
get_vscode_commit_from_code_version,
|
23
|
-
get_vscode_commit_from_server_installer,
|
24
20
|
get_vscode_extensions_config,
|
25
|
-
|
21
|
+
get_vscode_version_from_server_installer,
|
26
22
|
)
|
27
23
|
|
28
24
|
|
29
25
|
def cmd_download_server(args: Namespace) -> None:
|
30
|
-
if args.
|
31
|
-
args.
|
32
|
-
if args.
|
33
|
-
|
34
|
-
"Cannot determine
|
26
|
+
if args.code_version is None:
|
27
|
+
args.code_version = get_default_code_version()
|
28
|
+
if args.code_version is None:
|
29
|
+
raise ValueError(
|
30
|
+
"Cannot determine version from `code --version`, please specify `--version` when downloading."
|
35
31
|
)
|
36
|
-
raise ValueError("Please specify --commit when installing.")
|
37
32
|
|
38
33
|
download_vscode_server(
|
39
|
-
args.
|
40
|
-
output=args.installer / f"server-{args.
|
41
|
-
|
34
|
+
args.code_version,
|
35
|
+
output=args.installer / f"server-{args.code_version.replace(':', '-')}",
|
36
|
+
platform=args.platform,
|
42
37
|
)
|
43
38
|
extensions_config = Path(args.extensions_config).expanduser()
|
44
39
|
download_vscode_extensions(
|
45
|
-
extensions_config,
|
40
|
+
extensions_config,
|
41
|
+
target_platforms=[args.platform],
|
42
|
+
output=args.installer / "extensions",
|
46
43
|
)
|
47
44
|
|
48
45
|
|
49
46
|
def cmd_install_server(args: Namespace) -> None:
|
50
47
|
host_platform = get_host_platform()
|
51
|
-
if args.
|
48
|
+
if args.code_version is None:
|
52
49
|
try:
|
53
|
-
args.
|
50
|
+
args.code_version = get_vscode_version_from_server_installer(
|
54
51
|
args.installer, host_platform
|
55
52
|
)
|
56
53
|
except Exception as e:
|
57
54
|
raise ValueError(
|
58
|
-
f"{e}, please specify `--
|
55
|
+
f"{e}, please specify `--version` when installing."
|
59
56
|
) from None
|
60
57
|
|
61
|
-
install_vscode_server(
|
62
|
-
args.
|
63
|
-
server_installer=args.installer / f"server-{args.commit}",
|
64
|
-
vscode_cli_bin=get_vscode_cli_bin(args.commit),
|
58
|
+
vscode_server_home = install_vscode_server(
|
59
|
+
server_installer=args.installer / f"server-{args.code_version}",
|
65
60
|
platform=host_platform,
|
66
61
|
)
|
67
|
-
vscode_server_home = get_vscode_server_home(args.commit)
|
68
62
|
install_vscode_extensions(
|
69
63
|
Path(vscode_server_home) / "bin/code-server",
|
70
64
|
vsix_dir=args.installer / "extensions",
|
@@ -76,36 +70,65 @@ def cmd_install_server(args: Namespace) -> None:
|
|
76
70
|
def cmd_download_extensions(args: Namespace) -> None:
|
77
71
|
extensions_config = Path(args.extensions_config).expanduser()
|
78
72
|
download_vscode_extensions(
|
79
|
-
extensions_config,
|
73
|
+
extensions_config,
|
74
|
+
target_platforms=[args.platform],
|
75
|
+
output=args.installer / "extensions",
|
80
76
|
)
|
81
77
|
|
82
78
|
|
83
79
|
def cmd_install_extensions(args: Namespace) -> None:
|
84
80
|
host_platform = get_host_platform()
|
85
81
|
install_vscode_extensions(
|
86
|
-
|
82
|
+
args.code,
|
87
83
|
vsix_dir=args.installer / "extensions",
|
88
84
|
platform=host_platform,
|
89
85
|
)
|
90
86
|
|
91
87
|
|
92
88
|
def cmd_download_client(args: Namespace) -> None:
|
93
|
-
if args.
|
94
|
-
args.
|
95
|
-
if args.
|
96
|
-
|
97
|
-
"Cannot determine
|
89
|
+
if args.code_version is None:
|
90
|
+
args.code_version = get_default_code_version()
|
91
|
+
if args.code_version is None:
|
92
|
+
raise ValueError(
|
93
|
+
"Cannot determine version from `code --version`, please specify `--version` manually."
|
98
94
|
)
|
99
|
-
raise ValueError("Please specify --commit when installing.")
|
100
95
|
|
101
96
|
download_vscode_client(
|
102
|
-
args.
|
103
|
-
output=args.installer / f"client-{args.
|
104
|
-
|
97
|
+
args.code_version,
|
98
|
+
output=args.installer / f"client-{args.code_version.replace(':', '-')}",
|
99
|
+
platform=args.platform,
|
105
100
|
)
|
106
101
|
extensions_config = Path(args.extensions_config).expanduser()
|
107
102
|
download_vscode_extensions(
|
108
|
-
extensions_config,
|
103
|
+
extensions_config,
|
104
|
+
target_platforms=[args.platform],
|
105
|
+
output=args.installer / "extensions",
|
106
|
+
)
|
107
|
+
|
108
|
+
|
109
|
+
def cmd_download_all(args: Namespace) -> None:
|
110
|
+
if args.code_version is None:
|
111
|
+
args.code_version = get_default_code_version()
|
112
|
+
if args.code_version is None:
|
113
|
+
raise ValueError(
|
114
|
+
"Cannot determine version from `code --version`, please specify `--version` manually."
|
115
|
+
)
|
116
|
+
|
117
|
+
download_vscode_server(
|
118
|
+
args.code_version,
|
119
|
+
output=args.installer / f"server-{args.code_version.replace(':', '-')}",
|
120
|
+
platform=args.server_platform,
|
121
|
+
)
|
122
|
+
download_vscode_client(
|
123
|
+
args.code_version,
|
124
|
+
output=args.installer / f"client-{args.code_version.replace(':', '-')}",
|
125
|
+
platform=args.client_platform,
|
126
|
+
)
|
127
|
+
extensions_config = Path(args.extensions_config).expanduser()
|
128
|
+
download_vscode_extensions(
|
129
|
+
extensions_config,
|
130
|
+
target_platforms=[args.server_platform, args.client_platform],
|
131
|
+
output=args.installer / "extensions",
|
109
132
|
)
|
110
133
|
|
111
134
|
|
@@ -129,12 +152,12 @@ def make_argparser() -> ArgumentParser:
|
|
129
152
|
)
|
130
153
|
download_server_parser.set_defaults(func=cmd_download_server)
|
131
154
|
download_server_parser.add_argument(
|
132
|
-
"--
|
155
|
+
"--code-version",
|
133
156
|
type=str,
|
134
|
-
help="The
|
157
|
+
help="The version of the VS Code Server to download, must match the version of the VS Code Client.",
|
135
158
|
)
|
136
159
|
download_server_parser.add_argument(
|
137
|
-
"--
|
160
|
+
"--platform",
|
138
161
|
type=str,
|
139
162
|
required=True,
|
140
163
|
help="The target platform of the VS Code Server to download.",
|
@@ -153,9 +176,9 @@ def make_argparser() -> ArgumentParser:
|
|
153
176
|
)
|
154
177
|
install_server_parser.set_defaults(func=cmd_install_server)
|
155
178
|
install_server_parser.add_argument(
|
156
|
-
"--
|
179
|
+
"--code-version",
|
157
180
|
type=str,
|
158
|
-
help="The
|
181
|
+
help="The version of the VS Code Server to install.",
|
159
182
|
)
|
160
183
|
|
161
184
|
download_extensions_parser = subparsers.add_parser(
|
@@ -165,10 +188,10 @@ def make_argparser() -> ArgumentParser:
|
|
165
188
|
)
|
166
189
|
download_extensions_parser.set_defaults(func=cmd_download_extensions)
|
167
190
|
download_extensions_parser.add_argument(
|
168
|
-
"--
|
191
|
+
"--platform",
|
169
192
|
type=str,
|
170
193
|
required=True,
|
171
|
-
help="The target platform of the
|
194
|
+
help="The target platform of the VS Code extensions to download.",
|
172
195
|
)
|
173
196
|
download_extensions_parser.add_argument(
|
174
197
|
"--extensions-config",
|
@@ -179,11 +202,11 @@ def make_argparser() -> ArgumentParser:
|
|
179
202
|
|
180
203
|
install_extensions_parser = subparsers.add_parser(
|
181
204
|
"install-extensions",
|
182
|
-
help="Install
|
205
|
+
help="Install VS Code extensions",
|
183
206
|
parents=[parent_parser],
|
184
207
|
)
|
185
208
|
install_extensions_parser.set_defaults(func=cmd_install_extensions)
|
186
|
-
|
209
|
+
install_extensions_parser.add_argument(
|
187
210
|
"--code",
|
188
211
|
type=str,
|
189
212
|
default="code",
|
@@ -197,12 +220,12 @@ def make_argparser() -> ArgumentParser:
|
|
197
220
|
)
|
198
221
|
download_client_parser.set_defaults(func=cmd_download_client)
|
199
222
|
download_client_parser.add_argument(
|
200
|
-
"--
|
223
|
+
"--code-version",
|
201
224
|
type=str,
|
202
|
-
help="The
|
225
|
+
help="The version of the VS Code to download, must match the version of the VS Code Client.",
|
203
226
|
)
|
204
227
|
download_client_parser.add_argument(
|
205
|
-
"--
|
228
|
+
"--platform",
|
206
229
|
type=str,
|
207
230
|
required=True,
|
208
231
|
help="The target platform of the VS Code to download.",
|
@@ -214,6 +237,36 @@ def make_argparser() -> ArgumentParser:
|
|
214
237
|
help="Path to the extensions configuration file. Will search for extensions to download.",
|
215
238
|
)
|
216
239
|
|
240
|
+
download_all_parser = subparsers.add_parser(
|
241
|
+
"download-all",
|
242
|
+
help="Download VS Code server, client and extensions, all in one command",
|
243
|
+
parents=[parent_parser],
|
244
|
+
)
|
245
|
+
download_all_parser.set_defaults(func=cmd_download_all)
|
246
|
+
download_all_parser.add_argument(
|
247
|
+
"--code-version",
|
248
|
+
type=str,
|
249
|
+
help="The version of the VS Code to download, defaults to `code --version` at current environment.",
|
250
|
+
)
|
251
|
+
download_all_parser.add_argument(
|
252
|
+
"--server-platform",
|
253
|
+
type=str,
|
254
|
+
default="linux-x64",
|
255
|
+
help="The target platform of the VS Code Server to download, defaults to linux-x64.",
|
256
|
+
)
|
257
|
+
download_all_parser.add_argument(
|
258
|
+
"--client-platform",
|
259
|
+
type=str,
|
260
|
+
default="win32-x64",
|
261
|
+
help="The target platform of the VS Code to download, defaults to win32-x64.",
|
262
|
+
)
|
263
|
+
download_all_parser.add_argument(
|
264
|
+
"--extensions-config",
|
265
|
+
type=Path,
|
266
|
+
default=get_vscode_extensions_config(),
|
267
|
+
help="Path to the extensions configuration file. Will search for extensions to download.",
|
268
|
+
)
|
269
|
+
|
217
270
|
return parser
|
218
271
|
|
219
272
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
import json
|
4
4
|
import os
|
5
|
+
from collections.abc import Sequence
|
5
6
|
from gzip import GzipFile
|
6
7
|
from io import DEFAULT_BUFFER_SIZE
|
7
8
|
from pathlib import Path
|
@@ -94,7 +95,9 @@ def download_extension(
|
|
94
95
|
|
95
96
|
|
96
97
|
def download_vscode_extensions(
|
97
|
-
extensions_config: os.PathLike[str],
|
98
|
+
extensions_config: os.PathLike[str],
|
99
|
+
target_platforms: Sequence[str],
|
100
|
+
output: str = ".",
|
98
101
|
) -> None:
|
99
102
|
logger.info(f"Reading extensions config from {extensions_config}")
|
100
103
|
with open(extensions_config) as fp:
|
@@ -105,18 +108,42 @@ def download_vscode_extensions(
|
|
105
108
|
identifier = extension["identifier"]
|
106
109
|
publisher, name = identifier["id"].split(".")
|
107
110
|
version = extension["version"]
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
111
|
+
|
112
|
+
requires_fallback_download = False
|
113
|
+
for target_platform in target_platforms:
|
114
|
+
try:
|
115
|
+
download_extension(
|
116
|
+
publisher, name, version, target_platform, output=output
|
117
|
+
)
|
118
|
+
except HTTPError as e:
|
119
|
+
if e.code == 404:
|
120
|
+
requires_fallback_download = True
|
121
|
+
continue
|
112
122
|
raise
|
123
|
+
if requires_fallback_download:
|
113
124
|
download_extension(publisher, name, version, output=output)
|
114
125
|
|
115
126
|
|
127
|
+
def _download_vscode(
|
128
|
+
version: str,
|
129
|
+
output: str,
|
130
|
+
platform: str,
|
131
|
+
) -> None:
|
132
|
+
"""Download VS Code for the given version and target platform."""
|
133
|
+
|
134
|
+
# filename is like
|
135
|
+
# "VS CodeSetup-x64-1.104.3.exe" for windows VS Code,
|
136
|
+
# "vscode-server-linux-x64.tar.gz" for linux VS Code Server,
|
137
|
+
# "vscode_cli_alpine_x64_cli.tar.gz" for linux VS Code CLI.
|
138
|
+
download_file(
|
139
|
+
f"https://update.code.visualstudio.com/{version}/{platform}/stable", output
|
140
|
+
)
|
141
|
+
|
142
|
+
|
116
143
|
def download_vscode_server(
|
117
|
-
|
144
|
+
version: str,
|
118
145
|
output: str,
|
119
|
-
|
146
|
+
platform: str,
|
120
147
|
) -> None:
|
121
148
|
"""Download VS Code Server and CLI for the given commit and target platform.
|
122
149
|
|
@@ -125,29 +152,16 @@ def download_vscode_server(
|
|
125
152
|
https://blog.csdn.net/qq_69668825/article/details/144224417
|
126
153
|
"""
|
127
154
|
os.makedirs(output, exist_ok=True)
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
f"vscode-server-{target_platform}.tar.gz",
|
132
|
-
)
|
133
|
-
cli_target_platform = get_cli_platform(target_platform)
|
134
|
-
cli_target_platform_ = cli_target_platform.replace("-", "_")
|
135
|
-
download_file(
|
136
|
-
f"https://update.code.visualstudio.com/commit:{commit}/cli-{cli_target_platform}/stable",
|
137
|
-
output,
|
138
|
-
f"vscode_cli_{cli_target_platform_}_cli.tar.gz",
|
139
|
-
)
|
155
|
+
_download_vscode(version, output, f"server-{platform}")
|
156
|
+
cli_platform = get_cli_platform(platform)
|
157
|
+
_download_vscode(version, output, f"cli-{cli_platform}")
|
140
158
|
|
141
159
|
|
142
160
|
def download_vscode_client(
|
143
|
-
|
161
|
+
version: str,
|
144
162
|
output: str,
|
145
|
-
|
163
|
+
platform: str,
|
146
164
|
) -> None:
|
147
|
-
"""Download VS Code for the given
|
165
|
+
"""Download VS Code Client for the given version and target platform."""
|
148
166
|
os.makedirs(output, exist_ok=True)
|
149
|
-
|
150
|
-
f"https://update.code.visualstudio.com/commit:{commit}/{target_platform}/stable",
|
151
|
-
output,
|
152
|
-
# filename is like "VSCodeSetup-x64-1.104.3.exe" for windows
|
153
|
-
)
|
167
|
+
_download_vscode(version, output, platform)
|
@@ -1,13 +1,18 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import os
|
4
|
+
import re
|
4
5
|
import subprocess
|
5
6
|
from collections.abc import Set as AbstractSet
|
6
7
|
from pathlib import Path
|
7
8
|
from tempfile import TemporaryDirectory
|
8
9
|
|
9
10
|
from vscode_offline.loggers import logger
|
10
|
-
from vscode_offline.utils import
|
11
|
+
from vscode_offline.utils import (
|
12
|
+
get_cli_platform,
|
13
|
+
get_vscode_cli_bin,
|
14
|
+
get_vscode_server_home,
|
15
|
+
)
|
11
16
|
|
12
17
|
# These extensions are excluded because they are not needed in a VS Code Server.
|
13
18
|
SERVER_EXCLUDE_EXTENSIONS = frozenset(
|
@@ -64,26 +69,38 @@ def install_vscode_extensions(
|
|
64
69
|
logger.info(f"Installed {vsix_file}")
|
65
70
|
|
66
71
|
|
72
|
+
_code_version_output_pattern = re.compile(rb"\(commit ([0-9a-f]{40,})\)")
|
73
|
+
|
74
|
+
|
75
|
+
def _extract_commit_from_code_version_output(code_version_output: bytes) -> str:
|
76
|
+
m = _code_version_output_pattern.search(code_version_output)
|
77
|
+
if not m:
|
78
|
+
raise ValueError("Cannot determine commit hash from code version")
|
79
|
+
return m.group(1).decode("utf-8")
|
80
|
+
|
81
|
+
|
67
82
|
def install_vscode_server(
|
68
|
-
commit: str,
|
69
83
|
server_installer: str,
|
70
|
-
vscode_cli_bin: os.PathLike[str],
|
71
84
|
platform: str,
|
72
|
-
) ->
|
85
|
+
) -> os.PathLike[str]:
|
73
86
|
cli_platform = get_cli_platform(platform)
|
74
87
|
cli_platform_ = cli_platform.replace("-", "_")
|
75
88
|
|
76
|
-
|
77
|
-
Path(server_installer) / f"vscode_cli_{cli_platform_}_cli.tar.gz"
|
78
|
-
)
|
89
|
+
code_cli_tarball = Path(server_installer) / f"vscode_cli_{cli_platform_}_cli.tar.gz"
|
79
90
|
with TemporaryDirectory() as tmpdir:
|
80
|
-
subprocess.check_call(["tar", "-xzf",
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
91
|
+
subprocess.check_call(["tar", "-xzf", code_cli_tarball, "-C", tmpdir])
|
92
|
+
tmp_code_cli = Path(tmpdir) / "code"
|
93
|
+
version_output = subprocess.check_output(
|
94
|
+
["code", "--version"], executable=tmp_code_cli, cwd=tmpdir
|
95
|
+
)
|
96
|
+
commit = _extract_commit_from_code_version_output(version_output)
|
97
|
+
logger.info(f"Extracted commit from `code --version`: {commit}")
|
98
|
+
code_cli = get_vscode_cli_bin(commit)
|
99
|
+
if os.path.exists(code_cli):
|
100
|
+
os.remove(code_cli)
|
101
|
+
os.makedirs(os.path.dirname(code_cli), exist_ok=True)
|
102
|
+
os.rename(tmp_code_cli, code_cli)
|
103
|
+
logger.info(f"Extracted vscode_cli_{cli_platform_}_cli.tar.gz to {code_cli}")
|
87
104
|
|
88
105
|
vscode_server_tarball = Path(server_installer) / f"vscode-server-{platform}.tar.gz"
|
89
106
|
vscode_server_home = get_vscode_server_home(commit)
|
@@ -99,3 +116,4 @@ def install_vscode_server(
|
|
99
116
|
]
|
100
117
|
)
|
101
118
|
logger.info(f"Extracted vscode-server-{platform}.tar.gz to {vscode_server_home}")
|
119
|
+
return vscode_server_home
|
@@ -32,7 +32,7 @@ def get_vscode_extensions_config() -> os.PathLike[str]:
|
|
32
32
|
return p # default to this path
|
33
33
|
|
34
34
|
|
35
|
-
def
|
35
|
+
def get_vscode_version_from_server_installer(
|
36
36
|
installer: os.PathLike[str], platform: str
|
37
37
|
) -> str:
|
38
38
|
directories = list(
|
@@ -47,14 +47,16 @@ def get_vscode_commit_from_server_installer(
|
|
47
47
|
f"No matching installer found in {installer} for platform {platform}"
|
48
48
|
)
|
49
49
|
|
50
|
-
|
51
|
-
logger.info(f"Getting
|
52
|
-
return
|
50
|
+
version = directories[0].parent.name[len("server-") :]
|
51
|
+
logger.info(f"Getting version from {platform} installer: {version}")
|
52
|
+
return version
|
53
53
|
|
54
54
|
|
55
|
-
def
|
56
|
-
"""Get the current VS Code
|
57
|
-
|
55
|
+
def get_default_code_version() -> str | None:
|
56
|
+
"""Get the current VS Code version by running `code --version`.
|
57
|
+
|
58
|
+
Returns:
|
59
|
+
`None` if `code` is not found or the output is unexpected.
|
58
60
|
"""
|
59
61
|
executable = shutil.which("code")
|
60
62
|
if executable is None:
|
@@ -72,9 +74,10 @@ def get_vscode_commit_from_code_version() -> str | None:
|
|
72
74
|
|
73
75
|
# The commit hash is usually on the second line
|
74
76
|
commit = lines[1].strip().decode("utf-8")
|
75
|
-
|
77
|
+
version = f"commit:{commit}"
|
78
|
+
logger.info(f"Getting version from `code --version`: {version}")
|
76
79
|
|
77
|
-
return
|
80
|
+
return version
|
78
81
|
|
79
82
|
|
80
83
|
# Mapping from target platform to CLI OS and architecture used in download URLs
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from vscode_offline.install import (
|
4
|
+
_extract_commit_from_code_version_output, # pyright: ignore[reportPrivateUsage]
|
5
|
+
)
|
6
|
+
|
7
|
+
|
8
|
+
def test_extract_commit_from_valid_output() -> None:
|
9
|
+
# Simulate output like: b'code 1.80.0 (commit 1234567890abcdef1234567890abcdef12345678)\n'
|
10
|
+
commit = "1234567890abcdef1234567890abcdef12345678"
|
11
|
+
output = f"code 1.80.0 (commit {commit})\n".encode("utf-8")
|
12
|
+
assert _extract_commit_from_code_version_output(output) == commit
|
13
|
+
|
14
|
+
|
15
|
+
def test_extract_commit_from_invalid_output() -> None:
|
16
|
+
output = b"code 1.80.0 (no commit info here)\n"
|
17
|
+
with pytest.raises(
|
18
|
+
ValueError, match="Cannot determine commit hash from code version"
|
19
|
+
):
|
20
|
+
_extract_commit_from_code_version_output(output)
|
21
|
+
|
22
|
+
|
23
|
+
def test_extract_commit_from_output_short_commit() -> None:
|
24
|
+
# Should not match if commit is too short (<40 chars)
|
25
|
+
output = b"code 1.80.0 (commit 1234567890abcdef)\n"
|
26
|
+
with pytest.raises(ValueError):
|
27
|
+
_extract_commit_from_code_version_output(output)
|
vscode_offline-0.1.4/README.md
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
# vscode-offline
|
2
|
-
|
3
|
-
vscode-offline 主要用于在无网环境下安装 VS Code Server,方便使用 *Remote - SSH* 插件进行远程开发。
|
4
|
-
|
5
|
-
## 安装
|
6
|
-
|
7
|
-
```shell
|
8
|
-
pip install -U vscode-offline
|
9
|
-
```
|
10
|
-
|
11
|
-
## 优势
|
12
|
-
|
13
|
-
1. 自动识别并下载所有 `.vsix` 文件(包括间接依赖)
|
14
|
-
2. 一键安装 VS Code Server 以及所有插件
|
15
|
-
|
16
|
-
## VS Code Server 安装
|
17
|
-
|
18
|
-
(1)在联网环境安装好 VSCode 和你需要的插件。
|
19
|
-
|
20
|
-
(2)执行如下命令,将会自动下载 VS Code Server,和目前安装的所有的插件
|
21
|
-
|
22
|
-
> `--commit` 可以指定对应 VSCode 的 Commit,默认自动获取当前环境 VSCode 的 Commit。
|
23
|
-
>
|
24
|
-
> 手动查看方式:*帮助* -> *关于* -> *Commit*,
|
25
|
-
|
26
|
-
```shell
|
27
|
-
vscode-offline download-server --target-platform linux-x64 --installer ./vscode-offline-installer
|
28
|
-
```
|
29
|
-
|
30
|
-
(3)复制 `./vscode-offline-installer` 到内网服务器
|
31
|
-
|
32
|
-
```shell
|
33
|
-
vscode-offline install-server --installer ./vscode-offline-installer
|
34
|
-
```
|
35
|
-
|
36
|
-
## VS Code 插件安装
|
37
|
-
|
38
|
-
(1)联网环境执行如下命令,将会自动下载 VSCode 目前安装的所有的插件
|
39
|
-
|
40
|
-
```shell
|
41
|
-
vscode-offline download-extensions --target-platform win32-x64 --installer ./vscode-offline-installer
|
42
|
-
```
|
43
|
-
|
44
|
-
(2)复制 `./vscode-offline-installer` 到内网机器
|
45
|
-
|
46
|
-
```shell
|
47
|
-
vscode-offline install-extensions --installer ./vscode-offline-installer
|
48
|
-
```
|
49
|
-
|
50
|
-
## 贡献
|
51
|
-
|
52
|
-
欢迎提交 Issue 和 PR 改进本项目。
|
53
|
-
|
54
|
-
## License
|
55
|
-
|
56
|
-
Copyright (c) 2025 Chuck Fan.
|
57
|
-
|
58
|
-
Distributed under the terms of the [MIT License](https://github.com/fanck0605/vscode-offline/blob/master/LICENSE).
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|