ruyi 0.45.0__py3-none-any.whl → 0.45.0a20251230__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.
- ruyi/__main__.py +4 -16
- ruyi/cli/cmd.py +5 -6
- ruyi/cli/config_cli.py +11 -14
- ruyi/cli/main.py +4 -14
- ruyi/cli/oobe.py +3 -7
- ruyi/cli/self_cli.py +34 -48
- ruyi/cli/user_input.py +12 -42
- ruyi/cli/version_cli.py +5 -11
- ruyi/config/__init__.py +2 -26
- ruyi/config/errors.py +7 -19
- ruyi/device/provision.py +55 -116
- ruyi/device/provision_cli.py +3 -6
- ruyi/log/__init__.py +5 -6
- ruyi/mux/runtime.py +6 -19
- ruyi/mux/venv/maker.py +35 -93
- ruyi/mux/venv/venv_cli.py +10 -13
- ruyi/pluginhost/plugin_cli.py +3 -4
- ruyi/resource_bundle/__init__.py +8 -22
- ruyi/resource_bundle/__main__.py +5 -6
- ruyi/resource_bundle/data.py +9 -13
- ruyi/ruyipkg/admin_checksum.py +1 -4
- ruyi/ruyipkg/admin_cli.py +6 -9
- ruyi/ruyipkg/augmented_pkg.py +14 -15
- ruyi/ruyipkg/checksum.py +2 -8
- ruyi/ruyipkg/distfile.py +9 -33
- ruyi/ruyipkg/entity.py +2 -12
- ruyi/ruyipkg/entity_cli.py +12 -20
- ruyi/ruyipkg/entity_provider.py +2 -11
- ruyi/ruyipkg/fetcher.py +9 -38
- ruyi/ruyipkg/install.py +42 -143
- ruyi/ruyipkg/install_cli.py +15 -18
- ruyi/ruyipkg/list.py +20 -27
- ruyi/ruyipkg/list_cli.py +7 -12
- ruyi/ruyipkg/news.py +11 -23
- ruyi/ruyipkg/news_cli.py +7 -10
- ruyi/ruyipkg/profile_cli.py +2 -8
- ruyi/ruyipkg/repo.py +8 -22
- ruyi/ruyipkg/unpack.py +8 -42
- ruyi/ruyipkg/unpack_method.py +1 -5
- ruyi/ruyipkg/update_cli.py +3 -8
- ruyi/telemetry/provider.py +29 -74
- ruyi/telemetry/telemetry_cli.py +8 -9
- ruyi/utils/git.py +11 -18
- ruyi/utils/prereqs.py +5 -10
- ruyi/utils/ssl_patch.py +1 -2
- ruyi/version.py +3 -9
- {ruyi-0.45.0.dist-info → ruyi-0.45.0a20251230.dist-info}/METADATA +1 -2
- ruyi-0.45.0a20251230.dist-info/RECORD +102 -0
- {ruyi-0.45.0.dist-info → ruyi-0.45.0a20251230.dist-info}/WHEEL +1 -1
- ruyi/i18n/__init__.py +0 -129
- ruyi-0.45.0.dist-info/RECORD +0 -103
- {ruyi-0.45.0.dist-info → ruyi-0.45.0a20251230.dist-info}/entry_points.txt +0 -0
- {ruyi-0.45.0.dist-info → ruyi-0.45.0a20251230.dist-info}/licenses/LICENSE-Apache.txt +0 -0
ruyi/mux/runtime.py
CHANGED
|
@@ -5,7 +5,6 @@ import shlex
|
|
|
5
5
|
from typing import Final, List, NoReturn
|
|
6
6
|
|
|
7
7
|
from ..config import GlobalConfig
|
|
8
|
-
from ..i18n import _
|
|
9
8
|
from ..utils.global_mode import ProvidesGlobalMode
|
|
10
9
|
from .venv_cfg import RuyiVenvConfig
|
|
11
10
|
|
|
@@ -32,8 +31,8 @@ def mux_main(
|
|
|
32
31
|
|
|
33
32
|
vcfg = RuyiVenvConfig.load_from_venv(gm, logger)
|
|
34
33
|
if vcfg is None:
|
|
35
|
-
logger.F(
|
|
36
|
-
logger.I(
|
|
34
|
+
logger.F("the Ruyi toolchain mux is not configured")
|
|
35
|
+
logger.I("check out `ruyi venv` for making a virtual environment")
|
|
37
36
|
return 1
|
|
38
37
|
|
|
39
38
|
direct_symlink_target = resolve_direct_symlink_target(gm.argv0, vcfg)
|
|
@@ -61,11 +60,7 @@ def mux_main(
|
|
|
61
60
|
tgt_data = vcfg.targets.get(target_tuple)
|
|
62
61
|
if tgt_data is None:
|
|
63
62
|
logger.F(
|
|
64
|
-
|
|
65
|
-
"internal error: no target data for tuple [yellow]{target_tuple}[/]"
|
|
66
|
-
).format(
|
|
67
|
-
target_tuple=target_tuple,
|
|
68
|
-
)
|
|
63
|
+
f"internal error: no target data for tuple [yellow]{target_tuple}[/]"
|
|
69
64
|
)
|
|
70
65
|
return 1
|
|
71
66
|
toolchain_sysroot = tgt_data.get("toolchain_sysroot")
|
|
@@ -88,22 +83,14 @@ def mux_main(
|
|
|
88
83
|
if toolchain_bindir is None:
|
|
89
84
|
# should not happen
|
|
90
85
|
logger.F(
|
|
91
|
-
|
|
92
|
-
"internal error: no bindir configured for target [yellow]{target_tuple}[/]"
|
|
93
|
-
).format(
|
|
94
|
-
target_tuple=target_tuple,
|
|
95
|
-
)
|
|
86
|
+
f"internal error: no bindir configured for target [yellow]{target_tuple}[/]"
|
|
96
87
|
)
|
|
97
88
|
return 1
|
|
98
89
|
|
|
99
90
|
binpath = os.path.join(toolchain_bindir, basename)
|
|
100
91
|
|
|
101
92
|
if target_tuple is None:
|
|
102
|
-
logger.F(
|
|
103
|
-
_("no configured target found for command [yellow]{basename}[/]").format(
|
|
104
|
-
basename=basename,
|
|
105
|
-
)
|
|
106
|
-
)
|
|
93
|
+
logger.F(f"no configured target found for command [yellow]{basename}[/]")
|
|
107
94
|
return 1
|
|
108
95
|
|
|
109
96
|
logger.D(f"binary to exec: {binpath}")
|
|
@@ -189,7 +176,7 @@ def mux_qemu_main(
|
|
|
189
176
|
logger = gc.logger
|
|
190
177
|
binpath = vcfg.qemu_bin
|
|
191
178
|
if binpath is None:
|
|
192
|
-
logger.F(
|
|
179
|
+
logger.F("this virtual environment has no QEMU-like emulator configured")
|
|
193
180
|
return 1
|
|
194
181
|
|
|
195
182
|
if vcfg.profile_emu_env is not None:
|
ruyi/mux/venv/maker.py
CHANGED
|
@@ -7,13 +7,11 @@ import shutil
|
|
|
7
7
|
from typing import Any, Final, Iterator, TypedDict
|
|
8
8
|
|
|
9
9
|
from ...config import GlobalConfig
|
|
10
|
-
from ...i18n import _
|
|
11
10
|
from ...log import RuyiLogger, humanize_list
|
|
12
11
|
from ...ruyipkg.atom import Atom
|
|
13
12
|
from ...ruyipkg.pkg_manifest import BoundPackageManifest, EmulatorProgDecl
|
|
14
13
|
from ...ruyipkg.profile import ProfileProxy
|
|
15
14
|
from ...utils.global_mode import ProvidesGlobalMode
|
|
16
|
-
from ...utils.l10n import match_lang_code
|
|
17
15
|
from ...utils.templating import render_template_str
|
|
18
16
|
from .emulator_cfg import ResolvedEmulatorProg
|
|
19
17
|
|
|
@@ -69,7 +67,7 @@ def do_make_venv(
|
|
|
69
67
|
# this should come after implementation of local state cache
|
|
70
68
|
if tc_atoms_str is None:
|
|
71
69
|
logger.F(
|
|
72
|
-
|
|
70
|
+
"You have to specify at least one toolchain atom for now, e.g. [yellow]`-t gnu-plct`[/]"
|
|
73
71
|
)
|
|
74
72
|
return 1
|
|
75
73
|
|
|
@@ -77,7 +75,7 @@ def do_make_venv(
|
|
|
77
75
|
|
|
78
76
|
profile = mr.get_profile(profile_name)
|
|
79
77
|
if profile is None:
|
|
80
|
-
logger.F(
|
|
78
|
+
logger.F(f"profile '{profile_name}' not found")
|
|
81
79
|
return 1
|
|
82
80
|
|
|
83
81
|
target_arch = ""
|
|
@@ -95,46 +93,32 @@ def do_make_venv(
|
|
|
95
93
|
tc_atom = Atom.parse(tc_atom_str)
|
|
96
94
|
tc_pm = tc_atom.match_in_repo(mr, config.include_prereleases)
|
|
97
95
|
if tc_pm is None:
|
|
98
|
-
logger.F(
|
|
99
|
-
atom=tc_atom_str,
|
|
100
|
-
))
|
|
96
|
+
logger.F(f"cannot match a toolchain package with [yellow]{tc_atom_str}[/]")
|
|
101
97
|
return 1
|
|
102
98
|
|
|
103
99
|
if tc_pm.toolchain_metadata is None:
|
|
104
|
-
logger.F(
|
|
105
|
-
atom=tc_atom_str,
|
|
106
|
-
))
|
|
100
|
+
logger.F(f"the package [yellow]{tc_atom_str}[/] is not a toolchain")
|
|
107
101
|
return 1
|
|
108
102
|
|
|
109
103
|
if not tc_pm.toolchain_metadata.satisfies_quirk_set(profile.need_quirks):
|
|
110
|
-
logger.F(
|
|
111
|
-
"the package [yellow]{
|
|
112
|
-
).format(
|
|
113
|
-
atom=tc_atom_str,
|
|
114
|
-
profile=profile_name,
|
|
115
|
-
)
|
|
104
|
+
logger.F(
|
|
105
|
+
f"the package [yellow]{tc_atom_str}[/] does not support all necessary features for the profile [yellow]{profile_name}[/]"
|
|
116
106
|
)
|
|
117
107
|
logger.I(
|
|
118
|
-
|
|
119
|
-
humanized_list=humanize_list(profile.need_quirks, item_color='cyan'),
|
|
120
|
-
)
|
|
108
|
+
f"quirks needed by profile: {humanize_list(profile.need_quirks, item_color='cyan')}"
|
|
121
109
|
)
|
|
122
110
|
logger.I(
|
|
123
|
-
|
|
124
|
-
humanized_list=humanize_list(tc_pm.toolchain_metadata.quirks, item_color='yellow'),
|
|
125
|
-
)
|
|
111
|
+
f"quirks provided by package: {humanize_list(tc_pm.toolchain_metadata.quirks, item_color='yellow')}"
|
|
126
112
|
)
|
|
127
113
|
return 1
|
|
128
114
|
|
|
129
115
|
target_tuple = tc_pm.toolchain_metadata.target
|
|
130
116
|
if target_tuple in seen_target_tuples:
|
|
131
117
|
logger.F(
|
|
132
|
-
|
|
133
|
-
target_tuple=target_tuple,
|
|
134
|
-
)
|
|
118
|
+
f"the target tuple [yellow]{target_tuple}[/] is already covered by one of the requested toolchains"
|
|
135
119
|
)
|
|
136
120
|
logger.I(
|
|
137
|
-
|
|
121
|
+
"for now, only toolchains with differing target tuples can co-exist in one virtual environment"
|
|
138
122
|
)
|
|
139
123
|
return 1
|
|
140
124
|
|
|
@@ -143,7 +127,7 @@ def do_make_venv(
|
|
|
143
127
|
tc_pm.name_for_installation,
|
|
144
128
|
)
|
|
145
129
|
if toolchain_root is None:
|
|
146
|
-
logger.F(
|
|
130
|
+
logger.F("cannot find the installed directory for the toolchain")
|
|
147
131
|
return 1
|
|
148
132
|
|
|
149
133
|
tc_sysroot_dir: PathLike[Any] | None = None
|
|
@@ -155,7 +139,7 @@ def do_make_venv(
|
|
|
155
139
|
else:
|
|
156
140
|
if sysroot_atom_str is None:
|
|
157
141
|
logger.F(
|
|
158
|
-
|
|
142
|
+
"sysroot is requested but the toolchain package does not include one, and [yellow]--sysroot-from[/] is not given"
|
|
159
143
|
)
|
|
160
144
|
return 1
|
|
161
145
|
|
|
@@ -166,17 +150,13 @@ def do_make_venv(
|
|
|
166
150
|
gcc_pkg_pm = gcc_pkg_atom.match_in_repo(mr, config.include_prereleases)
|
|
167
151
|
if gcc_pkg_pm is None:
|
|
168
152
|
logger.F(
|
|
169
|
-
|
|
170
|
-
atom=sysroot_atom_str,
|
|
171
|
-
)
|
|
153
|
+
f"cannot match a toolchain package with [yellow]{sysroot_atom_str}[/]"
|
|
172
154
|
)
|
|
173
155
|
return 1
|
|
174
156
|
|
|
175
157
|
if gcc_pkg_pm.toolchain_metadata is None:
|
|
176
158
|
logger.F(
|
|
177
|
-
|
|
178
|
-
atom=sysroot_atom_str,
|
|
179
|
-
)
|
|
159
|
+
f"the package [yellow]{sysroot_atom_str}[/] is not a toolchain"
|
|
180
160
|
)
|
|
181
161
|
return 1
|
|
182
162
|
|
|
@@ -186,16 +166,14 @@ def do_make_venv(
|
|
|
186
166
|
)
|
|
187
167
|
if gcc_pkg_root is None:
|
|
188
168
|
logger.F(
|
|
189
|
-
|
|
169
|
+
"cannot find the installed directory for the sysroot package"
|
|
190
170
|
)
|
|
191
171
|
return 1
|
|
192
172
|
|
|
193
173
|
tc_sysroot_relpath = gcc_pkg_pm.toolchain_metadata.included_sysroot
|
|
194
174
|
if tc_sysroot_relpath is None:
|
|
195
175
|
logger.F(
|
|
196
|
-
|
|
197
|
-
atom=sysroot_atom_str,
|
|
198
|
-
)
|
|
176
|
+
f"sysroot is requested but the package [yellow]{sysroot_atom_str}[/] does not contain one"
|
|
199
177
|
)
|
|
200
178
|
return 1
|
|
201
179
|
|
|
@@ -213,7 +191,7 @@ def do_make_venv(
|
|
|
213
191
|
# for now, require this directory to be present (or clang would barely work)
|
|
214
192
|
if gcc_install_dir is None:
|
|
215
193
|
logger.F(
|
|
216
|
-
|
|
194
|
+
"cannot find a GCC include & lib directory in the sysroot package"
|
|
217
195
|
)
|
|
218
196
|
return 1
|
|
219
197
|
|
|
@@ -250,11 +228,9 @@ def do_make_venv(
|
|
|
250
228
|
warn_differing_target_arch = True
|
|
251
229
|
|
|
252
230
|
if warn_differing_target_arch:
|
|
253
|
-
logger.W(
|
|
231
|
+
logger.W("multiple toolchains specified with differing target architecture")
|
|
254
232
|
logger.I(
|
|
255
|
-
|
|
256
|
-
arch=target_arch,
|
|
257
|
-
)
|
|
233
|
+
f"using the target architecture of the first toolchain: [yellow]{target_arch}[/]"
|
|
258
234
|
)
|
|
259
235
|
|
|
260
236
|
# Now handle the emulator.
|
|
@@ -264,24 +240,17 @@ def do_make_venv(
|
|
|
264
240
|
emu_atom = Atom.parse(emu_atom_str)
|
|
265
241
|
emu_pm = emu_atom.match_in_repo(mr, config.include_prereleases)
|
|
266
242
|
if emu_pm is None:
|
|
267
|
-
logger.F(
|
|
268
|
-
atom=emu_atom_str,
|
|
269
|
-
))
|
|
243
|
+
logger.F(f"cannot match an emulator package with [yellow]{emu_atom_str}[/]")
|
|
270
244
|
return 1
|
|
271
245
|
|
|
272
246
|
if emu_pm.emulator_metadata is None:
|
|
273
|
-
logger.F(
|
|
274
|
-
atom=emu_atom_str,
|
|
275
|
-
))
|
|
247
|
+
logger.F(f"the package [yellow]{emu_atom_str}[/] is not an emulator")
|
|
276
248
|
return 1
|
|
277
249
|
|
|
278
250
|
emu_progs = list(emu_pm.emulator_metadata.list_for_arch(target_arch))
|
|
279
251
|
if not emu_progs:
|
|
280
252
|
logger.F(
|
|
281
|
-
|
|
282
|
-
atom=emu_atom_str,
|
|
283
|
-
arch=target_arch,
|
|
284
|
-
)
|
|
253
|
+
f"the emulator package [yellow]{emu_atom_str}[/] does not support the target architecture [yellow]{target_arch}[/]"
|
|
285
254
|
)
|
|
286
255
|
return 1
|
|
287
256
|
|
|
@@ -291,20 +260,13 @@ def do_make_venv(
|
|
|
291
260
|
emu_pm.emulator_metadata.quirks,
|
|
292
261
|
):
|
|
293
262
|
logger.F(
|
|
294
|
-
|
|
295
|
-
atom=emu_atom_str,
|
|
296
|
-
profile=profile_name,
|
|
297
|
-
)
|
|
263
|
+
f"the package [yellow]{emu_atom_str}[/] does not support all necessary features for the profile [yellow]{profile_name}[/]"
|
|
298
264
|
)
|
|
299
265
|
logger.I(
|
|
300
|
-
|
|
301
|
-
humanized_list=humanize_list(profile.get_needed_emulator_pkg_flavors(prog.flavor), item_color='cyan'),
|
|
302
|
-
)
|
|
266
|
+
f"quirks needed by profile: {humanize_list(profile.get_needed_emulator_pkg_flavors(prog.flavor), item_color='cyan')}"
|
|
303
267
|
)
|
|
304
268
|
logger.I(
|
|
305
|
-
|
|
306
|
-
humanized_list=humanize_list(emu_pm.emulator_metadata.quirks or [], item_color='yellow'),
|
|
307
|
-
)
|
|
269
|
+
f"quirks provided by package: {humanize_list(emu_pm.emulator_metadata.quirks or [], item_color='yellow')}"
|
|
308
270
|
)
|
|
309
271
|
return 1
|
|
310
272
|
|
|
@@ -313,7 +275,7 @@ def do_make_venv(
|
|
|
313
275
|
emu_pm.name_for_installation,
|
|
314
276
|
)
|
|
315
277
|
if emu_root is None:
|
|
316
|
-
logger.F(
|
|
278
|
+
logger.F("cannot find the installed directory for the emulator")
|
|
317
279
|
return 1
|
|
318
280
|
|
|
319
281
|
venv_metadata["emulator_pkgs"][target_arch] = _venv_pkg_info_from_pkg(emu_pm)
|
|
@@ -329,28 +291,21 @@ def do_make_venv(
|
|
|
329
291
|
)
|
|
330
292
|
if extra_cmd_pm is None:
|
|
331
293
|
logger.F(
|
|
332
|
-
|
|
333
|
-
atom=extra_cmd_atom_str,
|
|
334
|
-
)
|
|
294
|
+
f"cannot match an extra command package with [yellow]{extra_cmd_atom_str}[/]"
|
|
335
295
|
)
|
|
336
296
|
return 1
|
|
337
297
|
|
|
338
298
|
extra_cmd_bm = extra_cmd_pm.binary_metadata
|
|
339
299
|
if not extra_cmd_bm:
|
|
340
300
|
logger.F(
|
|
341
|
-
|
|
342
|
-
atom=extra_cmd_atom_str,
|
|
343
|
-
)
|
|
301
|
+
f"the package [yellow]{extra_cmd_atom_str}[/] is not a binary-providing package"
|
|
344
302
|
)
|
|
345
303
|
return 1
|
|
346
304
|
|
|
347
305
|
extra_cmds_decl = extra_cmd_bm.get_commands_for_host(host)
|
|
348
306
|
if not extra_cmds_decl:
|
|
349
307
|
logger.W(
|
|
350
|
-
|
|
351
|
-
atom=extra_cmd_atom_str,
|
|
352
|
-
host=host,
|
|
353
|
-
)
|
|
308
|
+
f"the package [yellow]{extra_cmd_atom_str}[/] does not provide any command for host [yellow]{host}[/], ignoring"
|
|
354
309
|
)
|
|
355
310
|
continue
|
|
356
311
|
|
|
@@ -360,9 +315,7 @@ def do_make_venv(
|
|
|
360
315
|
)
|
|
361
316
|
if cmd_root is None:
|
|
362
317
|
logger.F(
|
|
363
|
-
|
|
364
|
-
pkg=extra_cmd_pm.name_for_installation,
|
|
365
|
-
)
|
|
318
|
+
f"cannot find the installed directory for the package [yellow]{extra_cmd_pm.name_for_installation}[/]"
|
|
366
319
|
)
|
|
367
320
|
return 1
|
|
368
321
|
cmd_root = pathlib.Path(cmd_root)
|
|
@@ -376,7 +329,7 @@ def do_make_venv(
|
|
|
376
329
|
# we don't allow commands to resolve outside of the
|
|
377
330
|
# providing package's install root
|
|
378
331
|
logger.F(
|
|
379
|
-
|
|
332
|
+
"internal error: resolved command path is outside of the providing package"
|
|
380
333
|
)
|
|
381
334
|
return 1
|
|
382
335
|
|
|
@@ -385,17 +338,10 @@ def do_make_venv(
|
|
|
385
338
|
|
|
386
339
|
if override_name is not None:
|
|
387
340
|
logger.I(
|
|
388
|
-
|
|
389
|
-
name=override_name,
|
|
390
|
-
dest=dest,
|
|
391
|
-
)
|
|
341
|
+
f"Creating a Ruyi virtual environment [cyan]'{override_name}'[/] at [green]{dest}[/]..."
|
|
392
342
|
)
|
|
393
343
|
else:
|
|
394
|
-
logger.I(
|
|
395
|
-
_("Creating a Ruyi virtual environment at [green]{dest}[/]...").format(
|
|
396
|
-
dest=dest,
|
|
397
|
-
)
|
|
398
|
-
)
|
|
344
|
+
logger.I(f"Creating a Ruyi virtual environment at [green]{dest}[/]...")
|
|
399
345
|
|
|
400
346
|
maker = VenvMaker(
|
|
401
347
|
config,
|
|
@@ -410,11 +356,9 @@ def do_make_venv(
|
|
|
410
356
|
)
|
|
411
357
|
maker.provision()
|
|
412
358
|
|
|
413
|
-
# TODO: move the template to PO
|
|
414
|
-
locale = match_lang_code(config.lang_code, avail=("en", "zh_CN"))
|
|
415
359
|
logger.I(
|
|
416
360
|
render_template_str(
|
|
417
|
-
|
|
361
|
+
"prompt.venv-created.txt",
|
|
418
362
|
{
|
|
419
363
|
"sysroot": maker.sysroot_destdir(None),
|
|
420
364
|
},
|
|
@@ -615,9 +559,7 @@ class VenvMaker:
|
|
|
615
559
|
for cmd, dest in extra_cmds.items():
|
|
616
560
|
if cmd in cmd_metadata_map:
|
|
617
561
|
self.logger.W(
|
|
618
|
-
|
|
619
|
-
cmd=cmd,
|
|
620
|
-
)
|
|
562
|
+
f"extra command {cmd} is already provided by another package, overriding it"
|
|
621
563
|
)
|
|
622
564
|
cmd_metadata_map[cmd] = {
|
|
623
565
|
"dest": dest,
|
ruyi/mux/venv/venv_cli.py
CHANGED
|
@@ -3,7 +3,6 @@ import pathlib
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
5
|
from ...cli.cmd import RootCommand
|
|
6
|
-
from ...i18n import _
|
|
7
6
|
|
|
8
7
|
if TYPE_CHECKING:
|
|
9
8
|
from ...cli.completion import ArgumentParser
|
|
@@ -13,57 +12,55 @@ if TYPE_CHECKING:
|
|
|
13
12
|
class VenvCommand(
|
|
14
13
|
RootCommand,
|
|
15
14
|
cmd="venv",
|
|
16
|
-
help=
|
|
15
|
+
help="Generate a virtual environment adapted to the chosen toolchain and profile",
|
|
17
16
|
):
|
|
18
17
|
@classmethod
|
|
19
18
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
20
|
-
p.add_argument("profile", type=str, help=
|
|
21
|
-
|
|
22
|
-
p.add_argument("dest", type=str, help=_("Path to the new virtual environment"),
|
|
23
|
-
)
|
|
19
|
+
p.add_argument("profile", type=str, help="Profile to use for the environment")
|
|
20
|
+
p.add_argument("dest", type=str, help="Path to the new virtual environment")
|
|
24
21
|
p.add_argument(
|
|
25
22
|
"--name",
|
|
26
23
|
"-n",
|
|
27
24
|
type=str,
|
|
28
25
|
default=None,
|
|
29
|
-
help=
|
|
26
|
+
help="Override the venv's name",
|
|
30
27
|
)
|
|
31
28
|
p.add_argument(
|
|
32
29
|
"--toolchain",
|
|
33
30
|
"-t",
|
|
34
31
|
type=str,
|
|
35
32
|
action="append",
|
|
36
|
-
help=
|
|
33
|
+
help="Specifier(s) (atoms) of the toolchain package(s) to use",
|
|
37
34
|
)
|
|
38
35
|
p.add_argument(
|
|
39
36
|
"--emulator",
|
|
40
37
|
"-e",
|
|
41
38
|
type=str,
|
|
42
|
-
help=
|
|
39
|
+
help="Specifier (atom) of the emulator package to use",
|
|
43
40
|
)
|
|
44
41
|
p.add_argument(
|
|
45
42
|
"--with-sysroot",
|
|
46
43
|
action="store_true",
|
|
47
44
|
dest="with_sysroot",
|
|
48
45
|
default=True,
|
|
49
|
-
help=
|
|
46
|
+
help="Provision a fresh sysroot inside the new virtual environment (default)",
|
|
50
47
|
)
|
|
51
48
|
p.add_argument(
|
|
52
49
|
"--without-sysroot",
|
|
53
50
|
action="store_false",
|
|
54
51
|
dest="with_sysroot",
|
|
55
|
-
help=
|
|
52
|
+
help="Do not include a sysroot inside the new virtual environment",
|
|
56
53
|
)
|
|
57
54
|
p.add_argument(
|
|
58
55
|
"--sysroot-from",
|
|
59
56
|
type=str,
|
|
60
|
-
help=
|
|
57
|
+
help="Specifier (atom) of the sysroot package to use, in favor of the toolchain-included one if applicable",
|
|
61
58
|
)
|
|
62
59
|
p.add_argument(
|
|
63
60
|
"--extra-commands-from",
|
|
64
61
|
type=str,
|
|
65
62
|
action="append",
|
|
66
|
-
help=
|
|
63
|
+
help="Specifier(s) (atoms) of extra package(s) to add commands to the new virtual environment",
|
|
67
64
|
)
|
|
68
65
|
|
|
69
66
|
@classmethod
|
ruyi/pluginhost/plugin_cli.py
CHANGED
|
@@ -2,7 +2,6 @@ import argparse
|
|
|
2
2
|
from typing import TYPE_CHECKING
|
|
3
3
|
|
|
4
4
|
from ..cli.cmd import AdminCommand
|
|
5
|
-
from ..i18n import _
|
|
6
5
|
|
|
7
6
|
if TYPE_CHECKING:
|
|
8
7
|
from ..cli.completion import ArgumentParser
|
|
@@ -12,7 +11,7 @@ if TYPE_CHECKING:
|
|
|
12
11
|
class AdminRunPluginCommand(
|
|
13
12
|
AdminCommand,
|
|
14
13
|
cmd="run-plugin-cmd",
|
|
15
|
-
help=
|
|
14
|
+
help="Run a plugin-defined command",
|
|
16
15
|
):
|
|
17
16
|
@classmethod
|
|
18
17
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -20,14 +19,14 @@ class AdminRunPluginCommand(
|
|
|
20
19
|
"cmd_name",
|
|
21
20
|
type=str,
|
|
22
21
|
metavar="COMMAND-NAME",
|
|
23
|
-
help=
|
|
22
|
+
help="Command name",
|
|
24
23
|
)
|
|
25
24
|
p.add_argument(
|
|
26
25
|
"cmd_args",
|
|
27
26
|
type=str,
|
|
28
27
|
nargs="*",
|
|
29
28
|
metavar="COMMAND-ARG",
|
|
30
|
-
help=
|
|
29
|
+
help="Arguments to pass to the plugin command",
|
|
31
30
|
)
|
|
32
31
|
|
|
33
32
|
@classmethod
|
ruyi/resource_bundle/__init__.py
CHANGED
|
@@ -1,34 +1,20 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import zlib
|
|
3
3
|
|
|
4
|
-
from .data import RESOURCES,
|
|
4
|
+
from .data import RESOURCES, TEMPLATES
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
def _unpack_payload(x: bytes) ->
|
|
8
|
-
return zlib.decompress(base64.b64decode(x))
|
|
7
|
+
def _unpack_payload(x: bytes) -> str:
|
|
8
|
+
return zlib.decompress(base64.b64decode(x)).decode("utf-8")
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def get_resource_blob(name: str) -> bytes | None:
|
|
15
|
-
if t := RESOURCES.get(name):
|
|
16
|
-
if name not in _CACHE:
|
|
17
|
-
# In our use cases, the program is short-lived and involved resources
|
|
18
|
-
# are small in size, so it is fine to just store the decompressed
|
|
19
|
-
# blobs without eviction.
|
|
20
|
-
_CACHE[name] = _unpack_payload(t)
|
|
21
|
-
return _CACHE[name]
|
|
22
|
-
return None
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def get_resource_str(name: str) -> str | None:
|
|
26
|
-
if blob := get_resource_blob(name):
|
|
27
|
-
return blob.decode("utf-8")
|
|
11
|
+
def get_resource_str(template_name: str) -> str | None:
|
|
12
|
+
if t := RESOURCES.get(template_name):
|
|
13
|
+
return _unpack_payload(t)
|
|
28
14
|
return None
|
|
29
15
|
|
|
30
16
|
|
|
31
17
|
def get_template_str(template_name: str) -> str | None:
|
|
32
|
-
if t :=
|
|
33
|
-
return
|
|
18
|
+
if t := TEMPLATES.get(template_name):
|
|
19
|
+
return _unpack_payload(t)
|
|
34
20
|
return None
|
ruyi/resource_bundle/__main__.py
CHANGED
|
@@ -20,16 +20,15 @@ def main() -> None:
|
|
|
20
20
|
|
|
21
21
|
resources: dict[str, str] = {}
|
|
22
22
|
template_names: dict[str, str] = {}
|
|
23
|
-
for f in bundled_resource_root.
|
|
23
|
+
for f in bundled_resource_root.iterdir():
|
|
24
24
|
if not f.is_file():
|
|
25
25
|
continue
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
resources[str(rel_path)] = make_payload_from_file(f)
|
|
27
|
+
resources[f.name] = make_payload_from_file(f)
|
|
29
28
|
|
|
30
29
|
if f.suffix.lower() == ".jinja":
|
|
31
30
|
# strip the .jinja suffix for the template name
|
|
32
|
-
template_names[
|
|
31
|
+
template_names[f.stem] = f.name
|
|
33
32
|
|
|
34
33
|
with open(self_path / "data.py", "w", encoding="utf-8") as fp:
|
|
35
34
|
|
|
@@ -46,9 +45,9 @@ def main() -> None:
|
|
|
46
45
|
p(f' "{filename}": b"{payload}", # fmt: skip')
|
|
47
46
|
p("}\n")
|
|
48
47
|
|
|
49
|
-
p("
|
|
48
|
+
p("TEMPLATES: Final = {")
|
|
50
49
|
for stem, full_filename in sorted(template_names.items()):
|
|
51
|
-
p(f' "{stem}": "{full_filename}",')
|
|
50
|
+
p(f' "{stem}": RESOURCES["{full_filename}"],')
|
|
52
51
|
p("}")
|
|
53
52
|
|
|
54
53
|
|