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.
Files changed (23) hide show
  1. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.editorconfig +1 -1
  2. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.gitignore +1 -1
  3. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/PKG-INFO +16 -14
  4. vscode_offline-0.1.5/README.md +60 -0
  5. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/src/vscode_offline/app.py +101 -48
  6. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/src/vscode_offline/download.py +41 -27
  7. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/src/vscode_offline/install.py +32 -14
  8. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/src/vscode_offline/utils.py +12 -9
  9. vscode_offline-0.1.5/tests/test_install.py +27 -0
  10. vscode_offline-0.1.4/README.md +0 -58
  11. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.github/workflows/publish.yml +0 -0
  12. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.github/workflows/test.yml +0 -0
  13. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.python-version +0 -0
  14. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.vscode/extensions.json +0 -0
  15. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/.vscode/settings.json +0 -0
  16. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/LICENSE +0 -0
  17. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/lefthook.yml +0 -0
  18. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/pyproject.toml +0 -0
  19. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/pyrightconfig.json +0 -0
  20. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/src/vscode_offline/__init__.py +0 -0
  21. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/src/vscode_offline/loggers.py +0 -0
  22. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/tests/test_utils.py +0 -0
  23. {vscode_offline-0.1.4 → vscode_offline-0.1.5}/uv.lock +0 -0
@@ -7,7 +7,7 @@ end_of_line = lf
7
7
  trim_trailing_whitespace = true
8
8
  insert_final_newline = true
9
9
 
10
- # Disable rules for VSCode settings files
10
+ # Disable rules for VS Code settings files
11
11
  [.vscode/**]
12
12
  indent_style = unset
13
13
  charset = unset
@@ -10,5 +10,5 @@ wheels/
10
10
  # Virtual environments
11
11
  .venv
12
12
 
13
- # VSCode offline installer directory
13
+ # VS Code offline installer directory
14
14
  vscode-offline-installer/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vscode-offline
3
- Version: 0.1.4
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 Server 安装
39
+ ## VS Code 离线安装
40
40
 
41
- (1)在联网环境安装好 VSCode 和你需要的插件。
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)执行如下命令,将会自动下载 VS Code Server,和目前安装的所有的插件
43
+ (2)执行如下命令,下载 VS Code 安装包,和目前安装的所有的插件
44
44
 
45
- > `--commit` 可以指定对应 VSCode 的 Commit,默认自动获取当前环境 VSCode 的 Commit。
46
- >
47
- > 手动查看方式:*帮助* -> *关于* -> *Commit*,
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 download-server --target-platform linux-x64 --installer ./vscode-offline-installer
52
+ vscode-offline install-extensions --installer ./vscode-offline-installer
51
53
  ```
52
54
 
53
- 3)复制 `./vscode-offline-installer` 到内网服务器
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
- (1)联网环境执行如下命令,将会自动下载 VSCode 目前安装的所有的插件
63
+ 如果你想下载或安装指定版本的 VS Code,可以先通过 `code --version` 获取当前版本,然后通过 --code-version 参数指定版本号,例如:
62
64
 
63
65
  ```shell
64
- vscode-offline download-extensions --target-platform win32-x64 --installer ./vscode-offline-installer
66
+ vscode-offline download-all --code-version 1.104.3
65
67
  ```
66
68
 
67
- (2)复制 `./vscode-offline-installer` 到内网机器
69
+ 也支持使用 commit hash 作为版本号,例如:
68
70
 
69
71
  ```shell
70
- vscode-offline install-extensions --installer ./vscode-offline-installer
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
- get_vscode_server_home,
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.commit is None:
31
- args.commit = get_vscode_commit_from_code_version()
32
- if args.commit is None:
33
- logger.info(
34
- "Cannot determine commit from `code --version`, please specify --commit manually."
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.commit,
40
- output=args.installer / f"server-{args.commit}",
41
- target_platform=args.target_platform,
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, args.target_platform, args.installer / "extensions"
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.commit is None:
48
+ if args.code_version is None:
52
49
  try:
53
- args.commit = get_vscode_commit_from_server_installer(
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 `--commit` when installing."
55
+ f"{e}, please specify `--version` when installing."
59
56
  ) from None
60
57
 
61
- install_vscode_server(
62
- args.commit,
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, args.target_platform, args.installer / "extensions"
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
- os.fspath("code"),
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.commit is None:
94
- args.commit = get_vscode_commit_from_code_version()
95
- if args.commit is None:
96
- logger.info(
97
- "Cannot determine commit from `code --version`, please specify --commit manually."
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.commit,
103
- output=args.installer / f"client-{args.commit}",
104
- target_platform=args.target_platform,
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, args.target_platform, args.installer / "extensions"
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
- "--commit",
155
+ "--code-version",
133
156
  type=str,
134
- help="The commit hash of the VS Code Server to download, must match the version of the VSCode client.",
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
- "--target-platform",
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
- "--commit",
179
+ "--code-version",
157
180
  type=str,
158
- help="The commit hash of the VS Code Server to install.",
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
- "--target-platform",
191
+ "--platform",
169
192
  type=str,
170
193
  required=True,
171
- help="The target platform of the VSCode extensions to download.",
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 VSCode extensions",
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
- download_extensions_parser.add_argument(
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
- "--commit",
223
+ "--code-version",
201
224
  type=str,
202
- help="The commit hash of the VS Code to download, must match the version of the VSCode client.",
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
- "--target-platform",
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], target_platform: str, output: 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
- try:
109
- download_extension(publisher, name, version, target_platform, output=output)
110
- except HTTPError as e:
111
- if e.code != 404:
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
- commit: str,
144
+ version: str,
118
145
  output: str,
119
- target_platform: str,
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
- download_file(
129
- f"https://update.code.visualstudio.com/commit:{commit}/server-{target_platform}/stable",
130
- output,
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
- commit: str,
161
+ version: str,
144
162
  output: str,
145
- target_platform: str,
163
+ platform: str,
146
164
  ) -> None:
147
- """Download VS Code for the given commit and target platform."""
165
+ """Download VS Code Client for the given version and target platform."""
148
166
  os.makedirs(output, exist_ok=True)
149
- download_file(
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 get_cli_platform, get_vscode_server_home
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
- ) -> None:
85
+ ) -> os.PathLike[str]:
73
86
  cli_platform = get_cli_platform(platform)
74
87
  cli_platform_ = cli_platform.replace("-", "_")
75
88
 
76
- vscode_cli_tarball = (
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", vscode_cli_tarball, "-C", tmpdir])
81
- tmpfile = Path(tmpdir) / "code"
82
- if os.path.exists(vscode_cli_bin):
83
- os.remove(vscode_cli_bin)
84
- os.makedirs(os.path.dirname(vscode_cli_bin), exist_ok=True)
85
- os.rename(tmpfile, vscode_cli_bin)
86
- logger.info(f"Extracted vscode_cli_{cli_platform_}_cli.tar.gz to {vscode_cli_bin}")
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 get_vscode_commit_from_server_installer(
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
- commit = directories[0].parent.name[len("server-") :]
51
- logger.info(f"Getting commit from {platform} installer: {commit}")
52
- return commit
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 get_vscode_commit_from_code_version() -> str | None:
56
- """Get the current VS Code commit hash by running `code --version`.
57
- Returns None if `code` is not found or the output is unexpected.
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
- logger.info(f"Getting commit from `code --version`: {commit}")
77
+ version = f"commit:{commit}"
78
+ logger.info(f"Getting version from `code --version`: {version}")
76
79
 
77
- return commit
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)
@@ -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