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/telemetry/provider.py
CHANGED
|
@@ -7,7 +7,6 @@ import time
|
|
|
7
7
|
from typing import Callable, TYPE_CHECKING, cast
|
|
8
8
|
import uuid
|
|
9
9
|
|
|
10
|
-
from ..i18n import _, d_
|
|
11
10
|
from ..log import RuyiLogger
|
|
12
11
|
from ..utils.node_info import NodeInfo, gather_node_info
|
|
13
12
|
from .scope import TelemetryScope
|
|
@@ -19,8 +18,7 @@ if TYPE_CHECKING:
|
|
|
19
18
|
|
|
20
19
|
FALLBACK_PM_TELEMETRY_ENDPOINT = "https://api.ruyisdk.cn/telemetry/pm/"
|
|
21
20
|
|
|
22
|
-
TELEMETRY_CONSENT_AND_UPLOAD_DESC =
|
|
23
|
-
"""
|
|
21
|
+
TELEMETRY_CONSENT_AND_UPLOAD_DESC = """
|
|
24
22
|
RuyiSDK collects minimal usage data in the form of just a version number of
|
|
25
23
|
the running [yellow]ruyi[/], to help us improve the product. With your consent,
|
|
26
24
|
RuyiSDK may also collect additional non-tracking usage data to be sent
|
|
@@ -37,14 +35,11 @@ team can better understand adoption. If you choose to opt out, this will be the
|
|
|
37
35
|
only data to be ever uploaded, without any tracking ID being generated or kept.
|
|
38
36
|
Thank you for helping us build a better experience!
|
|
39
37
|
"""
|
|
40
|
-
|
|
41
|
-
TELEMETRY_CONSENT_AND_UPLOAD_PROMPT = d_(
|
|
38
|
+
TELEMETRY_CONSENT_AND_UPLOAD_PROMPT = (
|
|
42
39
|
"Do you agree to have usage data periodically uploaded?"
|
|
43
40
|
)
|
|
44
|
-
TELEMETRY_OPTOUT_PROMPT =
|
|
45
|
-
MALFORMED_TELEMETRY_STATE_MSG =
|
|
46
|
-
"malformed telemetry state: unable to determine upload weekday, nothing will be uploaded"
|
|
47
|
-
)
|
|
41
|
+
TELEMETRY_OPTOUT_PROMPT = "\nDo you want to opt out of telemetry entirely?"
|
|
42
|
+
MALFORMED_TELEMETRY_STATE_MSG = "malformed telemetry state: unable to determine upload weekday, nothing will be uploaded"
|
|
48
43
|
|
|
49
44
|
|
|
50
45
|
def next_utc_weekday(wday: int, now: float | None = None) -> int:
|
|
@@ -118,28 +113,22 @@ def set_telemetry_mode(
|
|
|
118
113
|
return
|
|
119
114
|
match mode:
|
|
120
115
|
case "on":
|
|
121
|
-
logger.I(
|
|
116
|
+
logger.I("telemetry data uploading is now enabled")
|
|
122
117
|
logger.I(
|
|
123
|
-
|
|
124
|
-
"you can opt out at any time by running [yellow]ruyi telemetry optout[/]"
|
|
125
|
-
)
|
|
118
|
+
"you can opt out at any time by running [yellow]ruyi telemetry optout[/]"
|
|
126
119
|
)
|
|
127
120
|
case "local":
|
|
128
|
-
logger.I(
|
|
121
|
+
logger.I("telemetry mode is now set to local collection only")
|
|
129
122
|
logger.I(
|
|
130
|
-
|
|
131
|
-
"you can re-enable telemetry data uploading at any time by running [yellow]ruyi telemetry consent[/]"
|
|
132
|
-
)
|
|
123
|
+
"you can re-enable telemetry data uploading at any time by running [yellow]ruyi telemetry consent[/]"
|
|
133
124
|
)
|
|
134
125
|
logger.I(
|
|
135
|
-
|
|
126
|
+
"or opt out at any time by running [yellow]ruyi telemetry optout[/]"
|
|
136
127
|
)
|
|
137
128
|
case "off":
|
|
138
|
-
logger.I(
|
|
129
|
+
logger.I("telemetry data collection is now disabled")
|
|
139
130
|
logger.I(
|
|
140
|
-
|
|
141
|
-
"you can re-enable telemetry data uploads at any time by running [yellow]ruyi telemetry consent[/]"
|
|
142
|
-
)
|
|
131
|
+
"you can re-enable telemetry data uploads at any time by running [yellow]ruyi telemetry consent[/]"
|
|
143
132
|
)
|
|
144
133
|
case _:
|
|
145
134
|
raise ValueError(f"invalid telemetry mode: {mode}")
|
|
@@ -327,50 +316,30 @@ class TelemetryProvider:
|
|
|
327
316
|
"%Y-%m-%d %H:%M:%S %z", time.localtime(last_upload_time)
|
|
328
317
|
)
|
|
329
318
|
self.logger.I(
|
|
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
|
-
)
|
|
319
|
+
f"scope {scope}: usage information has already been uploaded today at {last_upload_time_str}"
|
|
336
320
|
)
|
|
337
321
|
else:
|
|
338
322
|
self.logger.I(
|
|
339
|
-
|
|
340
|
-
"scope {scope}: usage information has already been uploaded sometime today"
|
|
341
|
-
).format(
|
|
342
|
-
scope=scope,
|
|
343
|
-
)
|
|
323
|
+
f"scope {scope}: usage information has already been uploaded sometime today"
|
|
344
324
|
)
|
|
345
325
|
else:
|
|
346
326
|
self.logger.I(
|
|
347
|
-
|
|
348
|
-
"scope {scope}: the next upload will happen [bold green]today[/] if not already"
|
|
349
|
-
).format(
|
|
350
|
-
scope=scope,
|
|
351
|
-
)
|
|
327
|
+
f"scope {scope}: the next upload will happen [bold green]today[/] if not already"
|
|
352
328
|
)
|
|
353
329
|
else:
|
|
354
330
|
self.logger.I(
|
|
355
|
-
|
|
331
|
+
"the next upload will happen anytime [yellow]ruyi[/] is executed:"
|
|
356
332
|
)
|
|
357
333
|
self.logger.I(
|
|
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
|
-
)
|
|
334
|
+
f" - between [bold green]{next_upload_day_str}[/] and [bold green]{next_upload_day_end_str}[/]"
|
|
364
335
|
)
|
|
365
|
-
self.logger.I(
|
|
336
|
+
self.logger.I(" - or if the last upload is more than a week ago")
|
|
366
337
|
|
|
367
338
|
def print_telemetry_notice(self, for_cli_verbose_output: bool = False) -> None:
|
|
368
339
|
if self.minimal:
|
|
369
340
|
if for_cli_verbose_output:
|
|
370
341
|
self.logger.I(
|
|
371
|
-
|
|
372
|
-
"telemetry mode is [green]off[/]: nothing is collected or uploaded after the first run"
|
|
373
|
-
)
|
|
342
|
+
"telemetry mode is [green]off[/]: nothing is collected or uploaded after the first run"
|
|
374
343
|
)
|
|
375
344
|
return
|
|
376
345
|
|
|
@@ -383,14 +352,12 @@ class TelemetryProvider:
|
|
|
383
352
|
self.logger.D(MALFORMED_TELEMETRY_STATE_MSG)
|
|
384
353
|
return
|
|
385
354
|
|
|
386
|
-
upload_wday_name =
|
|
355
|
+
upload_wday_name = calendar.day_name[upload_wday]
|
|
387
356
|
|
|
388
357
|
if self.local_mode:
|
|
389
358
|
if for_cli_verbose_output:
|
|
390
359
|
self.logger.I(
|
|
391
|
-
|
|
392
|
-
"telemetry mode is [green]local[/]: local usage collection only, no usage uploads except if requested"
|
|
393
|
-
)
|
|
360
|
+
"telemetry mode is [green]local[/]: local usage collection only, no usage uploads except if requested"
|
|
394
361
|
)
|
|
395
362
|
return
|
|
396
363
|
|
|
@@ -400,34 +367,22 @@ class TelemetryProvider:
|
|
|
400
367
|
|
|
401
368
|
if for_cli_verbose_output:
|
|
402
369
|
self.logger.I(
|
|
403
|
-
|
|
404
|
-
"telemetry mode is [green]on[/]: usage data is collected and periodically uploaded"
|
|
405
|
-
)
|
|
370
|
+
"telemetry mode is [green]on[/]: usage data is collected and periodically uploaded"
|
|
406
371
|
)
|
|
407
372
|
self.logger.I(
|
|
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
|
-
)
|
|
373
|
+
f"non-tracking usage information will be uploaded to RuyiSDK-managed servers [bold green]every {upload_wday_name}[/]"
|
|
413
374
|
)
|
|
414
375
|
else:
|
|
415
376
|
self.logger.W(
|
|
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
|
-
)
|
|
377
|
+
f"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 {upload_wday_name}[/]"
|
|
421
378
|
)
|
|
422
379
|
|
|
423
380
|
self._print_upload_schedule_notice(upload_wday, now)
|
|
424
381
|
|
|
425
382
|
if not for_cli_verbose_output:
|
|
426
|
-
self.logger.I(
|
|
427
|
-
self.logger.I(
|
|
428
|
-
self.logger.I(
|
|
429
|
-
_(" - or give consent with [yellow]ruyi telemetry consent[/]")
|
|
430
|
-
)
|
|
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("- or give consent with [yellow]ruyi telemetry consent[/]")
|
|
431
386
|
|
|
432
387
|
def _next_upload_day(self, time_now: float | None = None) -> int | None:
|
|
433
388
|
upload_wday = self._upload_weekday()
|
|
@@ -606,16 +561,16 @@ class TelemetryProvider:
|
|
|
606
561
|
|
|
607
562
|
from ..cli import user_input
|
|
608
563
|
|
|
609
|
-
self.logger.stdout(
|
|
564
|
+
self.logger.stdout(TELEMETRY_CONSENT_AND_UPLOAD_DESC)
|
|
610
565
|
if not user_input.ask_for_yesno_confirmation(
|
|
611
566
|
self.logger,
|
|
612
|
-
|
|
567
|
+
TELEMETRY_CONSENT_AND_UPLOAD_PROMPT,
|
|
613
568
|
False,
|
|
614
569
|
):
|
|
615
570
|
# ask if the user wants to opt out entirely
|
|
616
571
|
if user_input.ask_for_yesno_confirmation(
|
|
617
572
|
self.logger,
|
|
618
|
-
|
|
573
|
+
TELEMETRY_OPTOUT_PROMPT,
|
|
619
574
|
False,
|
|
620
575
|
):
|
|
621
576
|
set_telemetry_mode(self._gc, "off")
|
ruyi/telemetry/telemetry_cli.py
CHANGED
|
@@ -3,7 +3,6 @@ import datetime
|
|
|
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
|
|
@@ -16,7 +15,7 @@ class TelemetryCommand(
|
|
|
16
15
|
cmd="telemetry",
|
|
17
16
|
has_main=True,
|
|
18
17
|
has_subcommands=True,
|
|
19
|
-
help=
|
|
18
|
+
help="Manage your telemetry preferences",
|
|
20
19
|
):
|
|
21
20
|
@classmethod
|
|
22
21
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -48,7 +47,7 @@ class TelemetryConsentCommand(
|
|
|
48
47
|
TelemetryCommand,
|
|
49
48
|
cmd="consent",
|
|
50
49
|
aliases=["on"],
|
|
51
|
-
help=
|
|
50
|
+
help="Give consent to telemetry data uploads",
|
|
52
51
|
):
|
|
53
52
|
@classmethod
|
|
54
53
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -66,7 +65,7 @@ class TelemetryConsentCommand(
|
|
|
66
65
|
class TelemetryLocalCommand(
|
|
67
66
|
TelemetryCommand,
|
|
68
67
|
cmd="local",
|
|
69
|
-
help=
|
|
68
|
+
help="Set telemetry mode to local collection only",
|
|
70
69
|
):
|
|
71
70
|
@classmethod
|
|
72
71
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -84,7 +83,7 @@ class TelemetryOptoutCommand(
|
|
|
84
83
|
TelemetryCommand,
|
|
85
84
|
cmd="optout",
|
|
86
85
|
aliases=["off"],
|
|
87
|
-
help=
|
|
86
|
+
help="Opt out of telemetry data collection",
|
|
88
87
|
):
|
|
89
88
|
@classmethod
|
|
90
89
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -101,7 +100,7 @@ class TelemetryOptoutCommand(
|
|
|
101
100
|
class TelemetryStatusCommand(
|
|
102
101
|
TelemetryCommand,
|
|
103
102
|
cmd="status",
|
|
104
|
-
help=
|
|
103
|
+
help="Print the current telemetry mode",
|
|
105
104
|
):
|
|
106
105
|
@classmethod
|
|
107
106
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -109,7 +108,7 @@ class TelemetryStatusCommand(
|
|
|
109
108
|
"--verbose",
|
|
110
109
|
"-v",
|
|
111
110
|
action="store_true",
|
|
112
|
-
help=
|
|
111
|
+
help="Enable verbose output",
|
|
113
112
|
)
|
|
114
113
|
|
|
115
114
|
@classmethod
|
|
@@ -121,7 +120,7 @@ class TelemetryStatusCommand(
|
|
|
121
120
|
|
|
122
121
|
if cfg.telemetry is None:
|
|
123
122
|
cfg.logger.I(
|
|
124
|
-
|
|
123
|
+
"telemetry mode is [green]off[/]: no further data will be collected"
|
|
125
124
|
)
|
|
126
125
|
return 0
|
|
127
126
|
|
|
@@ -132,7 +131,7 @@ class TelemetryStatusCommand(
|
|
|
132
131
|
class TelemetryUploadCommand(
|
|
133
132
|
TelemetryCommand,
|
|
134
133
|
cmd="upload",
|
|
135
|
-
help=
|
|
134
|
+
help="Upload collected telemetry data now",
|
|
136
135
|
):
|
|
137
136
|
@classmethod
|
|
138
137
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
ruyi/utils/git.py
CHANGED
|
@@ -30,7 +30,6 @@ from rich.text import Text
|
|
|
30
30
|
if TYPE_CHECKING:
|
|
31
31
|
from typing_extensions import Self
|
|
32
32
|
|
|
33
|
-
from ..i18n import _
|
|
34
33
|
from ..log import RuyiLogger
|
|
35
34
|
|
|
36
35
|
|
|
@@ -78,11 +77,11 @@ class RemoteGitProgressIndicator(
|
|
|
78
77
|
self._last_stats is None
|
|
79
78
|
or self._last_stats.received_objects != stats.received_objects
|
|
80
79
|
):
|
|
81
|
-
task_name =
|
|
80
|
+
task_name = "transferring objects"
|
|
82
81
|
total = stats.total_objects
|
|
83
82
|
completed = stats.received_objects
|
|
84
83
|
elif self._last_stats.indexed_deltas != stats.indexed_deltas:
|
|
85
|
-
task_name =
|
|
84
|
+
task_name = "processing deltas"
|
|
86
85
|
total = stats.total_deltas
|
|
87
86
|
completed = stats.indexed_deltas
|
|
88
87
|
elif self._last_stats.received_bytes != stats.received_bytes:
|
|
@@ -114,15 +113,13 @@ def pull_ff_or_die(
|
|
|
114
113
|
if remote.url != remote_url:
|
|
115
114
|
if not allow_auto_management:
|
|
116
115
|
logger.F(
|
|
117
|
-
|
|
118
|
-
"URL of remote '[yellow]{remote}[/]' does not match expected URL"
|
|
119
|
-
).format(remote=remote_name)
|
|
116
|
+
f"URL of remote '[yellow]{remote_name}[/]' does not match expected URL"
|
|
120
117
|
)
|
|
121
118
|
repo_path = human_readable_path_of_repo(repo)
|
|
122
|
-
logger.I(
|
|
123
|
-
logger.I(
|
|
124
|
-
logger.I(
|
|
125
|
-
logger.I(
|
|
119
|
+
logger.I(f"repository: [yellow]{repo_path}[/]")
|
|
120
|
+
logger.I(f"expected remote URL: [yellow]{remote_url}[/]")
|
|
121
|
+
logger.I(f"actual remote URL: [yellow]{remote.url}[/]")
|
|
122
|
+
logger.I("please [bold red]fix the repo settings manually[/]")
|
|
126
123
|
raise SystemExit(1)
|
|
127
124
|
|
|
128
125
|
logger.D(
|
|
@@ -137,11 +134,7 @@ def pull_ff_or_die(
|
|
|
137
134
|
with RemoteGitProgressIndicator() as pr:
|
|
138
135
|
remote.fetch(callbacks=pr)
|
|
139
136
|
except GitError as e:
|
|
140
|
-
logger.F(
|
|
141
|
-
_("failed to fetch from remote URL {url}: {reason}").format(
|
|
142
|
-
url=remote_url, reason=e
|
|
143
|
-
)
|
|
144
|
-
)
|
|
137
|
+
logger.F(f"failed to fetch from remote URL {remote_url}: {e}")
|
|
145
138
|
raise SystemExit(1) from e
|
|
146
139
|
|
|
147
140
|
remote_head_ref = repo.lookup_reference(f"refs/remotes/{remote_name}/{branch_name}")
|
|
@@ -152,7 +145,7 @@ def pull_ff_or_die(
|
|
|
152
145
|
assert isinstance(remote_head_ref.target, str)
|
|
153
146
|
remote_head = Oid(hex=remote_head_ref.target)
|
|
154
147
|
|
|
155
|
-
merge_analysis,
|
|
148
|
+
merge_analysis, _ = repo.merge_analysis(remote_head)
|
|
156
149
|
|
|
157
150
|
if merge_analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE:
|
|
158
151
|
# nothing to do
|
|
@@ -173,6 +166,6 @@ def pull_ff_or_die(
|
|
|
173
166
|
return
|
|
174
167
|
|
|
175
168
|
# cannot handle these cases
|
|
176
|
-
logger.F(
|
|
177
|
-
logger.I(
|
|
169
|
+
logger.F("cannot fast-forward repo to newly fetched state")
|
|
170
|
+
logger.I("manual intervention is required to avoid data loss")
|
|
178
171
|
raise SystemExit(1)
|
ruyi/utils/prereqs.py
CHANGED
|
@@ -3,7 +3,6 @@ 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 _
|
|
7
6
|
from ..log import RuyiLogger, humanize_list
|
|
8
7
|
|
|
9
8
|
|
|
@@ -58,25 +57,21 @@ def ensure_cmds(
|
|
|
58
57
|
return None
|
|
59
58
|
|
|
60
59
|
cmds_str = humanize_list(absent_cmds, item_color="yellow")
|
|
61
|
-
prompt =
|
|
62
|
-
"The command(s) {cmds} cannot be found in PATH, which [yellow]ruyi[/] requires"
|
|
63
|
-
).format(cmds=cmds_str)
|
|
60
|
+
prompt = f"The command(s) {cmds_str} cannot be found in PATH, which [yellow]ruyi[/] requires"
|
|
64
61
|
if not interactive_retry:
|
|
65
62
|
logger.F(prompt)
|
|
66
|
-
logger.I(
|
|
63
|
+
logger.I("please install and retry")
|
|
67
64
|
sys.exit(1)
|
|
68
65
|
|
|
69
66
|
logger.W(prompt)
|
|
70
67
|
logger.I(
|
|
71
|
-
|
|
72
|
-
"please install them and press [green]Enter[/] to retry, or [green]Ctrl+C[/] to exit"
|
|
73
|
-
)
|
|
68
|
+
"please install them and press [green]Enter[/] to retry, or [green]Ctrl+C[/] to exit"
|
|
74
69
|
)
|
|
75
70
|
try:
|
|
76
71
|
pause_before_continuing(logger)
|
|
77
72
|
except EOFError:
|
|
78
|
-
logger.I(
|
|
73
|
+
logger.I("exiting due to EOF")
|
|
79
74
|
sys.exit(1)
|
|
80
75
|
except KeyboardInterrupt:
|
|
81
|
-
logger.I(
|
|
76
|
+
logger.I("exiting due to keyboard interrupt")
|
|
82
77
|
sys.exit(1)
|
ruyi/utils/ssl_patch.py
CHANGED
|
@@ -6,7 +6,6 @@ from typing import Final, NamedTuple
|
|
|
6
6
|
|
|
7
7
|
import certifi
|
|
8
8
|
|
|
9
|
-
from ..i18n import _
|
|
10
9
|
from ..log import RuyiConsoleLogger, RuyiLogger
|
|
11
10
|
from .global_mode import EnvGlobalModeProvider
|
|
12
11
|
|
|
@@ -36,7 +35,7 @@ def _get_system_ssl_default_verify_paths(logger: RuyiLogger) -> ssl.DefaultVerif
|
|
|
36
35
|
try:
|
|
37
36
|
parts = _query_linux_system_ssl_default_cert_paths(logger)
|
|
38
37
|
if parts is None:
|
|
39
|
-
logger.W(
|
|
38
|
+
logger.W("failed to probe system libcrypto")
|
|
40
39
|
else:
|
|
41
40
|
result = to_ssl_paths(parts)
|
|
42
41
|
except Exception as e:
|
ruyi/version.py
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
from typing import Final
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
RUYI_SEMVER: Final = "0.45.0"
|
|
3
|
+
RUYI_SEMVER: Final = "0.45.0-alpha.20251230"
|
|
6
4
|
RUYI_USER_AGENT: Final = f"ruyi/{RUYI_SEMVER}"
|
|
7
5
|
|
|
8
|
-
COPYRIGHT_NOTICE: Final =
|
|
9
|
-
"""\
|
|
6
|
+
COPYRIGHT_NOTICE: Final = """\
|
|
10
7
|
Copyright (C) Institute of Software, Chinese Academy of Sciences (ISCAS).
|
|
11
8
|
All rights reserved.
|
|
12
9
|
License: Apache-2.0 <https://www.apache.org/licenses/LICENSE-2.0>
|
|
13
10
|
\
|
|
14
11
|
"""
|
|
15
|
-
)
|
|
16
12
|
|
|
17
|
-
MPL_REDIST_NOTICE: Final =
|
|
18
|
-
"""\
|
|
13
|
+
MPL_REDIST_NOTICE: Final = """\
|
|
19
14
|
This distribution of ruyi contains code licensed under the Mozilla Public
|
|
20
15
|
License 2.0 (https://mozilla.org/MPL/2.0/). You can get the respective
|
|
21
16
|
project's sources from the project's official website:
|
|
@@ -23,4 +18,3 @@ project's sources from the project's official website:
|
|
|
23
18
|
* certifi: https://github.com/certifi/python-certifi
|
|
24
19
|
\
|
|
25
20
|
"""
|
|
26
|
-
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ruyi
|
|
3
|
-
Version: 0.45.
|
|
3
|
+
Version: 0.45.0a20251230
|
|
4
4
|
Summary: Package manager for RuyiSDK
|
|
5
5
|
License: Apache License
|
|
6
6
|
Version 2.0, January 2004
|
|
@@ -224,7 +224,6 @@ 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)
|
|
228
227
|
Requires-Dist: fastjsonschema (>=2.15.1)
|
|
229
228
|
Requires-Dist: jinja2 (>=3,<4)
|
|
230
229
|
Requires-Dist: pygit2 (>=1.6) ; python_version >= "3.11"
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
ruyi/__init__.py,sha256=_8k6Lm01mK35fGY7N9yQLF2SpmVPU70F2plkS6yG1YU,464
|
|
2
|
+
ruyi/__main__.py,sha256=jgWWxLHU07JJQSRRqWWR3EcZpauqRpaJju9q3DF9yHg,3335
|
|
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=kR3aEiDE3AfPoP0Zr7MO-09CKoExbkLLmPvve9oKaUg,6725
|
|
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=9kq5W3Ir_lfwImhvrUmQ1KTKy1aRCv_UU1CmL5eGyJs,4038
|
|
9
|
+
ruyi/cli/main.py,sha256=vSrYJJV8r8H-M0_vn25h5btUB1JWg5XK58EtXC9X3t4,4619
|
|
10
|
+
ruyi/cli/oobe.py,sha256=h7Aiudq0jDJm65BzMhbAHPjeS3GHC3wpsCfSdl3usII,2519
|
|
11
|
+
ruyi/cli/self_cli.py,sha256=Ir6xxe8SumjmU5qW2FmAaIhOTSKXMni4doCRaTAn_PQ,8812
|
|
12
|
+
ruyi/cli/user_input.py,sha256=ZJPyCAD7Aizkt37f_KDtW683aKvGZ2pL85Rg_y1LLfg,3711
|
|
13
|
+
ruyi/cli/version_cli.py,sha256=L2pejZ7LIPYLUTb9NIz4t51KB8ai8igPBuE64tyqUuI,1275
|
|
14
|
+
ruyi/config/__init__.py,sha256=j-nBewPMI1u3L-ICK4FU564k8GNziiLcJ1ObfOOlGDA,16696
|
|
15
|
+
ruyi/config/editor.py,sha256=piAJ-a68iX6IFWXy1g9OXoSs_3DardZwoaSPdStKKL0,4243
|
|
16
|
+
ruyi/config/errors.py,sha256=Yrzd3hX5Gb_bCawoVrWjFrLrpO-q_IOtg4ikE0P8ia0,2561
|
|
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=9rUbLtybBQ8x9qRXaMwz_yAMf51vb3wmYE0qm54P5Bk,20906
|
|
21
|
+
ruyi/device/provision_cli.py,sha256=sc6AF8ohWrXA-kIAYdZcD6sl1HHbj_dH2cCi-pjjOQg,1031
|
|
22
|
+
ruyi/log/__init__.py,sha256=ehgUl8iY1oRfP_nJKrln5lnvJFSPPU1J-3g-PK28YWk,6516
|
|
23
|
+
ruyi/mux/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
|
+
ruyi/mux/runtime.py,sha256=_d7p-4w2bA2jgCsgcEZxiV1HPnJqdFp0cy4uMGNBsd8,7116
|
|
25
|
+
ruyi/mux/venv/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
+
ruyi/mux/venv/emulator_cfg.py,sha256=vGw-pBtNii2fTllQqloN_o1FAFOOHgF7zDqLMVdIlzk,1125
|
|
27
|
+
ruyi/mux/venv/maker.py,sha256=6UabdjLKc77uWTjDRFlZda8Cm1v81inzgBmtQrD48ow,28684
|
|
28
|
+
ruyi/mux/venv/venv_cli.py,sha256=rIKNcYKu1j7ahHXNgv_ytYVR7qJOoly-TaHPvb21FGA,2974
|
|
29
|
+
ruyi/mux/venv_cfg.py,sha256=m75JCVLFWE1gE8OzcNDOHqwUc2c6ikJhZ-GhjsXv94U,6840
|
|
30
|
+
ruyi/pluginhost/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
+
ruyi/pluginhost/api.py,sha256=Zh69xJfR7PEbM6fjoFZRNqeqTneWAmC71NjA76HodSY,5711
|
|
32
|
+
ruyi/pluginhost/ctx.py,sha256=MsP1L7nchnbSrauId3GaQzv0YJLnWE0u_H3ZFEmjUX8,6590
|
|
33
|
+
ruyi/pluginhost/paths.py,sha256=3EVY3_i3LLff4Lk9py-E317C7_ysiRatfCiuxvCsVWw,4227
|
|
34
|
+
ruyi/pluginhost/plugin_cli.py,sha256=rLdXG4_OJ2nlaSjFBmTaclx_N2f0s_Wi-9qcSeq7h9I,968
|
|
35
|
+
ruyi/pluginhost/unsandboxed.py,sha256=A9T-6JFfDNiCAxq47_EhLo_rRmZ3Iyrod3teMWv3-XM,7122
|
|
36
|
+
ruyi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
+
ruyi/resource_bundle/__init__.py,sha256=yC1eQ4-EjD7PTr-m5T-l-YDFcblpy2j7i_WJAkC57tg,470
|
|
38
|
+
ruyi/resource_bundle/__main__.py,sha256=moZQB09_OU3BKaFJjtba4jX8TWilqqAOhxsjOlrqqZw,1566
|
|
39
|
+
ruyi/resource_bundle/data.py,sha256=I1gutOaCZziukFMnokYjbRFNDk-2TK4KhQS-ZtU7pV4,5839
|
|
40
|
+
ruyi/ruyipkg/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
|
+
ruyi/ruyipkg/admin_checksum.py,sha256=H4JthL4lViKQKEB7A_FTEX2c1G9tHp6N25Y83AUV6vc,2260
|
|
42
|
+
ruyi/ruyipkg/admin_cli.py,sha256=pPA88VZ-hjIxsf6Vl6OF72ZyEl5_swdl44aoxszu-AQ,2443
|
|
43
|
+
ruyi/ruyipkg/atom.py,sha256=S0mWmtI0HgfOnbkAK6BlHmCrAiHcJ-QVnub3iCiCJjU,5440
|
|
44
|
+
ruyi/ruyipkg/augmented_pkg.py,sha256=QbzYNHCRanFx9xwYRosN_dAEzOSxmOBxyBVli8SC9FE,6924
|
|
45
|
+
ruyi/ruyipkg/canonical_dump.py,sha256=Qu25YXwJpjWUBte0C3bmmaJxe7zyqfN-2-__u2_dJDM,9363
|
|
46
|
+
ruyi/ruyipkg/checksum.py,sha256=ChYFPXl7-Y8p_bDerkXOGroRz4k6ejjWY9ViaVWuEgk,1274
|
|
47
|
+
ruyi/ruyipkg/cli_completion.py,sha256=kJf7vN5rXi5zAwTI3dr4J8HdUzR3-ZXnsdaNQV6kqzo,1151
|
|
48
|
+
ruyi/ruyipkg/distfile.py,sha256=wkyYVcSM2b3vD462TtoltdLcUZElCwWvcZBiPG3lTZ0,7002
|
|
49
|
+
ruyi/ruyipkg/entity.py,sha256=s8h5kNaR2vsP6v_QUFIO6SZiUrt0jrb8GU11bNT6fn4,14498
|
|
50
|
+
ruyi/ruyipkg/entity_cli.py,sha256=hF66i3sJX8XVLIWq376GA9vzgegfQy-6s0x0L831Irk,3802
|
|
51
|
+
ruyi/ruyipkg/entity_provider.py,sha256=jDfS2Jh01PVHo0kb1XyI5WkZgL4fv21AooXLLwqK-1I,8741
|
|
52
|
+
ruyi/ruyipkg/fetcher.py,sha256=_btz2hkTz0uEUCCSAhOK7tlhAuvzCu42ZTUCP-RpU7U,9047
|
|
53
|
+
ruyi/ruyipkg/host.py,sha256=pmqgggi7koDCWgzFexwHpycv4SZ07VF6xUbi4s8FSKA,1399
|
|
54
|
+
ruyi/ruyipkg/install.py,sha256=N20h3iZ56_dJriBvUDDvmqVLP__k3YI6iH6--oor8yA,18054
|
|
55
|
+
ruyi/ruyipkg/install_cli.py,sha256=joIV5iY4iblDinoH2pgbHNYkMVWqMxtVNj89T0IpJuk,5267
|
|
56
|
+
ruyi/ruyipkg/list.py,sha256=iO7666xFEWKTDNtJqVLaaQKsp0BfLTzgXBwFFHrqCGc,4172
|
|
57
|
+
ruyi/ruyipkg/list_cli.py,sha256=9tRWWRcJv3yJqzup6Oc89E3xahGp5jIfybfEvwwd55I,2243
|
|
58
|
+
ruyi/ruyipkg/list_filter.py,sha256=F64_UhwUEiaUR73EkLu91qoUBA-Yz9mEVWj8XY46MXQ,5467
|
|
59
|
+
ruyi/ruyipkg/msg.py,sha256=d9uF1rBmdT8iVvpTU53XXtNTJzvNhIK68rO-4W4h5wc,3180
|
|
60
|
+
ruyi/ruyipkg/news.py,sha256=5uN4UYqvEW5MU_10W9MzwFo3lH25oZCvMMjfAjLed7U,3857
|
|
61
|
+
ruyi/ruyipkg/news_cli.py,sha256=s5mirEBmO2lZITfjcpzDakP7rNYPqopdM9odbwmAPpg,2378
|
|
62
|
+
ruyi/ruyipkg/news_store.py,sha256=ocTO4YDpL_HrKaIRFvJ_Gxvpmr7V7-R8b1B8f5Eue9c,5276
|
|
63
|
+
ruyi/ruyipkg/pkg_manifest.py,sha256=FmksKjQyBnU4zA3MFXiHdB2EjNmhs-J9km9vE-zBQlk,18836
|
|
64
|
+
ruyi/ruyipkg/profile.py,sha256=6xwL24crALShqD8bazGOIAFTYCpM_91mD8d6YMxM2FU,10762
|
|
65
|
+
ruyi/ruyipkg/profile_cli.py,sha256=ud9MS9JQLOtec_1tFRu669I-imVfi1DHU3AuBJym9mw,848
|
|
66
|
+
ruyi/ruyipkg/protocols.py,sha256=lPKRaAcK3DY3wmkyO2tKpFvPQ_4QA4aSNNsNLvi78O8,1833
|
|
67
|
+
ruyi/ruyipkg/repo.py,sha256=l5d4XPZS-ofbwlAOk5GZMM7AFGay1n1xDVzge935oA4,25231
|
|
68
|
+
ruyi/ruyipkg/state.py,sha256=Ie4vrt79Wp9P0L36tMj36tOtDlFnIb6uwVGDQCQyg8s,11544
|
|
69
|
+
ruyi/ruyipkg/unpack.py,sha256=hPd-lOnDXp1lEb4mdbLUEckT4QXblSFxz-dGAdwaAjc,11207
|
|
70
|
+
ruyi/ruyipkg/unpack_method.py,sha256=MonFFvcDb7MVsi2w4yitnCeZkmWmS7nRMMY-wSt9AMs,2106
|
|
71
|
+
ruyi/ruyipkg/update_cli.py,sha256=ywsAAUPctJ3_2qPDvFL2__ql9m8tGZ6ZfrwbSk30Xh4,1425
|
|
72
|
+
ruyi/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
73
|
+
ruyi/telemetry/aggregate.py,sha256=MhehVOtU7KLICHgOz3sZE5z3OgFa4OmlRIPqXOW_tBU,2334
|
|
74
|
+
ruyi/telemetry/event.py,sha256=GZnFj6E59Q7mjp-2VRApAZH3rT_bu4_cWb5QMCPm-Zc,982
|
|
75
|
+
ruyi/telemetry/provider.py,sha256=yOMDZ8Zn_znKiRQcJ-EOZH1pSavtkevt-_RNMV1yFQs,22332
|
|
76
|
+
ruyi/telemetry/scope.py,sha256=e45VPAvRAqSxrL0ESorN9SCnR_I6Bwi2CMPJDDshJEE,1133
|
|
77
|
+
ruyi/telemetry/store.py,sha256=IbikQ9dmcuf85SIxlWpXY1aydovM1EzXA9Q6hAo_mXE,10072
|
|
78
|
+
ruyi/telemetry/telemetry_cli.py,sha256=su8KeFgZv_PyppvpP4LqI9Bq59LnmCE236Boji5GZzg,4027
|
|
79
|
+
ruyi/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
80
|
+
ruyi/utils/ar.py,sha256=w9wiYYdbInLewr5IRTcP0TiOw2ibVDQEmnV0hHm9WlA,2271
|
|
81
|
+
ruyi/utils/ci.py,sha256=66DBm4ooA7yozDtXCJFd1n2jJXTsEnxPSpkNzLfE28M,2970
|
|
82
|
+
ruyi/utils/frontmatter.py,sha256=4EOohEYCZ_q6ncpDv7ktJYf9PN4WEdgFfdE9hZBV3Zg,1052
|
|
83
|
+
ruyi/utils/git.py,sha256=YspRRkfxLXluCv4LNx6q_mjkPdoX7WSM9aR7EfudqlM,5991
|
|
84
|
+
ruyi/utils/global_mode.py,sha256=9GES5RyisSXAo14_bP896Jat6BFru_N-DC1V_7bofWY,5684
|
|
85
|
+
ruyi/utils/l10n.py,sha256=l003oQ5M8fWIKQHbYTVSc6oHzFFGU2sbKac7Hh6FNFU,2530
|
|
86
|
+
ruyi/utils/markdown.py,sha256=Mpq--ClM4j9lm_-5zO53ptYePUTLI4rg0V1YshOwsf8,2654
|
|
87
|
+
ruyi/utils/mounts.py,sha256=31BGsVOpD2bO7PYpm8I1ogDHzP3MvrMWznKonS3Ajos,1210
|
|
88
|
+
ruyi/utils/node_info.py,sha256=8-4dtrr2Ww_Cb9iKH_WpTMOWx7wknJKRwMUUZJYo9dQ,6603
|
|
89
|
+
ruyi/utils/nuitka.py,sha256=7mdbmtKnUsGkIp1zxXgGWYrwZcCut3ipd0AP0DrbfZk,1112
|
|
90
|
+
ruyi/utils/porcelain.py,sha256=pF6ieSE2xlnC0HBADFY0m-uuwVNNME3wlbHo2jWdLFA,1403
|
|
91
|
+
ruyi/utils/prereqs.py,sha256=oWAaH-smpTMQxpHt782YBxqHxrTaheataslN988-a78,2076
|
|
92
|
+
ruyi/utils/ssl_patch.py,sha256=a5gf4br6nC39wTHsqiFtcJ-mGzqB-YzK6DHSeERLaHQ,5661
|
|
93
|
+
ruyi/utils/templating.py,sha256=94xBJTkIfDqmUBTc9hnLO54zQoC7hwGWONGF3YbaqHk,966
|
|
94
|
+
ruyi/utils/toml.py,sha256=aniIF3SGfR69_s3GWWwlnoKxW4B5IDVY2CM0eUI55_c,3501
|
|
95
|
+
ruyi/utils/url.py,sha256=Wyct6syS4GmZC6mY7SK-YgBWxKl3cOOBXtp9UtvGkto,186
|
|
96
|
+
ruyi/utils/xdg_basedir.py,sha256=RwVH199jPcLVsg5ngR62RaNS5hqnMpkdt31LqkCfa1g,2751
|
|
97
|
+
ruyi/version.py,sha256=d29zajfmsxqMKoF9B28V167SRpSrZD1HGVmnJifBE9U,610
|
|
98
|
+
ruyi-0.45.0a20251230.dist-info/METADATA,sha256=DByjgdcnqqVd3vYdXQl91gQ6RFmgkhs-IuqZQWY48wE,24459
|
|
99
|
+
ruyi-0.45.0a20251230.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
100
|
+
ruyi-0.45.0a20251230.dist-info/entry_points.txt,sha256=GXSNSy7OgFrnlU5xm5dE3l3PGO92Qf6VDIUCdvQNm8E,49
|
|
101
|
+
ruyi-0.45.0a20251230.dist-info/licenses/LICENSE-Apache.txt,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
102
|
+
ruyi-0.45.0a20251230.dist-info/RECORD,,
|