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.
Files changed (53) hide show
  1. ruyi/__main__.py +16 -4
  2. ruyi/cli/cmd.py +6 -5
  3. ruyi/cli/config_cli.py +14 -11
  4. ruyi/cli/main.py +14 -4
  5. ruyi/cli/oobe.py +7 -3
  6. ruyi/cli/self_cli.py +48 -34
  7. ruyi/cli/user_input.py +42 -12
  8. ruyi/cli/version_cli.py +11 -5
  9. ruyi/config/__init__.py +26 -2
  10. ruyi/config/errors.py +19 -7
  11. ruyi/device/provision.py +116 -55
  12. ruyi/device/provision_cli.py +6 -3
  13. ruyi/i18n/__init__.py +129 -0
  14. ruyi/log/__init__.py +6 -5
  15. ruyi/mux/runtime.py +19 -6
  16. ruyi/mux/venv/maker.py +93 -35
  17. ruyi/mux/venv/venv_cli.py +13 -10
  18. ruyi/pluginhost/plugin_cli.py +4 -3
  19. ruyi/resource_bundle/__init__.py +22 -8
  20. ruyi/resource_bundle/__main__.py +6 -5
  21. ruyi/resource_bundle/data.py +13 -9
  22. ruyi/ruyipkg/admin_checksum.py +4 -1
  23. ruyi/ruyipkg/admin_cli.py +9 -6
  24. ruyi/ruyipkg/augmented_pkg.py +15 -14
  25. ruyi/ruyipkg/checksum.py +8 -2
  26. ruyi/ruyipkg/distfile.py +33 -9
  27. ruyi/ruyipkg/entity.py +12 -2
  28. ruyi/ruyipkg/entity_cli.py +20 -12
  29. ruyi/ruyipkg/entity_provider.py +11 -2
  30. ruyi/ruyipkg/fetcher.py +38 -9
  31. ruyi/ruyipkg/install.py +143 -42
  32. ruyi/ruyipkg/install_cli.py +18 -15
  33. ruyi/ruyipkg/list.py +27 -20
  34. ruyi/ruyipkg/list_cli.py +12 -7
  35. ruyi/ruyipkg/news.py +23 -11
  36. ruyi/ruyipkg/news_cli.py +10 -7
  37. ruyi/ruyipkg/profile_cli.py +8 -2
  38. ruyi/ruyipkg/repo.py +22 -8
  39. ruyi/ruyipkg/unpack.py +42 -8
  40. ruyi/ruyipkg/unpack_method.py +5 -1
  41. ruyi/ruyipkg/update_cli.py +8 -3
  42. ruyi/telemetry/provider.py +74 -29
  43. ruyi/telemetry/telemetry_cli.py +9 -8
  44. ruyi/utils/git.py +18 -11
  45. ruyi/utils/prereqs.py +10 -5
  46. ruyi/utils/ssl_patch.py +2 -1
  47. ruyi/version.py +9 -3
  48. {ruyi-0.44.0b20251219.dist-info → ruyi-0.45.0.dist-info}/METADATA +2 -1
  49. ruyi-0.45.0.dist-info/RECORD +103 -0
  50. {ruyi-0.44.0b20251219.dist-info → ruyi-0.45.0.dist-info}/WHEEL +1 -1
  51. ruyi-0.44.0b20251219.dist-info/RECORD +0 -102
  52. {ruyi-0.44.0b20251219.dist-info → ruyi-0.45.0.dist-info}/entry_points.txt +0 -0
  53. {ruyi-0.44.0b20251219.dist-info → ruyi-0.45.0.dist-info}/licenses/LICENSE-Apache.txt +0 -0
@@ -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
- TELEMETRY_CONSENT_AND_UPLOAD_PROMPT = (
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 = "malformed telemetry state: unable to determine upload weekday, nothing will be uploaded"
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
- "you can opt out at any time by running [yellow]ruyi telemetry optout[/]"
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
- "you can re-enable telemetry data uploading at any time by running [yellow]ruyi telemetry consent[/]"
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
- "you can re-enable telemetry data uploads at any time by running [yellow]ruyi telemetry consent[/]"
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
- f"scope {scope}: usage information has already been uploaded today at {last_upload_time_str}"
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
- f"scope {scope}: usage information has already been uploaded sometime today"
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
- f"scope {scope}: the next upload will happen [bold green]today[/] if not already"
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
- f" - between [bold green]{next_upload_day_str}[/] and [bold green]{next_upload_day_end_str}[/]"
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
- "telemetry mode is [green]off[/]: nothing is collected or uploaded after the first run"
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 = calendar.day_name[upload_wday]
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
- "telemetry mode is [green]local[/]: local usage collection only, no usage uploads except if requested"
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
- "telemetry mode is [green]on[/]: usage data is collected and periodically uploaded"
403
+ _(
404
+ "telemetry mode is [green]on[/]: usage data is collected and periodically uploaded"
405
+ )
371
406
  )
372
407
  self.logger.I(
373
- f"non-tracking usage information will be uploaded to RuyiSDK-managed servers [bold green]every {upload_wday_name}[/]"
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
- 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}[/]"
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("- or give consent with [yellow]ruyi telemetry consent[/]")
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")
@@ -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
- f"URL of remote '[yellow]{remote_name}[/]' does not match expected URL"
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(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[/]")
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(f"failed to fetch from remote URL {remote_url}: {e}")
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, _ = repo.merge_analysis(remote_head)
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 = f"The command(s) {cmds_str} cannot be found in PATH, which [yellow]ruyi[/] requires"
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
- "please install them and press [green]Enter[/] to retry, or [green]Ctrl+C[/] to exit"
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
- RUYI_SEMVER: Final = "0.44.0-beta.20251219"
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.44.0b20251219
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,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.2.1
2
+ Generator: poetry-core 2.3.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any