ruyi 0.44.0b20251219__py3-none-any.whl → 0.45.0__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 +16 -4
- ruyi/cli/cmd.py +6 -5
- ruyi/cli/config_cli.py +14 -11
- ruyi/cli/main.py +14 -4
- ruyi/cli/oobe.py +7 -3
- ruyi/cli/self_cli.py +48 -34
- ruyi/cli/user_input.py +42 -12
- ruyi/cli/version_cli.py +11 -5
- ruyi/config/__init__.py +26 -2
- ruyi/config/errors.py +19 -7
- ruyi/device/provision.py +116 -55
- ruyi/device/provision_cli.py +6 -3
- ruyi/i18n/__init__.py +129 -0
- ruyi/log/__init__.py +6 -5
- ruyi/mux/runtime.py +19 -6
- ruyi/mux/venv/maker.py +93 -35
- ruyi/mux/venv/venv_cli.py +13 -10
- ruyi/pluginhost/plugin_cli.py +4 -3
- ruyi/resource_bundle/__init__.py +22 -8
- ruyi/resource_bundle/__main__.py +6 -5
- ruyi/resource_bundle/data.py +13 -9
- ruyi/ruyipkg/admin_checksum.py +4 -1
- ruyi/ruyipkg/admin_cli.py +9 -6
- ruyi/ruyipkg/augmented_pkg.py +15 -14
- ruyi/ruyipkg/checksum.py +8 -2
- ruyi/ruyipkg/distfile.py +33 -9
- ruyi/ruyipkg/entity.py +12 -2
- ruyi/ruyipkg/entity_cli.py +20 -12
- ruyi/ruyipkg/entity_provider.py +11 -2
- ruyi/ruyipkg/fetcher.py +38 -9
- ruyi/ruyipkg/install.py +143 -42
- ruyi/ruyipkg/install_cli.py +18 -15
- ruyi/ruyipkg/list.py +27 -20
- ruyi/ruyipkg/list_cli.py +12 -7
- ruyi/ruyipkg/news.py +23 -11
- ruyi/ruyipkg/news_cli.py +10 -7
- ruyi/ruyipkg/profile_cli.py +8 -2
- ruyi/ruyipkg/repo.py +22 -8
- ruyi/ruyipkg/unpack.py +42 -8
- ruyi/ruyipkg/unpack_method.py +5 -1
- ruyi/ruyipkg/update_cli.py +8 -3
- ruyi/telemetry/provider.py +74 -29
- ruyi/telemetry/telemetry_cli.py +9 -8
- ruyi/utils/git.py +18 -11
- ruyi/utils/prereqs.py +10 -5
- ruyi/utils/ssl_patch.py +2 -1
- ruyi/version.py +9 -3
- {ruyi-0.44.0b20251219.dist-info → ruyi-0.45.0.dist-info}/METADATA +2 -1
- ruyi-0.45.0.dist-info/RECORD +103 -0
- {ruyi-0.44.0b20251219.dist-info → ruyi-0.45.0.dist-info}/WHEEL +1 -1
- ruyi-0.44.0b20251219.dist-info/RECORD +0 -102
- {ruyi-0.44.0b20251219.dist-info → ruyi-0.45.0.dist-info}/entry_points.txt +0 -0
- {ruyi-0.44.0b20251219.dist-info → ruyi-0.45.0.dist-info}/licenses/LICENSE-Apache.txt +0 -0
ruyi/telemetry/provider.py
CHANGED
|
@@ -7,6 +7,7 @@ import time
|
|
|
7
7
|
from typing import Callable, TYPE_CHECKING, cast
|
|
8
8
|
import uuid
|
|
9
9
|
|
|
10
|
+
from ..i18n import _, d_
|
|
10
11
|
from ..log import RuyiLogger
|
|
11
12
|
from ..utils.node_info import NodeInfo, gather_node_info
|
|
12
13
|
from .scope import TelemetryScope
|
|
@@ -18,7 +19,8 @@ if TYPE_CHECKING:
|
|
|
18
19
|
|
|
19
20
|
FALLBACK_PM_TELEMETRY_ENDPOINT = "https://api.ruyisdk.cn/telemetry/pm/"
|
|
20
21
|
|
|
21
|
-
TELEMETRY_CONSENT_AND_UPLOAD_DESC =
|
|
22
|
+
TELEMETRY_CONSENT_AND_UPLOAD_DESC = d_(
|
|
23
|
+
"""
|
|
22
24
|
RuyiSDK collects minimal usage data in the form of just a version number of
|
|
23
25
|
the running [yellow]ruyi[/], to help us improve the product. With your consent,
|
|
24
26
|
RuyiSDK may also collect additional non-tracking usage data to be sent
|
|
@@ -35,11 +37,14 @@ team can better understand adoption. If you choose to opt out, this will be the
|
|
|
35
37
|
only data to be ever uploaded, without any tracking ID being generated or kept.
|
|
36
38
|
Thank you for helping us build a better experience!
|
|
37
39
|
"""
|
|
38
|
-
|
|
40
|
+
)
|
|
41
|
+
TELEMETRY_CONSENT_AND_UPLOAD_PROMPT = d_(
|
|
39
42
|
"Do you agree to have usage data periodically uploaded?"
|
|
40
43
|
)
|
|
41
|
-
TELEMETRY_OPTOUT_PROMPT = "\nDo you want to opt out of telemetry entirely?"
|
|
42
|
-
MALFORMED_TELEMETRY_STATE_MSG =
|
|
44
|
+
TELEMETRY_OPTOUT_PROMPT = d_("\nDo you want to opt out of telemetry entirely?")
|
|
45
|
+
MALFORMED_TELEMETRY_STATE_MSG = d_(
|
|
46
|
+
"malformed telemetry state: unable to determine upload weekday, nothing will be uploaded"
|
|
47
|
+
)
|
|
43
48
|
|
|
44
49
|
|
|
45
50
|
def next_utc_weekday(wday: int, now: float | None = None) -> int:
|
|
@@ -113,22 +118,28 @@ def set_telemetry_mode(
|
|
|
113
118
|
return
|
|
114
119
|
match mode:
|
|
115
120
|
case "on":
|
|
116
|
-
logger.I("telemetry data uploading is now enabled")
|
|
121
|
+
logger.I(_("telemetry data uploading is now enabled"))
|
|
117
122
|
logger.I(
|
|
118
|
-
|
|
123
|
+
_(
|
|
124
|
+
"you can opt out at any time by running [yellow]ruyi telemetry optout[/]"
|
|
125
|
+
)
|
|
119
126
|
)
|
|
120
127
|
case "local":
|
|
121
|
-
logger.I("telemetry mode is now set to local collection only")
|
|
128
|
+
logger.I(_("telemetry mode is now set to local collection only"))
|
|
122
129
|
logger.I(
|
|
123
|
-
|
|
130
|
+
_(
|
|
131
|
+
"you can re-enable telemetry data uploading at any time by running [yellow]ruyi telemetry consent[/]"
|
|
132
|
+
)
|
|
124
133
|
)
|
|
125
134
|
logger.I(
|
|
126
|
-
"or opt out at any time by running [yellow]ruyi telemetry optout[/]"
|
|
135
|
+
_("or opt out at any time by running [yellow]ruyi telemetry optout[/]")
|
|
127
136
|
)
|
|
128
137
|
case "off":
|
|
129
|
-
logger.I("telemetry data collection is now disabled")
|
|
138
|
+
logger.I(_("telemetry data collection is now disabled"))
|
|
130
139
|
logger.I(
|
|
131
|
-
|
|
140
|
+
_(
|
|
141
|
+
"you can re-enable telemetry data uploads at any time by running [yellow]ruyi telemetry consent[/]"
|
|
142
|
+
)
|
|
132
143
|
)
|
|
133
144
|
case _:
|
|
134
145
|
raise ValueError(f"invalid telemetry mode: {mode}")
|
|
@@ -316,30 +327,50 @@ class TelemetryProvider:
|
|
|
316
327
|
"%Y-%m-%d %H:%M:%S %z", time.localtime(last_upload_time)
|
|
317
328
|
)
|
|
318
329
|
self.logger.I(
|
|
319
|
-
|
|
330
|
+
_(
|
|
331
|
+
"scope {scope}: usage information has already been uploaded today at {last_upload_time_str}"
|
|
332
|
+
).format(
|
|
333
|
+
scope=scope,
|
|
334
|
+
last_upload_time_str=last_upload_time_str,
|
|
335
|
+
)
|
|
320
336
|
)
|
|
321
337
|
else:
|
|
322
338
|
self.logger.I(
|
|
323
|
-
|
|
339
|
+
_(
|
|
340
|
+
"scope {scope}: usage information has already been uploaded sometime today"
|
|
341
|
+
).format(
|
|
342
|
+
scope=scope,
|
|
343
|
+
)
|
|
324
344
|
)
|
|
325
345
|
else:
|
|
326
346
|
self.logger.I(
|
|
327
|
-
|
|
347
|
+
_(
|
|
348
|
+
"scope {scope}: the next upload will happen [bold green]today[/] if not already"
|
|
349
|
+
).format(
|
|
350
|
+
scope=scope,
|
|
351
|
+
)
|
|
328
352
|
)
|
|
329
353
|
else:
|
|
330
354
|
self.logger.I(
|
|
331
|
-
"the next upload will happen anytime [yellow]ruyi[/] is executed:"
|
|
355
|
+
_("the next upload will happen anytime [yellow]ruyi[/] is executed:")
|
|
332
356
|
)
|
|
333
357
|
self.logger.I(
|
|
334
|
-
|
|
358
|
+
_(
|
|
359
|
+
" - between [bold green]{time_start}[/] and [bold green]{time_end}[/]"
|
|
360
|
+
).format(
|
|
361
|
+
time_start=next_upload_day_str,
|
|
362
|
+
time_end=next_upload_day_end_str,
|
|
363
|
+
)
|
|
335
364
|
)
|
|
336
|
-
self.logger.I(" - or if the last upload is more than a week ago")
|
|
365
|
+
self.logger.I(_(" - or if the last upload is more than a week ago"))
|
|
337
366
|
|
|
338
367
|
def print_telemetry_notice(self, for_cli_verbose_output: bool = False) -> None:
|
|
339
368
|
if self.minimal:
|
|
340
369
|
if for_cli_verbose_output:
|
|
341
370
|
self.logger.I(
|
|
342
|
-
|
|
371
|
+
_(
|
|
372
|
+
"telemetry mode is [green]off[/]: nothing is collected or uploaded after the first run"
|
|
373
|
+
)
|
|
343
374
|
)
|
|
344
375
|
return
|
|
345
376
|
|
|
@@ -352,12 +383,14 @@ class TelemetryProvider:
|
|
|
352
383
|
self.logger.D(MALFORMED_TELEMETRY_STATE_MSG)
|
|
353
384
|
return
|
|
354
385
|
|
|
355
|
-
upload_wday_name =
|
|
386
|
+
upload_wday_name = self._gc.babel_locale.days["format"]["wide"][upload_wday]
|
|
356
387
|
|
|
357
388
|
if self.local_mode:
|
|
358
389
|
if for_cli_verbose_output:
|
|
359
390
|
self.logger.I(
|
|
360
|
-
|
|
391
|
+
_(
|
|
392
|
+
"telemetry mode is [green]local[/]: local usage collection only, no usage uploads except if requested"
|
|
393
|
+
)
|
|
361
394
|
)
|
|
362
395
|
return
|
|
363
396
|
|
|
@@ -367,22 +400,34 @@ class TelemetryProvider:
|
|
|
367
400
|
|
|
368
401
|
if for_cli_verbose_output:
|
|
369
402
|
self.logger.I(
|
|
370
|
-
|
|
403
|
+
_(
|
|
404
|
+
"telemetry mode is [green]on[/]: usage data is collected and periodically uploaded"
|
|
405
|
+
)
|
|
371
406
|
)
|
|
372
407
|
self.logger.I(
|
|
373
|
-
|
|
408
|
+
_(
|
|
409
|
+
"non-tracking usage information will be uploaded to RuyiSDK-managed servers [bold green]every {weekday}[/]"
|
|
410
|
+
).format(
|
|
411
|
+
weekday=upload_wday_name,
|
|
412
|
+
)
|
|
374
413
|
)
|
|
375
414
|
else:
|
|
376
415
|
self.logger.W(
|
|
377
|
-
|
|
416
|
+
_(
|
|
417
|
+
"this [yellow]ruyi[/] installation has telemetry mode set to [yellow]on[/], and [bold]will upload non-tracking usage information to RuyiSDK-managed servers[/] [bold green]every {weekday}[/]"
|
|
418
|
+
).format(
|
|
419
|
+
weekday=upload_wday_name,
|
|
420
|
+
)
|
|
378
421
|
)
|
|
379
422
|
|
|
380
423
|
self._print_upload_schedule_notice(upload_wday, now)
|
|
381
424
|
|
|
382
425
|
if not for_cli_verbose_output:
|
|
383
|
-
self.logger.I("in order to hide this banner:")
|
|
384
|
-
self.logger.I("- opt out with [yellow]ruyi telemetry optout[/]")
|
|
385
|
-
self.logger.I(
|
|
426
|
+
self.logger.I(_("in order to hide this banner:"))
|
|
427
|
+
self.logger.I(_(" - opt out with [yellow]ruyi telemetry optout[/]"))
|
|
428
|
+
self.logger.I(
|
|
429
|
+
_(" - or give consent with [yellow]ruyi telemetry consent[/]")
|
|
430
|
+
)
|
|
386
431
|
|
|
387
432
|
def _next_upload_day(self, time_now: float | None = None) -> int | None:
|
|
388
433
|
upload_wday = self._upload_weekday()
|
|
@@ -561,16 +606,16 @@ class TelemetryProvider:
|
|
|
561
606
|
|
|
562
607
|
from ..cli import user_input
|
|
563
608
|
|
|
564
|
-
self.logger.stdout(TELEMETRY_CONSENT_AND_UPLOAD_DESC)
|
|
609
|
+
self.logger.stdout(_(TELEMETRY_CONSENT_AND_UPLOAD_DESC))
|
|
565
610
|
if not user_input.ask_for_yesno_confirmation(
|
|
566
611
|
self.logger,
|
|
567
|
-
TELEMETRY_CONSENT_AND_UPLOAD_PROMPT,
|
|
612
|
+
_(TELEMETRY_CONSENT_AND_UPLOAD_PROMPT),
|
|
568
613
|
False,
|
|
569
614
|
):
|
|
570
615
|
# ask if the user wants to opt out entirely
|
|
571
616
|
if user_input.ask_for_yesno_confirmation(
|
|
572
617
|
self.logger,
|
|
573
|
-
TELEMETRY_OPTOUT_PROMPT,
|
|
618
|
+
_(TELEMETRY_OPTOUT_PROMPT),
|
|
574
619
|
False,
|
|
575
620
|
):
|
|
576
621
|
set_telemetry_mode(self._gc, "off")
|
ruyi/telemetry/telemetry_cli.py
CHANGED
|
@@ -3,6 +3,7 @@ import datetime
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
5
|
from ..cli.cmd import RootCommand
|
|
6
|
+
from ..i18n import _
|
|
6
7
|
|
|
7
8
|
if TYPE_CHECKING:
|
|
8
9
|
from ..cli.completion import ArgumentParser
|
|
@@ -15,7 +16,7 @@ class TelemetryCommand(
|
|
|
15
16
|
cmd="telemetry",
|
|
16
17
|
has_main=True,
|
|
17
18
|
has_subcommands=True,
|
|
18
|
-
help="Manage your telemetry preferences",
|
|
19
|
+
help=_("Manage your telemetry preferences"),
|
|
19
20
|
):
|
|
20
21
|
@classmethod
|
|
21
22
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -47,7 +48,7 @@ class TelemetryConsentCommand(
|
|
|
47
48
|
TelemetryCommand,
|
|
48
49
|
cmd="consent",
|
|
49
50
|
aliases=["on"],
|
|
50
|
-
help="Give consent to telemetry data uploads",
|
|
51
|
+
help=_("Give consent to telemetry data uploads"),
|
|
51
52
|
):
|
|
52
53
|
@classmethod
|
|
53
54
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -65,7 +66,7 @@ class TelemetryConsentCommand(
|
|
|
65
66
|
class TelemetryLocalCommand(
|
|
66
67
|
TelemetryCommand,
|
|
67
68
|
cmd="local",
|
|
68
|
-
help="Set telemetry mode to local collection only",
|
|
69
|
+
help=_("Set telemetry mode to local collection only"),
|
|
69
70
|
):
|
|
70
71
|
@classmethod
|
|
71
72
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -83,7 +84,7 @@ class TelemetryOptoutCommand(
|
|
|
83
84
|
TelemetryCommand,
|
|
84
85
|
cmd="optout",
|
|
85
86
|
aliases=["off"],
|
|
86
|
-
help="Opt out of telemetry data collection",
|
|
87
|
+
help=_("Opt out of telemetry data collection"),
|
|
87
88
|
):
|
|
88
89
|
@classmethod
|
|
89
90
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -100,7 +101,7 @@ class TelemetryOptoutCommand(
|
|
|
100
101
|
class TelemetryStatusCommand(
|
|
101
102
|
TelemetryCommand,
|
|
102
103
|
cmd="status",
|
|
103
|
-
help="Print the current telemetry mode",
|
|
104
|
+
help=_("Print the current telemetry mode"),
|
|
104
105
|
):
|
|
105
106
|
@classmethod
|
|
106
107
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -108,7 +109,7 @@ class TelemetryStatusCommand(
|
|
|
108
109
|
"--verbose",
|
|
109
110
|
"-v",
|
|
110
111
|
action="store_true",
|
|
111
|
-
help="Enable verbose output",
|
|
112
|
+
help=_("Enable verbose output"),
|
|
112
113
|
)
|
|
113
114
|
|
|
114
115
|
@classmethod
|
|
@@ -120,7 +121,7 @@ class TelemetryStatusCommand(
|
|
|
120
121
|
|
|
121
122
|
if cfg.telemetry is None:
|
|
122
123
|
cfg.logger.I(
|
|
123
|
-
"telemetry mode is [green]off[/]: no further data will be collected"
|
|
124
|
+
_("telemetry mode is [green]off[/]: no further data will be collected")
|
|
124
125
|
)
|
|
125
126
|
return 0
|
|
126
127
|
|
|
@@ -131,7 +132,7 @@ class TelemetryStatusCommand(
|
|
|
131
132
|
class TelemetryUploadCommand(
|
|
132
133
|
TelemetryCommand,
|
|
133
134
|
cmd="upload",
|
|
134
|
-
help="Upload collected telemetry data now",
|
|
135
|
+
help=_("Upload collected telemetry data now"),
|
|
135
136
|
):
|
|
136
137
|
@classmethod
|
|
137
138
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
ruyi/utils/git.py
CHANGED
|
@@ -30,6 +30,7 @@ from rich.text import Text
|
|
|
30
30
|
if TYPE_CHECKING:
|
|
31
31
|
from typing_extensions import Self
|
|
32
32
|
|
|
33
|
+
from ..i18n import _
|
|
33
34
|
from ..log import RuyiLogger
|
|
34
35
|
|
|
35
36
|
|
|
@@ -77,11 +78,11 @@ class RemoteGitProgressIndicator(
|
|
|
77
78
|
self._last_stats is None
|
|
78
79
|
or self._last_stats.received_objects != stats.received_objects
|
|
79
80
|
):
|
|
80
|
-
task_name = "transferring objects"
|
|
81
|
+
task_name = _("transferring objects")
|
|
81
82
|
total = stats.total_objects
|
|
82
83
|
completed = stats.received_objects
|
|
83
84
|
elif self._last_stats.indexed_deltas != stats.indexed_deltas:
|
|
84
|
-
task_name = "processing deltas"
|
|
85
|
+
task_name = _("processing deltas")
|
|
85
86
|
total = stats.total_deltas
|
|
86
87
|
completed = stats.indexed_deltas
|
|
87
88
|
elif self._last_stats.received_bytes != stats.received_bytes:
|
|
@@ -113,13 +114,15 @@ def pull_ff_or_die(
|
|
|
113
114
|
if remote.url != remote_url:
|
|
114
115
|
if not allow_auto_management:
|
|
115
116
|
logger.F(
|
|
116
|
-
|
|
117
|
+
_(
|
|
118
|
+
"URL of remote '[yellow]{remote}[/]' does not match expected URL"
|
|
119
|
+
).format(remote=remote_name)
|
|
117
120
|
)
|
|
118
121
|
repo_path = human_readable_path_of_repo(repo)
|
|
119
|
-
logger.I(
|
|
120
|
-
logger.I(
|
|
121
|
-
logger.I(
|
|
122
|
-
logger.I("please [bold red]fix the repo settings manually[/]")
|
|
122
|
+
logger.I(_("repository: [yellow]{path}[/]").format(path=repo_path))
|
|
123
|
+
logger.I(_("expected remote URL: [yellow]{url}[/]").format(url=remote_url))
|
|
124
|
+
logger.I(_("actual remote URL: [yellow]{url}[/]").format(url=remote.url))
|
|
125
|
+
logger.I(_("please [bold red]fix the repo settings manually[/]"))
|
|
123
126
|
raise SystemExit(1)
|
|
124
127
|
|
|
125
128
|
logger.D(
|
|
@@ -134,7 +137,11 @@ def pull_ff_or_die(
|
|
|
134
137
|
with RemoteGitProgressIndicator() as pr:
|
|
135
138
|
remote.fetch(callbacks=pr)
|
|
136
139
|
except GitError as e:
|
|
137
|
-
logger.F(
|
|
140
|
+
logger.F(
|
|
141
|
+
_("failed to fetch from remote URL {url}: {reason}").format(
|
|
142
|
+
url=remote_url, reason=e
|
|
143
|
+
)
|
|
144
|
+
)
|
|
138
145
|
raise SystemExit(1) from e
|
|
139
146
|
|
|
140
147
|
remote_head_ref = repo.lookup_reference(f"refs/remotes/{remote_name}/{branch_name}")
|
|
@@ -145,7 +152,7 @@ def pull_ff_or_die(
|
|
|
145
152
|
assert isinstance(remote_head_ref.target, str)
|
|
146
153
|
remote_head = Oid(hex=remote_head_ref.target)
|
|
147
154
|
|
|
148
|
-
merge_analysis,
|
|
155
|
+
merge_analysis, _mp = repo.merge_analysis(remote_head)
|
|
149
156
|
|
|
150
157
|
if merge_analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE:
|
|
151
158
|
# nothing to do
|
|
@@ -166,6 +173,6 @@ def pull_ff_or_die(
|
|
|
166
173
|
return
|
|
167
174
|
|
|
168
175
|
# cannot handle these cases
|
|
169
|
-
logger.F("cannot fast-forward repo to newly fetched state")
|
|
170
|
-
logger.I("manual intervention is required to avoid data loss")
|
|
176
|
+
logger.F(_("cannot fast-forward repo to newly fetched state"))
|
|
177
|
+
logger.I(_("manual intervention is required to avoid data loss"))
|
|
171
178
|
raise SystemExit(1)
|
ruyi/utils/prereqs.py
CHANGED
|
@@ -3,6 +3,7 @@ import sys
|
|
|
3
3
|
from typing import Final, Iterable, NoReturn
|
|
4
4
|
|
|
5
5
|
from ..cli.user_input import pause_before_continuing
|
|
6
|
+
from ..i18n import _
|
|
6
7
|
from ..log import RuyiLogger, humanize_list
|
|
7
8
|
|
|
8
9
|
|
|
@@ -57,21 +58,25 @@ def ensure_cmds(
|
|
|
57
58
|
return None
|
|
58
59
|
|
|
59
60
|
cmds_str = humanize_list(absent_cmds, item_color="yellow")
|
|
60
|
-
prompt =
|
|
61
|
+
prompt = _(
|
|
62
|
+
"The command(s) {cmds} cannot be found in PATH, which [yellow]ruyi[/] requires"
|
|
63
|
+
).format(cmds=cmds_str)
|
|
61
64
|
if not interactive_retry:
|
|
62
65
|
logger.F(prompt)
|
|
63
|
-
logger.I("please install and retry")
|
|
66
|
+
logger.I(_("please install and retry"))
|
|
64
67
|
sys.exit(1)
|
|
65
68
|
|
|
66
69
|
logger.W(prompt)
|
|
67
70
|
logger.I(
|
|
68
|
-
|
|
71
|
+
_(
|
|
72
|
+
"please install them and press [green]Enter[/] to retry, or [green]Ctrl+C[/] to exit"
|
|
73
|
+
)
|
|
69
74
|
)
|
|
70
75
|
try:
|
|
71
76
|
pause_before_continuing(logger)
|
|
72
77
|
except EOFError:
|
|
73
|
-
logger.I("exiting due to EOF")
|
|
78
|
+
logger.I(_("exiting due to EOF"))
|
|
74
79
|
sys.exit(1)
|
|
75
80
|
except KeyboardInterrupt:
|
|
76
|
-
logger.I("exiting due to keyboard interrupt")
|
|
81
|
+
logger.I(_("exiting due to keyboard interrupt"))
|
|
77
82
|
sys.exit(1)
|
ruyi/utils/ssl_patch.py
CHANGED
|
@@ -6,6 +6,7 @@ from typing import Final, NamedTuple
|
|
|
6
6
|
|
|
7
7
|
import certifi
|
|
8
8
|
|
|
9
|
+
from ..i18n import _
|
|
9
10
|
from ..log import RuyiConsoleLogger, RuyiLogger
|
|
10
11
|
from .global_mode import EnvGlobalModeProvider
|
|
11
12
|
|
|
@@ -35,7 +36,7 @@ def _get_system_ssl_default_verify_paths(logger: RuyiLogger) -> ssl.DefaultVerif
|
|
|
35
36
|
try:
|
|
36
37
|
parts = _query_linux_system_ssl_default_cert_paths(logger)
|
|
37
38
|
if parts is None:
|
|
38
|
-
logger.W("failed to probe system libcrypto")
|
|
39
|
+
logger.W(_("failed to probe system libcrypto"))
|
|
39
40
|
else:
|
|
40
41
|
result = to_ssl_paths(parts)
|
|
41
42
|
except Exception as e:
|
ruyi/version.py
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
from typing import Final
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
from .i18n import d_
|
|
4
|
+
|
|
5
|
+
RUYI_SEMVER: Final = "0.45.0"
|
|
4
6
|
RUYI_USER_AGENT: Final = f"ruyi/{RUYI_SEMVER}"
|
|
5
7
|
|
|
6
|
-
COPYRIGHT_NOTICE: Final =
|
|
8
|
+
COPYRIGHT_NOTICE: Final = d_(
|
|
9
|
+
"""\
|
|
7
10
|
Copyright (C) Institute of Software, Chinese Academy of Sciences (ISCAS).
|
|
8
11
|
All rights reserved.
|
|
9
12
|
License: Apache-2.0 <https://www.apache.org/licenses/LICENSE-2.0>
|
|
10
13
|
\
|
|
11
14
|
"""
|
|
15
|
+
)
|
|
12
16
|
|
|
13
|
-
MPL_REDIST_NOTICE: Final =
|
|
17
|
+
MPL_REDIST_NOTICE: Final = d_(
|
|
18
|
+
"""\
|
|
14
19
|
This distribution of ruyi contains code licensed under the Mozilla Public
|
|
15
20
|
License 2.0 (https://mozilla.org/MPL/2.0/). You can get the respective
|
|
16
21
|
project's sources from the project's official website:
|
|
@@ -18,3 +23,4 @@ project's sources from the project's official website:
|
|
|
18
23
|
* certifi: https://github.com/certifi/python-certifi
|
|
19
24
|
\
|
|
20
25
|
"""
|
|
26
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ruyi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.45.0
|
|
4
4
|
Summary: Package manager for RuyiSDK
|
|
5
5
|
License: Apache License
|
|
6
6
|
Version 2.0, January 2004
|
|
@@ -224,6 +224,7 @@ Classifier: Topic :: System :: Software Distribution
|
|
|
224
224
|
Classifier: Typing :: Typed
|
|
225
225
|
Requires-Dist: argcomplete (>=2.0.0)
|
|
226
226
|
Requires-Dist: arpy
|
|
227
|
+
Requires-Dist: babel (>=2.8.0)
|
|
227
228
|
Requires-Dist: fastjsonschema (>=2.15.1)
|
|
228
229
|
Requires-Dist: jinja2 (>=3,<4)
|
|
229
230
|
Requires-Dist: pygit2 (>=1.6) ; python_version >= "3.11"
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
ruyi/__init__.py,sha256=_8k6Lm01mK35fGY7N9yQLF2SpmVPU70F2plkS6yG1YU,464
|
|
2
|
+
ruyi/__main__.py,sha256=oj13tC5ie1nYguDgzWu1WJVQvkpUYtj1O9CD9kEG2Hc,3631
|
|
3
|
+
ruyi/cli/__init__.py,sha256=MCdAZ00CLb9atln-pJrdQBmcrZmvPx4SOL5LVDbRc_Q,116
|
|
4
|
+
ruyi/cli/builtin_commands.py,sha256=cYyPSF00DSBH1WMv6mHcMygbFRBGXObMWhbXHs5K1Mc,639
|
|
5
|
+
ruyi/cli/cmd.py,sha256=uPbtCgvvJoGjwPSNyRo4JCu0fta3NJ43avH3DvdfqCk,6761
|
|
6
|
+
ruyi/cli/completer.py,sha256=cnOkU7veDe-jP8ROXZL2uBop2HgWfaAZl6dromnPLx8,1426
|
|
7
|
+
ruyi/cli/completion.py,sha256=ffLs3Dv7pY_uinwH98wkBPohRvAjpUOGqy01OTA_Bgo,841
|
|
8
|
+
ruyi/cli/config_cli.py,sha256=QOQ1AZGaPF7JyeOAFGsYHz4TOBCB_tJqUGqAAf4afjA,4152
|
|
9
|
+
ruyi/cli/main.py,sha256=L-3wK_Sklp9Sc1k1I3G9XS2DkuC5xWaIJQUqYejpQyU,4905
|
|
10
|
+
ruyi/cli/oobe.py,sha256=Fjb2-7mFFz85Q-xxuxUG2FSjY9_7ADUDHeqWGidolmY,2572
|
|
11
|
+
ruyi/cli/self_cli.py,sha256=djH51igQ2Ljrh3L2uFx3f31HGhd9iT8UQxp2x6dvXBs,9137
|
|
12
|
+
ruyi/cli/user_input.py,sha256=t-AYWGHSl7VqyLg82l5cjgkOwj0wyeD_S9h5ZyN3yYg,4513
|
|
13
|
+
ruyi/cli/version_cli.py,sha256=teCysKc7hQ7ewuV-wAPwO6DQerJQDJoyWVFAEhoxtWE,1394
|
|
14
|
+
ruyi/config/__init__.py,sha256=QK8dXWp4Tpr8H_4IKLg3fc3-y5wsvnbFUIiLXd3CXOU,17559
|
|
15
|
+
ruyi/config/editor.py,sha256=piAJ-a68iX6IFWXy1g9OXoSs_3DardZwoaSPdStKKL0,4243
|
|
16
|
+
ruyi/config/errors.py,sha256=VH1bhEkddmqkEqbFDgR-Sqp4_OIz6pB4QUTeLRGuQmk,2888
|
|
17
|
+
ruyi/config/news.py,sha256=83LjQjJHsqOPdRrytG7VBFubG6pyDwJ-Mg37gpBRU20,1061
|
|
18
|
+
ruyi/config/schema.py,sha256=u0TdpoUV6I7ZGZKlHAAGnqZbfaoTiA45UsM5c82M99M,7405
|
|
19
|
+
ruyi/device/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
+
ruyi/device/provision.py,sha256=aUtD4nc_A7kNpUSQDbZaVi39V2aHKc82UYW03OszlnQ,22534
|
|
21
|
+
ruyi/device/provision_cli.py,sha256=n6qgDsOeZ9Ta0DNX-awTwvcTwp6KsH5vZ7DXcQn8udk,1091
|
|
22
|
+
ruyi/i18n/__init__.py,sha256=5Qmcwk8cP8kYUACw8dJcYvXJOWo6EhLWVg4m60qv64g,4312
|
|
23
|
+
ruyi/log/__init__.py,sha256=VTVstSCUIeyPGyuLnwUGa5JGknqyOMdJyZJBbkHqK5Y,6663
|
|
24
|
+
ruyi/mux/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
+
ruyi/mux/runtime.py,sha256=7dK55D57c1O8hVRy6fEo4VWa4SbjDHoNYPqFd6YxmgA,7469
|
|
26
|
+
ruyi/mux/venv/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
+
ruyi/mux/venv/emulator_cfg.py,sha256=vGw-pBtNii2fTllQqloN_o1FAFOOHgF7zDqLMVdIlzk,1125
|
|
28
|
+
ruyi/mux/venv/maker.py,sha256=NEt8L8lV4PwDWsFek__dWhxaIfOThprcCojuwDxLlBw,30640
|
|
29
|
+
ruyi/mux/venv/venv_cli.py,sha256=LL2nmRsqzeFVe8KoXiJl82uTBkemr2X1yX3oooI5RBk,3076
|
|
30
|
+
ruyi/mux/venv_cfg.py,sha256=m75JCVLFWE1gE8OzcNDOHqwUc2c6ikJhZ-GhjsXv94U,6840
|
|
31
|
+
ruyi/pluginhost/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
+
ruyi/pluginhost/api.py,sha256=Zh69xJfR7PEbM6fjoFZRNqeqTneWAmC71NjA76HodSY,5711
|
|
33
|
+
ruyi/pluginhost/ctx.py,sha256=MsP1L7nchnbSrauId3GaQzv0YJLnWE0u_H3ZFEmjUX8,6590
|
|
34
|
+
ruyi/pluginhost/paths.py,sha256=3EVY3_i3LLff4Lk9py-E317C7_ysiRatfCiuxvCsVWw,4227
|
|
35
|
+
ruyi/pluginhost/plugin_cli.py,sha256=Mdw3JYfdDuKLgxnE7Ca7PA-iCdXupqAl8E58nLL9wbk,998
|
|
36
|
+
ruyi/pluginhost/unsandboxed.py,sha256=A9T-6JFfDNiCAxq47_EhLo_rRmZ3Iyrod3teMWv3-XM,7122
|
|
37
|
+
ruyi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
|
+
ruyi/resource_bundle/__init__.py,sha256=AQonNhDlWGWSFSgcuw74Z296umGe5ojc2gkDYvw3Rqw,900
|
|
39
|
+
ruyi/resource_bundle/__main__.py,sha256=F3M-c9nzeI9Yimnn-qCbLKITAzjPYI8mtR-SvjNayrs,1659
|
|
40
|
+
ruyi/resource_bundle/data.py,sha256=QkFTjlplftVC2sJ7iaDy7_1OLVxa8qn8KbJ9n8g4GQ0,34704
|
|
41
|
+
ruyi/ruyipkg/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
|
+
ruyi/ruyipkg/admin_checksum.py,sha256=l-YFbSHUBFM-_Gzv0PnSfk9Xv4Srpb0Vd38SrrpA1y0,2331
|
|
43
|
+
ruyi/ruyipkg/admin_cli.py,sha256=ynlkybso9BH6-HLUjgapBI8Gv_y1pXOn7B4ecaUGWq0,2512
|
|
44
|
+
ruyi/ruyipkg/atom.py,sha256=S0mWmtI0HgfOnbkAK6BlHmCrAiHcJ-QVnub3iCiCJjU,5440
|
|
45
|
+
ruyi/ruyipkg/augmented_pkg.py,sha256=O3q9l5zIygvphi-7BK0oCqkuyYrfDYujHNmAC63pf-k,6987
|
|
46
|
+
ruyi/ruyipkg/canonical_dump.py,sha256=Qu25YXwJpjWUBte0C3bmmaJxe7zyqfN-2-__u2_dJDM,9363
|
|
47
|
+
ruyi/ruyipkg/checksum.py,sha256=O3IsmO_LYgmL7RWbN9F3dqe-56qj6JMAutRALXXkCw4,1451
|
|
48
|
+
ruyi/ruyipkg/cli_completion.py,sha256=kJf7vN5rXi5zAwTI3dr4J8HdUzR3-ZXnsdaNQV6kqzo,1151
|
|
49
|
+
ruyi/ruyipkg/distfile.py,sha256=bsUpJm1zopolOIgMCtZDyDgfLXQW7RpcA1BPPLA8Hug,7624
|
|
50
|
+
ruyi/ruyipkg/entity.py,sha256=Ixs_d8Xw6j_NghafOkp0L9MQIYmKj6upue1GGUJe6uQ,14760
|
|
51
|
+
ruyi/ruyipkg/entity_cli.py,sha256=rxY1EMYzfQ-KCnDjyDjyoSEvNNN0tqOHWidJzLN0COc,4029
|
|
52
|
+
ruyi/ruyipkg/entity_provider.py,sha256=agYmFOWz36RpVIggo8BW6kfRWfYTIcyqsD3IVq065io,9018
|
|
53
|
+
ruyi/ruyipkg/fetcher.py,sha256=SWInsI_aQ2Wv1O_9YJEF1BcAxbb24m4UJwwt5maPl2s,9803
|
|
54
|
+
ruyi/ruyipkg/host.py,sha256=pmqgggi7koDCWgzFexwHpycv4SZ07VF6xUbi4s8FSKA,1399
|
|
55
|
+
ruyi/ruyipkg/install.py,sha256=oLMZgW2Lh3b4Odcx-dNE0BEds9oJzlktm83sr8RHbOw,20345
|
|
56
|
+
ruyi/ruyipkg/install_cli.py,sha256=jUoM6mGGDJKSfjv7GhhE5C1rO-IVvMP2nUESZdWiscM,5363
|
|
57
|
+
ruyi/ruyipkg/list.py,sha256=qxzJIe02rqnA9ngYsfNeqUbYgWba9rzprqk4ScF-YwI,4535
|
|
58
|
+
ruyi/ruyipkg/list_cli.py,sha256=tXpsMEZt0ntOSpuybv534VR4ZDIbbV0PS_A01Z5Lj-4,2345
|
|
59
|
+
ruyi/ruyipkg/list_filter.py,sha256=F64_UhwUEiaUR73EkLu91qoUBA-Yz9mEVWj8XY46MXQ,5467
|
|
60
|
+
ruyi/ruyipkg/msg.py,sha256=d9uF1rBmdT8iVvpTU53XXtNTJzvNhIK68rO-4W4h5wc,3180
|
|
61
|
+
ruyi/ruyipkg/news.py,sha256=kqU8Ci9D9fcUMTd-yGGBwP9kJ3NCznw76Sc24V7xn6g,4223
|
|
62
|
+
ruyi/ruyipkg/news_cli.py,sha256=Z4rS30RRG1fnEGKFTYJcxeKNMvIjei4vyPeYNdkuRn8,2434
|
|
63
|
+
ruyi/ruyipkg/news_store.py,sha256=ocTO4YDpL_HrKaIRFvJ_Gxvpmr7V7-R8b1B8f5Eue9c,5276
|
|
64
|
+
ruyi/ruyipkg/pkg_manifest.py,sha256=FmksKjQyBnU4zA3MFXiHdB2EjNmhs-J9km9vE-zBQlk,18836
|
|
65
|
+
ruyi/ruyipkg/profile.py,sha256=6xwL24crALShqD8bazGOIAFTYCpM_91mD8d6YMxM2FU,10762
|
|
66
|
+
ruyi/ruyipkg/profile_cli.py,sha256=GR-f0PKFRz0BzHvPq-Vii4qGGQ31RqYdUbs7pkvWOAc,1038
|
|
67
|
+
ruyi/ruyipkg/protocols.py,sha256=lPKRaAcK3DY3wmkyO2tKpFvPQ_4QA4aSNNsNLvi78O8,1833
|
|
68
|
+
ruyi/ruyipkg/repo.py,sha256=OqDH0GDGPXxFFyP18dO-ZfFQVAuHKwTdmT9joEwIXzM,25634
|
|
69
|
+
ruyi/ruyipkg/state.py,sha256=Ie4vrt79Wp9P0L36tMj36tOtDlFnIb6uwVGDQCQyg8s,11544
|
|
70
|
+
ruyi/ruyipkg/unpack.py,sha256=XS1pB2ahGXjSRE0ViOQKfjStrgDISf6WGlMzR-USD9U,11991
|
|
71
|
+
ruyi/ruyipkg/unpack_method.py,sha256=qJdZXB7OhLLuXhgejZDpiqK2BqMvxxcLJaMWCkc0G0Y,2179
|
|
72
|
+
ruyi/ruyipkg/update_cli.py,sha256=llq8oHctSQ9ahY0JYvGaoUOYzbMx8Y2VVTuj4GdLUDY,1531
|
|
73
|
+
ruyi/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
|
+
ruyi/telemetry/aggregate.py,sha256=MhehVOtU7KLICHgOz3sZE5z3OgFa4OmlRIPqXOW_tBU,2334
|
|
75
|
+
ruyi/telemetry/event.py,sha256=GZnFj6E59Q7mjp-2VRApAZH3rT_bu4_cWb5QMCPm-Zc,982
|
|
76
|
+
ruyi/telemetry/provider.py,sha256=1SRqs6Yq2RnKVsthvdcwleWIMbRoi9P0CiikC4YzJPU,23593
|
|
77
|
+
ruyi/telemetry/scope.py,sha256=e45VPAvRAqSxrL0ESorN9SCnR_I6Bwi2CMPJDDshJEE,1133
|
|
78
|
+
ruyi/telemetry/store.py,sha256=IbikQ9dmcuf85SIxlWpXY1aydovM1EzXA9Q6hAo_mXE,10072
|
|
79
|
+
ruyi/telemetry/telemetry_cli.py,sha256=JCgYAH4mJK8e5LPYs6HtoN9WaudDb-jJ33gZkcNgbVo,4072
|
|
80
|
+
ruyi/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
81
|
+
ruyi/utils/ar.py,sha256=w9wiYYdbInLewr5IRTcP0TiOw2ibVDQEmnV0hHm9WlA,2271
|
|
82
|
+
ruyi/utils/ci.py,sha256=66DBm4ooA7yozDtXCJFd1n2jJXTsEnxPSpkNzLfE28M,2970
|
|
83
|
+
ruyi/utils/frontmatter.py,sha256=4EOohEYCZ_q6ncpDv7ktJYf9PN4WEdgFfdE9hZBV3Zg,1052
|
|
84
|
+
ruyi/utils/git.py,sha256=9AumrbBfXBtZwvYvrezDKJJW3TA6HA4gch69eqfGRuo,6232
|
|
85
|
+
ruyi/utils/global_mode.py,sha256=9GES5RyisSXAo14_bP896Jat6BFru_N-DC1V_7bofWY,5684
|
|
86
|
+
ruyi/utils/l10n.py,sha256=l003oQ5M8fWIKQHbYTVSc6oHzFFGU2sbKac7Hh6FNFU,2530
|
|
87
|
+
ruyi/utils/markdown.py,sha256=Mpq--ClM4j9lm_-5zO53ptYePUTLI4rg0V1YshOwsf8,2654
|
|
88
|
+
ruyi/utils/mounts.py,sha256=31BGsVOpD2bO7PYpm8I1ogDHzP3MvrMWznKonS3Ajos,1210
|
|
89
|
+
ruyi/utils/node_info.py,sha256=8-4dtrr2Ww_Cb9iKH_WpTMOWx7wknJKRwMUUZJYo9dQ,6603
|
|
90
|
+
ruyi/utils/nuitka.py,sha256=7mdbmtKnUsGkIp1zxXgGWYrwZcCut3ipd0AP0DrbfZk,1112
|
|
91
|
+
ruyi/utils/porcelain.py,sha256=pF6ieSE2xlnC0HBADFY0m-uuwVNNME3wlbHo2jWdLFA,1403
|
|
92
|
+
ruyi/utils/prereqs.py,sha256=R24UQyHm3pGt2QmZ-5g89AJsxr2eO5SlPrhIoRtz9lM,2181
|
|
93
|
+
ruyi/utils/ssl_patch.py,sha256=HZsJ_nMEzPLjxSl1b8jkYkKU-O6koYK1rdFckic-bi0,5685
|
|
94
|
+
ruyi/utils/templating.py,sha256=94xBJTkIfDqmUBTc9hnLO54zQoC7hwGWONGF3YbaqHk,966
|
|
95
|
+
ruyi/utils/toml.py,sha256=aniIF3SGfR69_s3GWWwlnoKxW4B5IDVY2CM0eUI55_c,3501
|
|
96
|
+
ruyi/utils/url.py,sha256=Wyct6syS4GmZC6mY7SK-YgBWxKl3cOOBXtp9UtvGkto,186
|
|
97
|
+
ruyi/utils/xdg_basedir.py,sha256=RwVH199jPcLVsg5ngR62RaNS5hqnMpkdt31LqkCfa1g,2751
|
|
98
|
+
ruyi/version.py,sha256=qFJ1dp12sOzWy23xY5eKU0c7X8ZaKJy-W4OvavRb1w4,637
|
|
99
|
+
ruyi-0.45.0.dist-info/METADATA,sha256=Pm_WaW_bndLfRLYW1EocJtSuJjp5DYxkOUL-bDyCaEM,24481
|
|
100
|
+
ruyi-0.45.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
|
|
101
|
+
ruyi-0.45.0.dist-info/entry_points.txt,sha256=GXSNSy7OgFrnlU5xm5dE3l3PGO92Qf6VDIUCdvQNm8E,49
|
|
102
|
+
ruyi-0.45.0.dist-info/licenses/LICENSE-Apache.txt,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
103
|
+
ruyi-0.45.0.dist-info/RECORD,,
|