vscode-offline 0.1.6__py3-none-any.whl → 0.1.8__py3-none-any.whl
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/__init__.py +7 -1
- vscode_offline/_version.py +34 -0
- vscode_offline/app.py +48 -23
- vscode_offline/download.py +33 -20
- vscode_offline/py.typed +0 -0
- vscode_offline/utils.py +147 -13
- vscode_offline-0.1.8.dist-info/METADATA +137 -0
- vscode_offline-0.1.8.dist-info/RECORD +13 -0
- vscode_offline-0.1.6.dist-info/METADATA +0 -83
- vscode_offline-0.1.6.dist-info/RECORD +0 -11
- {vscode_offline-0.1.6.dist-info → vscode_offline-0.1.8.dist-info}/WHEEL +0 -0
- {vscode_offline-0.1.6.dist-info → vscode_offline-0.1.8.dist-info}/entry_points.txt +0 -0
- {vscode_offline-0.1.6.dist-info → vscode_offline-0.1.8.dist-info}/licenses/LICENSE +0 -0
vscode_offline/__init__.py
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
# file generated by setuptools-scm
|
2
|
+
# don't change, don't track in version control
|
3
|
+
|
4
|
+
__all__ = [
|
5
|
+
"__version__",
|
6
|
+
"__version_tuple__",
|
7
|
+
"version",
|
8
|
+
"version_tuple",
|
9
|
+
"__commit_id__",
|
10
|
+
"commit_id",
|
11
|
+
]
|
12
|
+
|
13
|
+
TYPE_CHECKING = False
|
14
|
+
if TYPE_CHECKING:
|
15
|
+
from typing import Tuple
|
16
|
+
from typing import Union
|
17
|
+
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
19
|
+
COMMIT_ID = Union[str, None]
|
20
|
+
else:
|
21
|
+
VERSION_TUPLE = object
|
22
|
+
COMMIT_ID = object
|
23
|
+
|
24
|
+
version: str
|
25
|
+
__version__: str
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
27
|
+
version_tuple: VERSION_TUPLE
|
28
|
+
commit_id: COMMIT_ID
|
29
|
+
__commit_id__: COMMIT_ID
|
30
|
+
|
31
|
+
__version__ = version = '0.1.8'
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 8)
|
33
|
+
|
34
|
+
__commit_id__ = commit_id = None
|
vscode_offline/app.py
CHANGED
@@ -4,6 +4,7 @@ import logging
|
|
4
4
|
from argparse import ArgumentParser, Namespace
|
5
5
|
from pathlib import Path
|
6
6
|
|
7
|
+
from vscode_offline._version import __version__
|
7
8
|
from vscode_offline.download import (
|
8
9
|
download_vscode_client,
|
9
10
|
download_vscode_extensions,
|
@@ -15,10 +16,14 @@ from vscode_offline.install import (
|
|
15
16
|
install_vscode_server,
|
16
17
|
)
|
17
18
|
from vscode_offline.utils import (
|
19
|
+
get_client_platform,
|
18
20
|
get_default_code_version,
|
21
|
+
get_extension_platform,
|
19
22
|
get_host_platform,
|
23
|
+
get_server_platform,
|
20
24
|
get_vscode_extensions_config,
|
21
25
|
get_vscode_version_from_server_installer,
|
26
|
+
validate_platform,
|
22
27
|
)
|
23
28
|
|
24
29
|
|
@@ -32,13 +37,15 @@ def cmd_download_server(args: Namespace) -> None:
|
|
32
37
|
|
33
38
|
download_vscode_server(
|
34
39
|
args.code_version,
|
35
|
-
output=args.installer /
|
36
|
-
platform=args.platform,
|
40
|
+
output=args.installer / args.code_version.replace(":", "-"),
|
41
|
+
platform=get_server_platform(args.platform),
|
37
42
|
)
|
38
43
|
extensions_config = Path(args.extensions_config).expanduser()
|
39
44
|
download_vscode_extensions(
|
40
45
|
extensions_config,
|
41
|
-
target_platforms=
|
46
|
+
target_platforms={
|
47
|
+
get_extension_platform(args.platform),
|
48
|
+
},
|
42
49
|
output=args.installer / "extensions",
|
43
50
|
)
|
44
51
|
|
@@ -56,13 +63,13 @@ def cmd_install_server(args: Namespace) -> None:
|
|
56
63
|
) from None
|
57
64
|
|
58
65
|
vscode_server_home = install_vscode_server(
|
59
|
-
server_installer=args.installer /
|
60
|
-
platform=host_platform,
|
66
|
+
server_installer=args.installer / args.code_version.replace(":", "-"),
|
67
|
+
platform=get_server_platform(host_platform),
|
61
68
|
)
|
62
69
|
install_vscode_extensions(
|
63
70
|
Path(vscode_server_home) / "bin/code-server",
|
64
71
|
vsix_dir=args.installer / "extensions",
|
65
|
-
platform=host_platform,
|
72
|
+
platform=get_extension_platform(host_platform),
|
66
73
|
exclude=SERVER_EXCLUDE_EXTENSIONS,
|
67
74
|
)
|
68
75
|
|
@@ -71,7 +78,9 @@ def cmd_download_extensions(args: Namespace) -> None:
|
|
71
78
|
extensions_config = Path(args.extensions_config).expanduser()
|
72
79
|
download_vscode_extensions(
|
73
80
|
extensions_config,
|
74
|
-
target_platforms=
|
81
|
+
target_platforms={
|
82
|
+
get_extension_platform(args.platform),
|
83
|
+
},
|
75
84
|
output=args.installer / "extensions",
|
76
85
|
)
|
77
86
|
|
@@ -81,7 +90,7 @@ def cmd_install_extensions(args: Namespace) -> None:
|
|
81
90
|
install_vscode_extensions(
|
82
91
|
args.code,
|
83
92
|
vsix_dir=args.installer / "extensions",
|
84
|
-
platform=host_platform,
|
93
|
+
platform=get_extension_platform(host_platform),
|
85
94
|
)
|
86
95
|
|
87
96
|
|
@@ -95,13 +104,15 @@ def cmd_download_client(args: Namespace) -> None:
|
|
95
104
|
|
96
105
|
download_vscode_client(
|
97
106
|
args.code_version,
|
98
|
-
output=args.installer /
|
99
|
-
platform=args.platform,
|
107
|
+
output=args.installer / args.code_version.replace(":", "-"),
|
108
|
+
platform=get_client_platform(args.platform),
|
100
109
|
)
|
101
110
|
extensions_config = Path(args.extensions_config).expanduser()
|
102
111
|
download_vscode_extensions(
|
103
112
|
extensions_config,
|
104
|
-
target_platforms=
|
113
|
+
target_platforms={
|
114
|
+
get_extension_platform(args.platform),
|
115
|
+
},
|
105
116
|
output=args.installer / "extensions",
|
106
117
|
)
|
107
118
|
|
@@ -116,22 +127,30 @@ def cmd_download_all(args: Namespace) -> None:
|
|
116
127
|
|
117
128
|
download_vscode_server(
|
118
129
|
args.code_version,
|
119
|
-
output=args.installer /
|
120
|
-
platform=args.server_platform,
|
130
|
+
output=args.installer / args.code_version.replace(":", "-"),
|
131
|
+
platform=get_server_platform(args.server_platform),
|
121
132
|
)
|
122
133
|
download_vscode_client(
|
123
134
|
args.code_version,
|
124
|
-
output=args.installer /
|
125
|
-
platform=args.client_platform,
|
135
|
+
output=args.installer / args.code_version.replace(":", "-"),
|
136
|
+
platform=get_client_platform(args.client_platform),
|
126
137
|
)
|
127
138
|
extensions_config = Path(args.extensions_config).expanduser()
|
128
139
|
download_vscode_extensions(
|
129
140
|
extensions_config,
|
130
|
-
target_platforms=
|
141
|
+
target_platforms={
|
142
|
+
get_extension_platform(args.server_platform),
|
143
|
+
get_extension_platform(args.client_platform),
|
144
|
+
},
|
131
145
|
output=args.installer / "extensions",
|
132
146
|
)
|
133
147
|
|
134
148
|
|
149
|
+
def cmd_version(args: Namespace) -> None:
|
150
|
+
# print version instead of logging
|
151
|
+
print(__version__)
|
152
|
+
|
153
|
+
|
135
154
|
def make_argparser() -> ArgumentParser:
|
136
155
|
parent_parser = ArgumentParser(add_help=False)
|
137
156
|
|
@@ -145,6 +164,12 @@ def make_argparser() -> ArgumentParser:
|
|
145
164
|
parser = ArgumentParser()
|
146
165
|
subparsers = parser.add_subparsers(required=True)
|
147
166
|
|
167
|
+
version_parser = subparsers.add_parser(
|
168
|
+
"version",
|
169
|
+
help="Show version information",
|
170
|
+
)
|
171
|
+
version_parser.set_defaults(func=cmd_version)
|
172
|
+
|
148
173
|
download_server_parser = subparsers.add_parser(
|
149
174
|
"download-server",
|
150
175
|
help="Download VS Code Server and extensions",
|
@@ -158,7 +183,7 @@ def make_argparser() -> ArgumentParser:
|
|
158
183
|
)
|
159
184
|
download_server_parser.add_argument(
|
160
185
|
"--platform",
|
161
|
-
type=
|
186
|
+
type=validate_platform,
|
162
187
|
required=True,
|
163
188
|
help="The target platform of the VS Code Server to download.",
|
164
189
|
)
|
@@ -189,7 +214,7 @@ def make_argparser() -> ArgumentParser:
|
|
189
214
|
download_extensions_parser.set_defaults(func=cmd_download_extensions)
|
190
215
|
download_extensions_parser.add_argument(
|
191
216
|
"--platform",
|
192
|
-
type=
|
217
|
+
type=validate_platform,
|
193
218
|
required=True,
|
194
219
|
help="The target platform of the VS Code extensions to download.",
|
195
220
|
)
|
@@ -226,7 +251,7 @@ def make_argparser() -> ArgumentParser:
|
|
226
251
|
)
|
227
252
|
download_client_parser.add_argument(
|
228
253
|
"--platform",
|
229
|
-
type=
|
254
|
+
type=validate_platform,
|
230
255
|
required=True,
|
231
256
|
help="The target platform of the VS Code to download.",
|
232
257
|
)
|
@@ -250,14 +275,14 @@ def make_argparser() -> ArgumentParser:
|
|
250
275
|
)
|
251
276
|
download_all_parser.add_argument(
|
252
277
|
"--server-platform",
|
253
|
-
type=
|
254
|
-
|
278
|
+
type=validate_platform,
|
279
|
+
required=True,
|
255
280
|
help="The target platform of the VS Code Server to download, defaults to linux-x64.",
|
256
281
|
)
|
257
282
|
download_all_parser.add_argument(
|
258
283
|
"--client-platform",
|
259
|
-
type=
|
260
|
-
|
284
|
+
type=validate_platform,
|
285
|
+
required=True,
|
261
286
|
help="The target platform of the VS Code to download, defaults to win32-x64.",
|
262
287
|
)
|
263
288
|
download_all_parser.add_argument(
|
vscode_offline/download.py
CHANGED
@@ -2,18 +2,19 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
import json
|
4
4
|
import os
|
5
|
-
from collections.abc import
|
5
|
+
from collections.abc import Set as AbstractSet
|
6
6
|
from gzip import GzipFile
|
7
|
-
from io import DEFAULT_BUFFER_SIZE
|
8
7
|
from pathlib import Path
|
9
8
|
from urllib.error import HTTPError
|
10
9
|
from urllib.request import urlopen
|
11
10
|
|
12
11
|
from vscode_offline.loggers import logger
|
13
|
-
from vscode_offline.utils import
|
12
|
+
from vscode_offline.utils import extract_filename_from_headers, get_cli_platform
|
14
13
|
|
14
|
+
_DOWNLOAD_CHUNK_SIZE = 4 * 1024 * 1024 # 4 MiB
|
15
15
|
|
16
|
-
|
16
|
+
|
17
|
+
def _download_file_once(
|
17
18
|
url: str,
|
18
19
|
directory: str | os.PathLike[str],
|
19
20
|
filename: str | None = None,
|
@@ -31,12 +32,12 @@ def _download_file(
|
|
31
32
|
if filename:
|
32
33
|
file_path = Path(directory).joinpath(filename)
|
33
34
|
else:
|
34
|
-
filename =
|
35
|
+
filename = extract_filename_from_headers(resp.headers)
|
35
36
|
if not filename:
|
36
37
|
raise ValueError(
|
37
|
-
"Cannot
|
38
|
+
"Cannot extract filename from HTTP headers, please specify argument `filename`."
|
38
39
|
)
|
39
|
-
logger.info(f"
|
40
|
+
logger.info(f"Extracted filename {filename} from HTTP headers.")
|
40
41
|
file_path = Path(directory).joinpath(filename)
|
41
42
|
if file_path.exists():
|
42
43
|
logger.info(f"File {file_path} already exists, skipping download.")
|
@@ -45,7 +46,7 @@ def _download_file(
|
|
45
46
|
tmp_file_path = Path(directory).joinpath(f"{filename}.tmp")
|
46
47
|
with reader, tmp_file_path.open("wb") as fp:
|
47
48
|
while True:
|
48
|
-
chunk = reader.read(
|
49
|
+
chunk = reader.read(_DOWNLOAD_CHUNK_SIZE)
|
49
50
|
if not chunk:
|
50
51
|
break
|
51
52
|
fp.write(chunk)
|
@@ -58,7 +59,7 @@ def _download_file(
|
|
58
59
|
return file_path
|
59
60
|
|
60
61
|
|
61
|
-
def
|
62
|
+
def _download_file(
|
62
63
|
url: str,
|
63
64
|
directory: str | os.PathLike[str],
|
64
65
|
filename: str | None = None,
|
@@ -70,35 +71,47 @@ def download_file(
|
|
70
71
|
return
|
71
72
|
|
72
73
|
logger.info(f"Downloading {url} ...")
|
73
|
-
|
74
|
+
attempt_num = 0
|
75
|
+
while True:
|
74
76
|
try:
|
75
|
-
|
77
|
+
_download_file_once(url, directory, filename)
|
76
78
|
break
|
77
79
|
except Exception as e:
|
78
80
|
if isinstance(e, HTTPError) and e.code == 404:
|
79
81
|
raise
|
80
|
-
|
82
|
+
attempt_num += 1
|
83
|
+
if attempt_num >= 3:
|
84
|
+
raise
|
85
|
+
logger.info(f"Attempt {attempt_num} times failed: {e}")
|
81
86
|
|
82
87
|
|
83
|
-
def
|
88
|
+
def _download_extension(
|
84
89
|
publisher: str,
|
85
90
|
name: str,
|
86
91
|
version: str,
|
87
92
|
platform: str | None = None,
|
88
|
-
output: str = ".",
|
93
|
+
output: str | os.PathLike[str] = ".",
|
89
94
|
) -> None:
|
90
95
|
url = f"https://marketplace.visualstudio.com/_apis/public/gallery/publishers/{publisher}/vsextensions/{name}/{version}/vspackage"
|
91
96
|
if platform:
|
92
97
|
url = f"{url}?targetPlatform={platform}"
|
93
98
|
filename = f"{publisher}.{name}-{version}{f'@{platform}' if platform else ''}.vsix"
|
94
|
-
|
99
|
+
_download_file(url, output, filename)
|
95
100
|
|
96
101
|
|
97
102
|
def download_vscode_extensions(
|
98
103
|
extensions_config: os.PathLike[str],
|
99
|
-
target_platforms:
|
100
|
-
output: str = ".",
|
104
|
+
target_platforms: AbstractSet[str],
|
105
|
+
output: str | os.PathLike[str] = ".",
|
101
106
|
) -> None:
|
107
|
+
"""Download VS Code extensions listed in the given extensions config file.
|
108
|
+
|
109
|
+
Args:
|
110
|
+
extensions_config: Path to the extensions config file, which is a JSON file
|
111
|
+
containing a list of extensions with their publisher, name, and version.
|
112
|
+
target_platforms: List of target platforms for which to download the extensions.
|
113
|
+
output: Directory to save the downloaded extensions.
|
114
|
+
"""
|
102
115
|
logger.info(f"Reading extensions config from {extensions_config}")
|
103
116
|
with open(extensions_config) as fp:
|
104
117
|
data = json.loads(fp.read())
|
@@ -112,7 +125,7 @@ def download_vscode_extensions(
|
|
112
125
|
requires_fallback_download = False
|
113
126
|
for target_platform in target_platforms:
|
114
127
|
try:
|
115
|
-
|
128
|
+
_download_extension(
|
116
129
|
publisher, name, version, target_platform, output=output
|
117
130
|
)
|
118
131
|
except HTTPError as e:
|
@@ -121,7 +134,7 @@ def download_vscode_extensions(
|
|
121
134
|
continue
|
122
135
|
raise
|
123
136
|
if requires_fallback_download:
|
124
|
-
|
137
|
+
_download_extension(publisher, name, version, output=output)
|
125
138
|
|
126
139
|
|
127
140
|
def _download_vscode(
|
@@ -135,7 +148,7 @@ def _download_vscode(
|
|
135
148
|
# "VS CodeSetup-x64-1.104.3.exe" for windows VS Code,
|
136
149
|
# "vscode-server-linux-x64.tar.gz" for linux VS Code Server,
|
137
150
|
# "vscode_cli_alpine_x64_cli.tar.gz" for linux VS Code CLI.
|
138
|
-
|
151
|
+
_download_file(
|
139
152
|
f"https://update.code.visualstudio.com/{version}/{platform}/stable", output
|
140
153
|
)
|
141
154
|
|
vscode_offline/py.typed
ADDED
File without changes
|
vscode_offline/utils.py
CHANGED
@@ -4,9 +4,12 @@ import os
|
|
4
4
|
import shutil
|
5
5
|
import subprocess
|
6
6
|
import sys
|
7
|
+
from argparse import ArgumentTypeError
|
7
8
|
from collections.abc import Mapping
|
9
|
+
from collections.abc import Set as AbstractSet
|
8
10
|
from email.parser import HeaderParser
|
9
11
|
from pathlib import Path
|
12
|
+
from typing import Final
|
10
13
|
|
11
14
|
from vscode_offline.loggers import logger
|
12
15
|
|
@@ -35,9 +38,7 @@ def get_vscode_extensions_config() -> os.PathLike[str]:
|
|
35
38
|
def get_vscode_version_from_server_installer(
|
36
39
|
installer: os.PathLike[str], platform: str
|
37
40
|
) -> str:
|
38
|
-
directories = list(
|
39
|
-
Path(installer).glob(f"server-*/vscode-server-{platform}.tar.gz")
|
40
|
-
)
|
41
|
+
directories = list(Path(installer).glob(f"*/vscode-server-{platform}.tar.gz"))
|
41
42
|
if len(directories) > 1:
|
42
43
|
raise ValueError(
|
43
44
|
f"Multiple matching installers found in {installer} for platform {platform}"
|
@@ -47,9 +48,9 @@ def get_vscode_version_from_server_installer(
|
|
47
48
|
f"No matching installer found in {installer} for platform {platform}"
|
48
49
|
)
|
49
50
|
|
50
|
-
version = directories[0].parent.name
|
51
|
+
version = directories[0].parent.name
|
51
52
|
logger.info(f"Getting version from {platform} installer: {version}")
|
52
|
-
return version
|
53
|
+
return version.replace("commit-", "commit:")
|
53
54
|
|
54
55
|
|
55
56
|
def get_default_code_version() -> str | None:
|
@@ -80,20 +81,151 @@ def get_default_code_version() -> str | None:
|
|
80
81
|
return version
|
81
82
|
|
82
83
|
|
83
|
-
# Mapping from
|
84
|
-
|
84
|
+
# Mapping from other platforms to VS Code client platform used in download URLs
|
85
|
+
_client_platform_mapping: Final[Mapping[str, str]] = {
|
86
|
+
"linux-x64": "linux-x64",
|
87
|
+
"alpine-x64": "linux-x64",
|
88
|
+
"linux-deb-x64": "linux-deb-x64",
|
89
|
+
"linux-rpm-x64": "linux-rpm-x64",
|
90
|
+
"linux-arm64": "linux-arm64",
|
91
|
+
"alpine-arm64": "linux-arm64",
|
92
|
+
"linux-deb-arm64": "linux-deb-arm64",
|
93
|
+
"linux-rpm-arm64": "linux-rpm-arm64",
|
94
|
+
"linux-armhf": "linux-armhf",
|
95
|
+
"linux-deb-armhf": "linux-deb-armhf",
|
96
|
+
"linux-rpm-armhf": "linux-rpm-armhf",
|
97
|
+
"win32-x64": "win32-x64",
|
98
|
+
"win32-x64-user": "win32-x64-user",
|
99
|
+
"win32-x64-archive": "win32-x64-archive",
|
100
|
+
"win32-arm64": "win32-arm64",
|
101
|
+
"win32-arm64-user": "win32-arm64-user",
|
102
|
+
"win32-arm64-archive": "win32-arm64-archive",
|
103
|
+
"darwin": "darwin",
|
104
|
+
"darwin-x64": "darwin",
|
105
|
+
"darwin-arm64": "darwin-arm64",
|
106
|
+
}
|
107
|
+
|
108
|
+
# Mapping from other platforms to VS Code server platform used in download URLs
|
109
|
+
_server_platform_mapping: Final[Mapping[str, str]] = {
|
110
|
+
"linux-x64": "linux-x64",
|
111
|
+
"alpine-x64": "linux-x64",
|
112
|
+
"linux-deb-x64": "linux-x64",
|
113
|
+
"linux-rpm-x64": "linux-x64",
|
114
|
+
"linux-arm64": "linux-arm64",
|
115
|
+
"alpine-arm64": "linux-arm64",
|
116
|
+
"linux-deb-arm64": "linux-arm64",
|
117
|
+
"linux-rpm-arm64": "linux-arm64",
|
118
|
+
"linux-armhf": "linux-armhf",
|
119
|
+
"linux-deb-armhf": "linux-armhf",
|
120
|
+
"linux-rpm-armhf": "linux-armhf",
|
121
|
+
"win32-x64": "win32-x64",
|
122
|
+
"win32-x64-user": "win32-x64",
|
123
|
+
"win32-x64-archive": "win32-x64",
|
124
|
+
"win32-arm64": "win32-arm64",
|
125
|
+
"win32-arm64-user": "win32-arm64",
|
126
|
+
"win32-arm64-archive": "win32-arm64",
|
127
|
+
"darwin": "darwin",
|
128
|
+
"darwin-x64": "darwin",
|
129
|
+
"darwin-arm64": "darwin-arm64",
|
130
|
+
}
|
131
|
+
|
132
|
+
|
133
|
+
# Mapping from other platforms to VS Code CLI platform used in download URLs
|
134
|
+
_cli_platform_mapping: Final[Mapping[str, str]] = {
|
85
135
|
"linux-x64": "alpine-x64",
|
136
|
+
"alpine-x64": "alpine-x64",
|
137
|
+
"linux-deb-x64": "alpine-x64",
|
138
|
+
"linux-rpm-x64": "alpine-x64",
|
86
139
|
"linux-arm64": "alpine-arm64",
|
87
|
-
"
|
140
|
+
"alpine-arm64": "alpine-arm64",
|
141
|
+
"linux-deb-arm64": "alpine-arm64",
|
142
|
+
"linux-rpm-arm64": "alpine-arm64",
|
143
|
+
"linux-armhf": "linux-armhf",
|
144
|
+
"linux-deb-armhf": "linux-armhf",
|
145
|
+
"linux-rpm-armhf": "linux-armhf",
|
146
|
+
"win32-x64": "win32-x64",
|
147
|
+
"win32-x64-user": "win32-x64",
|
148
|
+
"win32-x64-archive": "win32-x64",
|
149
|
+
"win32-arm64": "win32-arm64",
|
150
|
+
"win32-arm64-user": "win32-arm64",
|
151
|
+
"win32-arm64-archive": "win32-arm64",
|
152
|
+
"darwin": "darwin-x64",
|
153
|
+
"darwin-x64": "darwin-x64",
|
154
|
+
"darwin-arm64": "darwin-arm64",
|
155
|
+
}
|
156
|
+
|
157
|
+
|
158
|
+
# Mapping from other platforms to extension target platform used in download URLs
|
159
|
+
_extension_platform_mapping: Final[Mapping[str, str]] = {
|
160
|
+
"linux-x64": "linux-x64",
|
161
|
+
"alpine-x64": "linux-x64",
|
162
|
+
"linux-deb-x64": "linux-x64",
|
163
|
+
"linux-rpm-x64": "linux-x64",
|
164
|
+
"linux-arm64": "linux-arm64",
|
165
|
+
"alpine-arm64": "linux-arm64",
|
166
|
+
"linux-deb-arm64": "linux-arm64",
|
167
|
+
"linux-rpm-arm64": "linux-arm64",
|
168
|
+
"linux-armhf": "linux-armhf",
|
169
|
+
"linux-deb-armhf": "linux-armhf",
|
170
|
+
"linux-rpm-armhf": "linux-armhf",
|
88
171
|
"win32-x64": "win32-x64",
|
172
|
+
"win32-x64-user": "win32-x64",
|
173
|
+
"win32-x64-archive": "win32-x64",
|
174
|
+
"win32-arm64": "win32-arm64",
|
175
|
+
"win32-arm64-user": "win32-arm64",
|
176
|
+
"win32-arm64-archive": "win32-arm64",
|
177
|
+
"darwin": "darwin-x64",
|
178
|
+
"darwin-x64": "darwin-x64",
|
179
|
+
"darwin-arm64": "darwin-arm64",
|
89
180
|
}
|
90
181
|
|
91
182
|
|
183
|
+
def get_client_platform(platform: str) -> str:
|
184
|
+
"""Get the VS Code platform for the given platform."""
|
185
|
+
return _client_platform_mapping.get(platform, platform)
|
186
|
+
|
187
|
+
|
188
|
+
def get_server_platform(platform: str) -> str:
|
189
|
+
"""Get the VS Code server platform for the given platform."""
|
190
|
+
return _server_platform_mapping.get(platform, platform)
|
191
|
+
|
192
|
+
|
92
193
|
def get_cli_platform(platform: str) -> str:
|
93
|
-
"""Get the
|
94
|
-
|
95
|
-
|
96
|
-
|
194
|
+
"""Get the VS Code CLI platform for the given platform."""
|
195
|
+
return _cli_platform_mapping.get(platform, platform)
|
196
|
+
|
197
|
+
|
198
|
+
def get_extension_platform(platform: str) -> str:
|
199
|
+
"""Get the VS Code extension target platform for the given platform."""
|
200
|
+
return _extension_platform_mapping.get(platform, platform)
|
201
|
+
|
202
|
+
|
203
|
+
_all_platforms: Final[AbstractSet[str]] = {
|
204
|
+
*_client_platform_mapping.keys(),
|
205
|
+
*_client_platform_mapping.values(),
|
206
|
+
*_server_platform_mapping.keys(),
|
207
|
+
*_server_platform_mapping.values(),
|
208
|
+
*_cli_platform_mapping.keys(),
|
209
|
+
*_cli_platform_mapping.values(),
|
210
|
+
*_extension_platform_mapping.keys(),
|
211
|
+
*_extension_platform_mapping.values(),
|
212
|
+
}
|
213
|
+
|
214
|
+
|
215
|
+
assert (
|
216
|
+
_client_platform_mapping.keys()
|
217
|
+
== _server_platform_mapping.keys()
|
218
|
+
== _cli_platform_mapping.keys()
|
219
|
+
== _extension_platform_mapping.keys()
|
220
|
+
== _all_platforms
|
221
|
+
)
|
222
|
+
|
223
|
+
|
224
|
+
def validate_platform(platform: str) -> str:
|
225
|
+
"""Check if the given platform is a valid VS Code platform."""
|
226
|
+
if platform in _all_platforms:
|
227
|
+
return platform
|
228
|
+
raise ArgumentTypeError(f"Unsupported platform: {platform!r}")
|
97
229
|
|
98
230
|
|
99
231
|
def get_host_platform() -> str:
|
@@ -110,10 +242,12 @@ def get_host_platform() -> str:
|
|
110
242
|
return "linux-x64"
|
111
243
|
elif machine in ("aarch64", "arm64"):
|
112
244
|
return "linux-arm64"
|
245
|
+
elif machine in ("armv7l", "armhf"):
|
246
|
+
return "linux-armhf"
|
113
247
|
raise ValueError(f"Unsupported host platform: {osname}-{machine}")
|
114
248
|
|
115
249
|
|
116
|
-
def
|
250
|
+
def extract_filename_from_headers(headers: Mapping[str, str]) -> str | None:
|
117
251
|
"""Get the filename from HTTP headers.
|
118
252
|
|
119
253
|
Args:
|
@@ -0,0 +1,137 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: vscode-offline
|
3
|
+
Version: 0.1.8
|
4
|
+
Summary: Download and install VS Code for offline environments
|
5
|
+
Project-URL: Homepage, https://github.com/fanck0605/vscode-offline
|
6
|
+
Author-email: Chuck Fan <fanck0605@qq.com>
|
7
|
+
License-Expression: MIT
|
8
|
+
License-File: LICENSE
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
10
|
+
Classifier: Intended Audience :: Developers
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
12
|
+
Classifier: Operating System :: Microsoft :: Windows
|
13
|
+
Classifier: Operating System :: POSIX :: Linux
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
20
|
+
Classifier: Topic :: Utilities
|
21
|
+
Requires-Python: >=3.9
|
22
|
+
Description-Content-Type: text/markdown
|
23
|
+
|
24
|
+
# vscode-offline
|
25
|
+
|
26
|
+
[](https://github.com/fanck0605/vscode-offline/actions/workflows/build.yml)
|
27
|
+
[](https://github.com/astral-sh/ruff)
|
28
|
+
[](https://pypi.org/project/vscode-offline/)
|
29
|
+
[](https://github.com/fanck0605/vscode-offline/blob/master/LICENSE)
|
30
|
+
|
31
|
+
**vscode-offline** 主要用于在无网环境下安装 VS Code 和 VS Code Server,方便使用 [Remote - SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) 插件进行远程开发。
|
32
|
+
|
33
|
+
## 安装
|
34
|
+
|
35
|
+
```shell
|
36
|
+
pip install -U vscode-offline
|
37
|
+
```
|
38
|
+
|
39
|
+
## 优势
|
40
|
+
|
41
|
+
1. 自动识别并下载所有 `.vsix` 文件(包括间接依赖)
|
42
|
+
2. 一键安装 VS Code Server 以及其所有插件
|
43
|
+
|
44
|
+
## VS Code 离线安装
|
45
|
+
|
46
|
+
(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) 等。
|
47
|
+
|
48
|
+
(2)执行如下命令,下载 VS Code 安装包,和目前安装的所有的插件
|
49
|
+
|
50
|
+
```shell
|
51
|
+
vscode-offline download-all --client-platform win32-x64 --server-platform linux-x64
|
52
|
+
```
|
53
|
+
|
54
|
+
(3)复制 `./vscode-offline-installer` 到内网 Windows 机器,安装 `./vscode-offline-installer/<version>` 下的 VS Code,然后执行如下命令安装所有插件
|
55
|
+
|
56
|
+
```shell
|
57
|
+
vscode-offline install-extensions --installer ./vscode-offline-installer
|
58
|
+
```
|
59
|
+
|
60
|
+
(4)复制 `./vscode-offline-installer` 到内网 Linux 服务器,执行如下命令安装 VS Code Server 和所有插件
|
61
|
+
|
62
|
+
```shell
|
63
|
+
vscode-offline install-server --installer ./vscode-offline-installer
|
64
|
+
```
|
65
|
+
|
66
|
+
## 指定 VS Code 版本号
|
67
|
+
|
68
|
+
如果你想下载或安装指定版本的 VS Code,可以先通过 `code --version` 获取当前版本,然后通过 --code-version 参数指定版本号,例如:
|
69
|
+
|
70
|
+
```shell
|
71
|
+
vscode-offline download-all --code-version 1.104.3
|
72
|
+
```
|
73
|
+
|
74
|
+
也支持使用 commit hash 作为版本号,例如:
|
75
|
+
|
76
|
+
```shell
|
77
|
+
vscode-offline download-all --code-version commit:385651c938df8a906869babee516bffd0ddb9829
|
78
|
+
```
|
79
|
+
|
80
|
+
|
81
|
+
## 文件下载地址
|
82
|
+
|
83
|
+
如果你不想使用 `vscode-offline`,也可以手动下载对应的文件。
|
84
|
+
|
85
|
+
VS Code / VS Code Server / VS Code CLI 下载地址格式:
|
86
|
+
|
87
|
+
```shell
|
88
|
+
curl -O https://update.code.visualstudio.com/<version>/<platform>/stable
|
89
|
+
curl -O https://update.code.visualstudio.com/commit:<commit>/<platform>/stable
|
90
|
+
|
91
|
+
# 比如
|
92
|
+
curl -O https://update.code.visualstudio.com/1.104.3/cli-alpine-x64/stable
|
93
|
+
curl -O https://update.code.visualstudio.com/commit:385651c938df8a906869babee516bffd0ddb9829/win32-x64/stable
|
94
|
+
```
|
95
|
+
|
96
|
+
|
97
|
+
VS Code Extension 下载地址格式:
|
98
|
+
|
99
|
+
```shell
|
100
|
+
curl -O https://marketplace.visualstudio.com/_apis/public/gallery/publishers/<publisher>/vsextensions/<extension>/<version>/vspackage?targetPlatform=<platform>
|
101
|
+
|
102
|
+
# 比如
|
103
|
+
curl -O https://marketplace.visualstudio.com/_apis/public/gallery/publishers/ms-python/vsextensions/python/2025.14.0/vspackage?targetPlatform=linux-x64
|
104
|
+
```
|
105
|
+
|
106
|
+
Platform 映射关系:
|
107
|
+
|
108
|
+
| VS Code | VS Code Server | VS Code CLI | VS Code Extension |
|
109
|
+
| ------------------- | ------------------- | ---------------- | ----------------- |
|
110
|
+
| win32-x64 | server-win32-x64 | cli-win32-x64 | win32-x64 |
|
111
|
+
| win32-x64-user | server-win32-x64 | cli-win32-x64 | win32-x64 |
|
112
|
+
| win32-x64-archive | server-win32-x64 | cli-win32-x64 | win32-x64 |
|
113
|
+
| win32-arm64 | server-win32-arm64 | cli-win32-arm64 | win32-arm64 |
|
114
|
+
| win32-arm64-user | server-win32-arm64 | cli-win32-arm64 | win32-arm64 |
|
115
|
+
| win32-arm64-archive | server-win32-arm64 | cli-win32-arm64 | win32-arm64 |
|
116
|
+
| linux-x64 | server-linux-x64 | cli-alpine-x64 | linux-x64 |
|
117
|
+
| linux-deb-x64 | server-linux-x64 | cli-alpine-x64 | linux-x64 |
|
118
|
+
| linux-rpm-x64 | server-linux-x64 | cli-alpine-x64 | linux-x64 |
|
119
|
+
| linux-arm64 | server-linux-arm64 | cli-alpine-arm64 | linux-arm64 |
|
120
|
+
| linux-deb-arm64 | server-linux-arm64 | cli-alpine-arm64 | linux-arm64 |
|
121
|
+
| linux-rpm-arm64 | server-linux-arm64 | cli-alpine-arm64 | linux-arm64 |
|
122
|
+
| linux-armhf | server-linux-armhf | cli-linux-armhf | linux-armhf |
|
123
|
+
| linux-deb-armhf | server-linux-armhf | cli-linux-armhf | linux-armhf |
|
124
|
+
| linux-rpm-armhf | server-linux-armhf | cli-linux-armhf | linux-armhf |
|
125
|
+
| darwin | server-darwin | cli-darwin-x64 | darwin-x64 |
|
126
|
+
| darwin-arm64 | server-darwin-arm64 | cli-darwin-arm64 | darwin-arm64 |
|
127
|
+
|
128
|
+
|
129
|
+
## 贡献
|
130
|
+
|
131
|
+
欢迎提交 Issue 和 PR 改进本项目。
|
132
|
+
|
133
|
+
## License
|
134
|
+
|
135
|
+
Copyright (c) 2025 Chuck Fan.
|
136
|
+
|
137
|
+
Distributed under the terms of the [MIT License](https://github.com/fanck0605/vscode-offline/blob/master/LICENSE).
|
@@ -0,0 +1,13 @@
|
|
1
|
+
vscode_offline/__init__.py,sha256=-TweZdViMkxGYKEAvUN-6g0oUKnKapeC8ytTsWgxjRk,210
|
2
|
+
vscode_offline/_version.py,sha256=Zaz3s9gl_rzsS46-ymJOALojMxviW77EJq_agE8knLk,704
|
3
|
+
vscode_offline/app.py,sha256=XMq400ghmtlaTfLbtTTI7TRk56ZOjFTd6VzIRGDQl60,9951
|
4
|
+
vscode_offline/download.py,sha256=l10xenEUoE4rp4Uy1lWHjy_cYGYWFLwPeJ81oLrV3PQ,6060
|
5
|
+
vscode_offline/install.py,sha256=plZxKrlwy5FgyEAtDWRt0ZfvPWTB2tMRf54_kzVK5h0,4320
|
6
|
+
vscode_offline/loggers.py,sha256=vX91NMtNo1xfxq5y4BCtm_uhCTKtCODqBJHNvcT7JdQ,104
|
7
|
+
vscode_offline/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
+
vscode_offline/utils.py,sha256=YhDydIllSMSJfICJLqmdiIcKfEihct63woVFBGj80Ew,8581
|
9
|
+
vscode_offline-0.1.8.dist-info/METADATA,sha256=KDQK_DgRiBov3RnjC1txFVIlCVHa4gedFH22qoyIVEQ,6050
|
10
|
+
vscode_offline-0.1.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
11
|
+
vscode_offline-0.1.8.dist-info/entry_points.txt,sha256=XyuZLe7bgm2RmZp9oh9qCxcrAwHypD8XrTnm4G0_CzM,55
|
12
|
+
vscode_offline-0.1.8.dist-info/licenses/LICENSE,sha256=pUIXFkLeTS986b7dopOVLyuw72fJsUxhl8H3rEMIycA,1053
|
13
|
+
vscode_offline-0.1.8.dist-info/RECORD,,
|
@@ -1,83 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: vscode-offline
|
3
|
-
Version: 0.1.6
|
4
|
-
Summary: Download and install VS Code Server for offline environments
|
5
|
-
Project-URL: Homepage, https://github.com/fanck0605/vscode-offline
|
6
|
-
Author-email: Chuck Fan <fanck0605@qq.com>
|
7
|
-
License-Expression: MIT
|
8
|
-
License-File: LICENSE
|
9
|
-
Classifier: Development Status :: 4 - Beta
|
10
|
-
Classifier: Intended Audience :: Developers
|
11
|
-
Classifier: License :: OSI Approved :: MIT License
|
12
|
-
Classifier: Operating System :: Microsoft :: Windows
|
13
|
-
Classifier: Operating System :: POSIX :: Linux
|
14
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
15
|
-
Classifier: Programming Language :: Python :: 3.9
|
16
|
-
Classifier: Programming Language :: Python :: 3.10
|
17
|
-
Classifier: Programming Language :: Python :: 3.11
|
18
|
-
Classifier: Programming Language :: Python :: 3.12
|
19
|
-
Classifier: Programming Language :: Python :: 3.13
|
20
|
-
Classifier: Topic :: Utilities
|
21
|
-
Requires-Python: >=3.9
|
22
|
-
Description-Content-Type: text/markdown
|
23
|
-
|
24
|
-
# vscode-offline
|
25
|
-
|
26
|
-
vscode-offline 主要用于在无网环境下安装 VS Code Server,方便使用 *Remote - SSH* 插件进行远程开发。
|
27
|
-
|
28
|
-
## 安装
|
29
|
-
|
30
|
-
```shell
|
31
|
-
pip install -U vscode-offline
|
32
|
-
```
|
33
|
-
|
34
|
-
## 优势
|
35
|
-
|
36
|
-
1. 自动识别并下载所有 `.vsix` 文件(包括间接依赖)
|
37
|
-
2. 一键安装 VS Code Server 以及所有插件
|
38
|
-
|
39
|
-
## VS Code 离线安装
|
40
|
-
|
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
|
-
|
43
|
-
(2)执行如下命令,下载 VS Code 安装包,和目前安装的所有的插件
|
44
|
-
|
45
|
-
```shell
|
46
|
-
vscode-offline download-all --installer ./vscode-offline-installer
|
47
|
-
```
|
48
|
-
|
49
|
-
(3)复制 `./vscode-offline-installer` 到内网 Windows 机器,安装 `client-<version>` 下的 VS Code,然后执行如下命令安装所有插件
|
50
|
-
|
51
|
-
```shell
|
52
|
-
vscode-offline install-extensions --installer ./vscode-offline-installer
|
53
|
-
```
|
54
|
-
|
55
|
-
(4)复制 `./vscode-offline-installer` 到内网 Linux 服务器,执行如下命令安装 VS Code Server 和所有插件
|
56
|
-
|
57
|
-
```shell
|
58
|
-
vscode-offline install-server --installer ./vscode-offline-installer
|
59
|
-
```
|
60
|
-
|
61
|
-
## 指定 VS Code 版本号
|
62
|
-
|
63
|
-
如果你想下载或安装指定版本的 VS Code,可以先通过 `code --version` 获取当前版本,然后通过 --code-version 参数指定版本号,例如:
|
64
|
-
|
65
|
-
```shell
|
66
|
-
vscode-offline download-all --code-version 1.104.3
|
67
|
-
```
|
68
|
-
|
69
|
-
也支持使用 commit hash 作为版本号,例如:
|
70
|
-
|
71
|
-
```shell
|
72
|
-
vscode-offline download-all --code-version commit:385651c938df8a906869babee516bffd0ddb9829
|
73
|
-
```
|
74
|
-
|
75
|
-
## 贡献
|
76
|
-
|
77
|
-
欢迎提交 Issue 和 PR 改进本项目。
|
78
|
-
|
79
|
-
## License
|
80
|
-
|
81
|
-
Copyright (c) 2025 Chuck Fan.
|
82
|
-
|
83
|
-
Distributed under the terms of the [MIT License](https://github.com/fanck0605/vscode-offline/blob/master/LICENSE).
|
@@ -1,11 +0,0 @@
|
|
1
|
-
vscode_offline/__init__.py,sha256=dr6Jtj0XT9eQEC4fzNigEYsAIEfCsaom3HDbUsS-2O4,57
|
2
|
-
vscode_offline/app.py,sha256=Rm-uSkJrRmJVmyjiubPpRQTofttQdTADsGyEeZDSeY0,9142
|
3
|
-
vscode_offline/download.py,sha256=blu2WjG8zhuBrHrrV-v-FUf2fXbIt7fVSX8DoUX_Ikk,5442
|
4
|
-
vscode_offline/install.py,sha256=plZxKrlwy5FgyEAtDWRt0ZfvPWTB2tMRf54_kzVK5h0,4320
|
5
|
-
vscode_offline/loggers.py,sha256=vX91NMtNo1xfxq5y4BCtm_uhCTKtCODqBJHNvcT7JdQ,104
|
6
|
-
vscode_offline/utils.py,sha256=vpVSmE4JN0O-ezpzNJo9R9Y3YjzmzslhRVTG5H_-We0,4038
|
7
|
-
vscode_offline-0.1.6.dist-info/METADATA,sha256=UPt5DA0VlejIxNXCWUCztcKc36pacYF6I_mN6SnW98s,2803
|
8
|
-
vscode_offline-0.1.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
9
|
-
vscode_offline-0.1.6.dist-info/entry_points.txt,sha256=XyuZLe7bgm2RmZp9oh9qCxcrAwHypD8XrTnm4G0_CzM,55
|
10
|
-
vscode_offline-0.1.6.dist-info/licenses/LICENSE,sha256=pUIXFkLeTS986b7dopOVLyuw72fJsUxhl8H3rEMIycA,1053
|
11
|
-
vscode_offline-0.1.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|