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.
Files changed (53) hide show
  1. ruyi/__main__.py +4 -16
  2. ruyi/cli/cmd.py +5 -6
  3. ruyi/cli/config_cli.py +11 -14
  4. ruyi/cli/main.py +4 -14
  5. ruyi/cli/oobe.py +3 -7
  6. ruyi/cli/self_cli.py +34 -48
  7. ruyi/cli/user_input.py +12 -42
  8. ruyi/cli/version_cli.py +5 -11
  9. ruyi/config/__init__.py +2 -26
  10. ruyi/config/errors.py +7 -19
  11. ruyi/device/provision.py +55 -116
  12. ruyi/device/provision_cli.py +3 -6
  13. ruyi/log/__init__.py +5 -6
  14. ruyi/mux/runtime.py +6 -19
  15. ruyi/mux/venv/maker.py +35 -93
  16. ruyi/mux/venv/venv_cli.py +10 -13
  17. ruyi/pluginhost/plugin_cli.py +3 -4
  18. ruyi/resource_bundle/__init__.py +8 -22
  19. ruyi/resource_bundle/__main__.py +5 -6
  20. ruyi/resource_bundle/data.py +9 -13
  21. ruyi/ruyipkg/admin_checksum.py +1 -4
  22. ruyi/ruyipkg/admin_cli.py +6 -9
  23. ruyi/ruyipkg/augmented_pkg.py +14 -15
  24. ruyi/ruyipkg/checksum.py +2 -8
  25. ruyi/ruyipkg/distfile.py +9 -33
  26. ruyi/ruyipkg/entity.py +2 -12
  27. ruyi/ruyipkg/entity_cli.py +12 -20
  28. ruyi/ruyipkg/entity_provider.py +2 -11
  29. ruyi/ruyipkg/fetcher.py +9 -38
  30. ruyi/ruyipkg/install.py +42 -143
  31. ruyi/ruyipkg/install_cli.py +15 -18
  32. ruyi/ruyipkg/list.py +20 -27
  33. ruyi/ruyipkg/list_cli.py +7 -12
  34. ruyi/ruyipkg/news.py +11 -23
  35. ruyi/ruyipkg/news_cli.py +7 -10
  36. ruyi/ruyipkg/profile_cli.py +2 -8
  37. ruyi/ruyipkg/repo.py +8 -22
  38. ruyi/ruyipkg/unpack.py +8 -42
  39. ruyi/ruyipkg/unpack_method.py +1 -5
  40. ruyi/ruyipkg/update_cli.py +3 -8
  41. ruyi/telemetry/provider.py +29 -74
  42. ruyi/telemetry/telemetry_cli.py +8 -9
  43. ruyi/utils/git.py +11 -18
  44. ruyi/utils/prereqs.py +5 -10
  45. ruyi/utils/ssl_patch.py +1 -2
  46. ruyi/version.py +3 -9
  47. {ruyi-0.45.0.dist-info → ruyi-0.45.0a20251230.dist-info}/METADATA +1 -2
  48. ruyi-0.45.0a20251230.dist-info/RECORD +102 -0
  49. {ruyi-0.45.0.dist-info → ruyi-0.45.0a20251230.dist-info}/WHEEL +1 -1
  50. ruyi/i18n/__init__.py +0 -129
  51. ruyi-0.45.0.dist-info/RECORD +0 -103
  52. {ruyi-0.45.0.dist-info → ruyi-0.45.0a20251230.dist-info}/entry_points.txt +0 -0
  53. {ruyi-0.45.0.dist-info → ruyi-0.45.0a20251230.dist-info}/licenses/LICENSE-Apache.txt +0 -0
ruyi/config/__init__.py CHANGED
@@ -18,13 +18,6 @@ if TYPE_CHECKING:
18
18
  from ..utils.xdg_basedir import XDGPathEntry
19
19
  from .news import NewsReadStatusStore
20
20
 
21
- import babel
22
- # not sure why Pyright insists on individual imports
23
- # otherwise, at the use site (`except babel.core.UnknownLocaleError`):
24
- # error: "core" is not a known attribute of module "babel" (reportAttributeAccessIssue)
25
- from babel.core import UnknownLocaleError
26
-
27
- from ..i18n import _
28
21
  from . import errors
29
22
  from . import schema
30
23
 
@@ -122,11 +115,7 @@ class GlobalConfig:
122
115
  if iem is not None and not is_global_scope:
123
116
  iem_cfg_key = f"{schema.SECTION_INSTALLATION}.{schema.KEY_INSTALLATION_EXTERNALLY_MANAGED}"
124
117
  self.logger.W(
125
- _(
126
- "the config key [yellow]{key}[/] cannot be set from user config; ignoring"
127
- ).format(
128
- key=iem_cfg_key,
129
- ),
118
+ f"the config key [yellow]{iem_cfg_key}[/] cannot be set from user config; ignoring",
130
119
  )
131
120
  else:
132
121
  self.is_installation_externally_managed = bool(iem)
@@ -144,11 +133,7 @@ class GlobalConfig:
144
133
  if self.override_repo_dir:
145
134
  if not pathlib.Path(self.override_repo_dir).is_absolute():
146
135
  self.logger.W(
147
- _(
148
- "the local repo path '{path}' is not absolute; ignoring"
149
- ).format(
150
- path=self.override_repo_dir,
151
- )
136
+ f"the local repo path '{self.override_repo_dir}' is not absolute; ignoring"
152
137
  )
153
138
  self.override_repo_dir = None
154
139
 
@@ -289,15 +274,6 @@ class GlobalConfig:
289
274
  def lang_code(self) -> str:
290
275
  return self._lang_code
291
276
 
292
- @cached_property
293
- def babel_locale(self) -> babel.Locale:
294
- try:
295
- return babel.Locale.parse(self.lang_code)
296
- except UnknownLocaleError:
297
- # this can happen in case of unrecognized locale names, which
298
- # apparently falls back to "C"
299
- return babel.Locale.parse("en_US")
300
-
301
277
  @property
302
278
  def cache_root(self) -> os.PathLike[Any]:
303
279
  return self._dirs.app_cache
ruyi/config/errors.py CHANGED
@@ -1,8 +1,6 @@
1
1
  from os import PathLike
2
2
  from typing import Any, Sequence
3
3
 
4
- from ..i18n import _
5
-
6
4
 
7
5
  class InvalidConfigSectionError(Exception):
8
6
  def __init__(self, section: str) -> None:
@@ -10,7 +8,7 @@ class InvalidConfigSectionError(Exception):
10
8
  self._section = section
11
9
 
12
10
  def __str__(self) -> str:
13
- return _("invalid config section: {section}").format(section=self._section)
11
+ return f"invalid config section: {self._section}"
14
12
 
15
13
  def __repr__(self) -> str:
16
14
  return f"InvalidConfigSectionError({self._section!r})"
@@ -22,7 +20,7 @@ class InvalidConfigKeyError(Exception):
22
20
  self._key = key
23
21
 
24
22
  def __str__(self) -> str:
25
- return _("invalid config key: {key}").format(key=self._key)
23
+ return f"invalid config key: {self._key}"
26
24
 
27
25
  def __repr__(self) -> str:
28
26
  return f"InvalidConfigKeyError({self._key:!r})"
@@ -41,13 +39,7 @@ class InvalidConfigValueTypeError(TypeError):
41
39
  self._expected = expected
42
40
 
43
41
  def __str__(self) -> str:
44
- return _(
45
- "invalid value type for config key {key}: {actual_type}, expected {expected_type}"
46
- ).format(
47
- key=self._key,
48
- actual_type=type(self._val),
49
- expected_type=self._expected,
50
- )
42
+ return f"invalid value type for config key {self._key}: {type(self._val)}, expected {self._expected}"
51
43
 
52
44
  def __repr__(self) -> str:
53
45
  return f"InvalidConfigValueTypeError({self._key!r}, {self._val!r}, {self._expected:!r})"
@@ -66,10 +58,8 @@ class InvalidConfigValueError(ValueError):
66
58
  self._typ = typ
67
59
 
68
60
  def __str__(self) -> str:
69
- return _("invalid config value for key {key} (type {typ}): {val}").format(
70
- key=self._key,
71
- typ=self._typ,
72
- val=self._val,
61
+ return (
62
+ f"invalid config value for key {self._key} (type {self._typ}): {self._val}"
73
63
  )
74
64
 
75
65
  def __repr__(self) -> str:
@@ -84,7 +74,7 @@ class MalformedConfigFileError(Exception):
84
74
  self._path = path
85
75
 
86
76
  def __str__(self) -> str:
87
- return _("malformed config file: {path}").format(path=self._path)
77
+ return f"malformed config file: {self._path}"
88
78
 
89
79
  def __repr__(self) -> str:
90
80
  return f"MalformedConfigFileError({self._path:!r})"
@@ -96,9 +86,7 @@ class ProtectedGlobalConfigError(Exception):
96
86
  self._key = key
97
87
 
98
88
  def __str__(self) -> str:
99
- return _("attempt to modify protected global config key: {key}").format(
100
- key=self._key,
101
- )
89
+ return f"attempt to modify protected global config key: {self._key}"
102
90
 
103
91
  def __repr__(self) -> str:
104
92
  return f"ProtectedGlobalConfigError({self._key!r})"
ruyi/device/provision.py CHANGED
@@ -4,7 +4,6 @@ from typing import TYPE_CHECKING, TypedDict, TypeGuard, cast
4
4
 
5
5
  from ..cli import user_input
6
6
  from ..config import GlobalConfig
7
- from ..i18n import _
8
7
  from ..log import RuyiLogger
9
8
  from ..ruyipkg.atom import Atom, ExprAtom, SlugAtom
10
9
  from ..ruyipkg.entity_provider import BaseEntity
@@ -37,8 +36,7 @@ def do_provision_interactive(config: GlobalConfig) -> int:
37
36
  mr.ensure_git_repo()
38
37
 
39
38
  log.stdout(
40
- _(
41
- """
39
+ """
42
40
  [bold green]RuyiSDK Device Provisioning Wizard[/]
43
41
 
44
42
  This is a wizard intended to help you install a system on your device for your
@@ -54,12 +52,11 @@ required to flash images, you should arrange to allow your user account [yellow]
54
52
  access to necessary commands such as [yellow]dd[/]. Flashing will fail if the [yellow]sudo[/]
55
53
  configuration does not allow so.
56
54
  """
57
- )
58
55
  )
59
56
 
60
- if not user_input.ask_for_yesno_confirmation(log, _("Continue?")):
57
+ if not user_input.ask_for_yesno_confirmation(log, "Continue?"):
61
58
  log.stdout(
62
- _("\nExiting. You can restart the wizard whenever prepared."),
59
+ "\nExiting. You can restart the wizard whenever prepared.",
63
60
  end="\n\n",
64
61
  )
65
62
  return 1
@@ -71,9 +68,7 @@ configuration does not allow so.
71
68
  dev_choices = {k: v.display_name or "" for k, v in devices_by_id.items()}
72
69
  dev_id = user_input.ask_for_kv_choice(
73
70
  log,
74
- _(
75
- "\nThe following devices are currently supported by the wizard. Please pick your device:"
76
- ),
71
+ "\nThe following devices are currently supported by the wizard. Please pick your device:",
77
72
  dev_choices,
78
73
  )
79
74
  dev = devices_by_id[dev_id]
@@ -89,9 +84,7 @@ configuration does not allow so.
89
84
  variant_choices = [get_variant_display_name(dev, i) for i in variants]
90
85
  variant_idx = user_input.ask_for_choice(
91
86
  log,
92
- _(
93
- "\nThe device has the following variants. Please choose the one corresponding to your hardware at hand:"
94
- ),
87
+ "\nThe device has the following variants. Please choose the one corresponding to your hardware at hand:",
95
88
  variant_choices,
96
89
  )
97
90
  variant = variants[variant_idx]
@@ -108,9 +101,7 @@ configuration does not allow so.
108
101
  combo_choices = [combo.display_name or "" for combo in supported_combos]
109
102
  combo_idx = user_input.ask_for_choice(
110
103
  log,
111
- _(
112
- "\nThe following system configurations are supported by the device variant you have chosen. Please pick the one you want to put on the device:"
113
- ),
104
+ "\nThe following system configurations are supported by the device variant you have chosen. Please pick the one you want to put on the device:",
114
105
  combo_choices,
115
106
  )
116
107
  combo = supported_combos[combo_idx]
@@ -141,8 +132,7 @@ def do_provision_combo_interactive(
141
132
  combo: BaseEntity,
142
133
  ) -> int:
143
134
  logger = config.logger
144
- devid = f"{dev_decl.id}@{variant_decl.id}"
145
- logger.D(f"provisioning device variant '{devid}'")
135
+ logger.D(f"provisioning device variant '{dev_decl.id}@{variant_decl.id}'")
146
136
 
147
137
  # download packages
148
138
  pkg_atoms = combo.data.get("package_atoms", [])
@@ -151,36 +141,28 @@ def do_provision_combo_interactive(
151
141
  return 0
152
142
 
153
143
  logger.F(
154
- _(
155
- "malformed config: device variant '{devid}' asks for no packages but provides no messages either"
156
- ).format(
157
- devid=devid,
158
- )
144
+ f"malformed config: device variant '{dev_decl.id}@{variant_decl.id}' asks for no packages but provides no messages either"
159
145
  )
160
146
  return 1
161
147
 
162
148
  new_pkg_atoms = customize_package_versions(config, mr, pkg_atoms)
163
149
  if new_pkg_atoms is None:
164
- logger.stdout(
165
- _("\nExiting. You may restart the wizard at any time."), end="\n\n"
166
- )
150
+ logger.stdout("\nExiting. You may restart the wizard at any time.", end="\n\n")
167
151
  return 1
168
152
  else:
169
153
  pkg_atoms = new_pkg_atoms
170
154
 
171
155
  pkg_names_for_display = "\n".join(f" * [green]{i}[/]" for i in pkg_atoms)
172
156
  logger.stdout(
173
- _(
174
- "\nWe are about to download and install the following packages for your device:"
175
- ),
176
- end="\n\n",
157
+ f"""
158
+ We are about to download and install the following packages for your device:
159
+
160
+ {pkg_names_for_display}
161
+ """
177
162
  )
178
- logger.stdout(pkg_names_for_display, end="\n\n")
179
163
 
180
- if not user_input.ask_for_yesno_confirmation(logger, _("Proceed?")):
181
- logger.stdout(
182
- _("\nExiting. You may restart the wizard at any time."), end="\n\n"
183
- )
164
+ if not user_input.ask_for_yesno_confirmation(logger, "Proceed?"):
165
+ logger.stdout("\nExiting. You may restart the wizard at any time.", end="\n\n")
184
166
  return 1
185
167
 
186
168
  ret = do_install_atoms(
@@ -192,8 +174,8 @@ def do_provision_combo_interactive(
192
174
  reinstall=False,
193
175
  )
194
176
  if ret != 0:
195
- logger.F(_("failed to download and install packages"))
196
- logger.I(_("your device was not touched"))
177
+ logger.F("failed to download and install packages")
178
+ logger.I("your device was not touched")
197
179
  return 2
198
180
 
199
181
  strat_provider = ProvisionStrategyProvider(mr)
@@ -216,8 +198,7 @@ def do_provision_combo_interactive(
216
198
  host_blkdev_map: PartitionMapDecl = {}
217
199
  if requested_host_blkdevs:
218
200
  logger.stdout(
219
- _(
220
- """
201
+ """
221
202
  For initializing this target device, you should plug into this host system the
222
203
  device's storage (e.g. SD card or NVMe SSD), or a removable disk to be
223
204
  reformatted as a live medium, and note down the corresponding device file
@@ -225,7 +206,6 @@ path(s), e.g. /dev/sdX, /dev/nvmeXnY for whole disks; /dev/sdXY, /dev/nvmeXnYpZ
225
206
  for partitions. You may consult e.g. [yellow]sudo blkid[/] output for the
226
207
  information you will need later.
227
208
  """
228
- )
229
209
  )
230
210
  for part in requested_host_blkdevs:
231
211
  part_desc = get_part_desc(part)
@@ -233,9 +213,7 @@ information you will need later.
233
213
  while True:
234
214
  path = user_input.ask_for_file(
235
215
  logger,
236
- _("Please give the path for the {part_desc}:").format(
237
- part_desc=part_desc,
238
- ),
216
+ f"Please give the path for the {part_desc}:",
239
217
  )
240
218
 
241
219
  # Retrieve the latest mount info in case the user un-mounts
@@ -246,17 +224,10 @@ information you will need later.
246
224
  for m in blkdev_mounts:
247
225
  if m.source_path.samefile(path):
248
226
  logger.W(
249
- _(
250
- "path [cyan]'{path}'[/] is currently mounted at [yellow]'{target}'[/]"
251
- ).format(
252
- path=path,
253
- target=m.target,
254
- )
227
+ f"path [cyan]'{path}'[/] is currently mounted at [yellow]'{m.target}'[/]"
255
228
  )
256
229
  logger.I(
257
- _(
258
- "rejecting the path for safety; please double-check and retry"
259
- )
230
+ "rejecting the path for safety; please double-check and retry"
260
231
  )
261
232
  path_valid = False
262
233
  break
@@ -267,14 +238,12 @@ information you will need later.
267
238
 
268
239
  # final confirmation
269
240
  logger.stdout(
270
- _(
271
- """
241
+ """
272
242
  We have collected enough information for the actual flashing. Now is the last
273
243
  chance to re-check and confirm everything is fine.
274
244
 
275
245
  We are about to:
276
246
  """
277
- )
278
247
  )
279
248
 
280
249
  pretend_steps = "\n".join(
@@ -288,11 +257,9 @@ We are about to:
288
257
  )
289
258
  logger.stdout(pretend_steps, end="\n\n")
290
259
 
291
- if not user_input.ask_for_yesno_confirmation(logger, _("Proceed with flashing?")):
260
+ if not user_input.ask_for_yesno_confirmation(logger, "Proceed with flashing?"):
292
261
  logger.stdout(
293
- _(
294
- "\nExiting. The device is not touched and you may re-start the wizard at will."
295
- ),
262
+ "\nExiting. The device is not touched and you may re-start the wizard at will.",
296
263
  end="\n\n",
297
264
  )
298
265
  return 1
@@ -306,20 +273,18 @@ We are about to:
306
273
  # ask the user to ensure the device shows up
307
274
  # TODO: automate doing so
308
275
  logger.stdout(
309
- _("""
276
+ """
310
277
  Some flashing steps require the use of fastboot, in which case you should
311
278
  ensure the target device is showing up in [yellow]fastboot devices[/] output.
312
279
  Please [bold red]confirm it yourself before continuing[/].
313
- """)
280
+ """
314
281
  )
315
282
  if not user_input.ask_for_yesno_confirmation(
316
283
  logger,
317
- _("Is the device identified by fastboot now?"),
284
+ "Is the device identified by fastboot now?",
318
285
  ):
319
286
  logger.stdout(
320
- _(
321
- "\nAborting. The device is not touched. You may re-start the wizard after [yellow]fastboot[/] is fixed for the device."
322
- ),
287
+ "\nAborting. The device is not touched. You may re-start the wizard after [yellow]fastboot[/] is fixed for the device.",
323
288
  end="\n\n",
324
289
  )
325
290
  return 1
@@ -329,16 +294,16 @@ Please [bold red]confirm it yourself before continuing[/].
329
294
  logger.D(f"flashing {pkg} with strategy {strat}")
330
295
  ret = strat.flash(pkg_part_maps[pkg], host_blkdev_map)
331
296
  if ret != 0:
332
- logger.F(_("flashing failed, check your device right now"))
297
+ logger.F("flashing failed, check your device right now")
333
298
  return ret
334
299
 
335
300
  # parting words
336
301
  logger.stdout(
337
- _("""
302
+ """
338
303
  It seems the flashing has finished without errors.
339
304
 
340
305
  [bold green]Happy hacking![/]
341
- """)
306
+ """
342
307
  )
343
308
 
344
309
  maybe_render_postinst_msg(logger, mr, combo, config.lang_code)
@@ -349,11 +314,11 @@ It seems the flashing has finished without errors.
349
314
  def get_part_desc(part: PartitionKind) -> str:
350
315
  match part:
351
316
  case "disk":
352
- return _("target's whole disk")
317
+ return "target's whole disk"
353
318
  case "live":
354
- return _("removable disk to use as live medium")
319
+ return "removable disk to use as live medium"
355
320
  case _:
356
- return _("target's '{part}' partition").format(part=part)
321
+ return f"target's '{part}' partition"
357
322
 
358
323
 
359
324
  class PackageProvisionStrategyDecl(TypedDict):
@@ -524,19 +489,17 @@ def customize_package_versions(
524
489
 
525
490
  # Ask if the user wants to customize package versions
526
491
  logger.stdout(
527
- _(
528
- "By default, we'll install the latest version of each package, but in this case, other choices are possible."
529
- )
492
+ "By default, we'll install the latest version of each package, but in this case, other choices are possible."
530
493
  )
531
494
  if not user_input.ask_for_yesno_confirmation(
532
495
  logger,
533
- _("Would you like to customize package versions?"),
496
+ "Would you like to customize package versions?",
534
497
  ):
535
498
  return pkg_atoms
536
499
 
537
500
  while True: # Loop to allow restarting the selection process
538
501
  result: list[str] = []
539
- logger.stdout(_("\n[bold]Package Version Selection[/]"))
502
+ logger.stdout("\n[bold]Package Version Selection[/]")
540
503
 
541
504
  for atom_str in pkg_atoms:
542
505
  # Parse the atom to get package name
@@ -544,26 +507,18 @@ def customize_package_versions(
544
507
  if isinstance(a, ExprAtom):
545
508
  # If it's already an expression with version constraints, show the constraints
546
509
  logger.stdout(
547
- _(
548
- "\nPackage [green]{atom}[/] already has version constraints."
549
- ).format(
550
- atom=atom_str,
551
- )
510
+ f"\nPackage [green]{atom_str}[/] already has version constraints."
552
511
  )
553
512
  if not user_input.ask_for_yesno_confirmation(
554
513
  logger,
555
- _("Would you like to change them?"),
514
+ "Would you like to change them?",
556
515
  ):
557
516
  result.append(atom_str)
558
517
  continue
559
518
  elif isinstance(a, SlugAtom):
560
519
  # Slugs already fix the version, so we can't change them
561
520
  logger.W(
562
- _(
563
- "version cannot be overridden for slug atom [green]{atom}[/]"
564
- ).format(
565
- atom=atom_str,
566
- )
521
+ f"version cannot be overridden for slug atom [green]{atom_str}[/]"
567
522
  )
568
523
  result.append(atom_str)
569
524
  continue
@@ -571,24 +526,19 @@ def customize_package_versions(
571
526
  # Get all available versions for this package
572
527
  package_name = a.name
573
528
  category = a.category
574
- pkg_fullname = f"{category}/{package_name}" if category else package_name
575
529
 
576
530
  available_versions: "list[BoundPackageManifest]" = []
577
531
  try:
578
532
  available_versions = list(mr.iter_pkg_vers(package_name, category))
579
533
  except KeyError:
580
534
  logger.W(
581
- _("could not find package [yellow]{pkg}[/] in repository").format(
582
- pkg=pkg_fullname
583
- )
535
+ f"could not find package [yellow]{category}/{package_name}[/] in repository"
584
536
  )
585
537
  result.append(atom_str)
586
538
 
587
539
  if not available_versions:
588
540
  logger.W(
589
- _("no versions found for package [yellow]{pkg}[/]").format(
590
- pkg=pkg_fullname
591
- )
541
+ f"no versions found for package [yellow]{category}/{package_name}[/]"
592
542
  )
593
543
  result.append(atom_str)
594
544
  continue
@@ -597,12 +547,7 @@ def customize_package_versions(
597
547
  # If there's only one version available, use it
598
548
  selected_version = available_versions[0]
599
549
  logger.stdout(
600
- _(
601
- "Only one version available for [green]{pkg}[/]: [blue]{ver}[/], using it."
602
- ).format(
603
- pkg=pkg_fullname,
604
- ver=selected_version.ver,
605
- )
550
+ f"Only one version available for [green]{category}/{package_name}[/]: [blue]{selected_version.ver}[/], using it."
606
551
  )
607
552
  result.append(atom_str)
608
553
  continue
@@ -617,15 +562,11 @@ def customize_package_versions(
617
562
  remarks = []
618
563
 
619
564
  if pm.is_prerelease:
620
- remarks.append(_("prerelease"))
565
+ remarks.append("prerelease")
621
566
  if pm.service_level.has_known_issues:
622
- remarks.append(_("has known issues"))
567
+ remarks.append("has known issues")
623
568
  if pm.upstream_version:
624
- remarks.append(
625
- _("upstream: {upstream_ver}").format(
626
- upstream_ver=pm.upstream_version
627
- )
628
- )
569
+ remarks.append(f"upstream: {pm.upstream_version}")
629
570
 
630
571
  remark_str = f" ({', '.join(remarks)})" if remarks else ""
631
572
  version_choices.append(f"{version_str}{remark_str}")
@@ -633,9 +574,7 @@ def customize_package_versions(
633
574
  # Ask the user to select a version
634
575
  version_idx = user_input.ask_for_choice(
635
576
  logger,
636
- _("\nSelect a version for package [green]{pkg}[/]:").format(
637
- pkg=pkg_fullname,
638
- ),
577
+ f"\nSelect a version for package [green]{category or ''}{('/' + package_name) if category else package_name}[/]:",
639
578
  version_choices,
640
579
  )
641
580
 
@@ -647,27 +586,27 @@ def customize_package_versions(
647
586
  else:
648
587
  new_atom = f"{package_name}(=={selected_version.ver})"
649
588
 
650
- logger.stdout(_("Selected: [blue]{new_atom}[/]").format(new_atom=new_atom))
589
+ logger.stdout(f"Selected: [blue]{new_atom}[/]")
651
590
  result.append(new_atom)
652
591
 
653
- logger.stdout(_("\nPackage versions to be installed:"))
592
+ logger.stdout("\nPackage versions to be installed:")
654
593
  for atom in result:
655
594
  logger.stdout(f" * [green]{atom}[/]")
656
595
 
657
596
  confirmation = user_input.ask_for_choice(
658
597
  logger,
659
- _("\nHow would you like to proceed?"),
598
+ "\nHow would you like to proceed?",
660
599
  [
661
- _("Continue with these versions"),
662
- _("Restart version selection"),
663
- _("Abort device provisioning"),
600
+ "Continue with these versions",
601
+ "Restart version selection",
602
+ "Abort device provisioning",
664
603
  ],
665
604
  )
666
605
 
667
606
  if confirmation == 0: # Continue with these versions
668
607
  return result
669
608
  elif confirmation == 1: # Restart version selection
670
- logger.stdout(_("\nRestarting package version selection..."))
609
+ logger.stdout("\nRestarting package version selection...")
671
610
  continue
672
611
  else: # Abort installation
673
612
  return None
@@ -2,7 +2,6 @@ import argparse
2
2
  from typing import TYPE_CHECKING
3
3
 
4
4
  from ..cli.cmd import RootCommand
5
- from ..i18n import _
6
5
 
7
6
  if TYPE_CHECKING:
8
7
  from ..cli.completion import ArgumentParser
@@ -13,7 +12,7 @@ class DeviceCommand(
13
12
  RootCommand,
14
13
  cmd="device",
15
14
  has_subcommands=True,
16
- help=_("Manage devices"),
15
+ help="Manage devices",
17
16
  ):
18
17
  @classmethod
19
18
  def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
@@ -24,7 +23,7 @@ class DeviceProvisionCommand(
24
23
  DeviceCommand,
25
24
  cmd="provision",
26
25
  aliases=["flash"],
27
- help=_("Interactively initialize a device for development"),
26
+ help="Interactively initialize a device for development",
28
27
  ):
29
28
  @classmethod
30
29
  def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
@@ -37,7 +36,5 @@ class DeviceProvisionCommand(
37
36
  try:
38
37
  return do_provision_interactive(cfg)
39
38
  except KeyboardInterrupt:
40
- cfg.logger.stdout(
41
- _("\n\nKeyboard interrupt received, exiting."), end="\n\n"
42
- )
39
+ cfg.logger.stdout("\n\nKeyboard interrupt received, exiting.", end="\n\n")
43
40
  return 1
ruyi/log/__init__.py CHANGED
@@ -11,7 +11,6 @@ if TYPE_CHECKING:
11
11
  from rich.console import Console, RenderableType
12
12
  from rich.text import Text
13
13
 
14
- from ..i18n import _
15
14
  from ..utils.global_mode import ProvidesGlobalMode
16
15
  from ..utils.porcelain import PorcelainEntity, PorcelainEntityType, PorcelainOutput
17
16
 
@@ -218,7 +217,7 @@ class RuyiConsoleLogger(RuyiLogger):
218
217
  return self._emit_porcelain_log("F", message, sep, *objects)
219
218
 
220
219
  return self.log_console.print(
221
- _("[bold red]fatal error:[/] {message}").format(message=message),
220
+ f"[bold red]fatal error:[/] {message}",
222
221
  *objects,
223
222
  sep=sep,
224
223
  end=end,
@@ -235,7 +234,7 @@ class RuyiConsoleLogger(RuyiLogger):
235
234
  return self._emit_porcelain_log("I", message, sep, *objects)
236
235
 
237
236
  return self.log_console.print(
238
- _("[bold green]info:[/] {message}").format(message=message),
237
+ f"[bold green]info:[/] {message}",
239
238
  *objects,
240
239
  sep=sep,
241
240
  end=end,
@@ -252,7 +251,7 @@ class RuyiConsoleLogger(RuyiLogger):
252
251
  return self._emit_porcelain_log("W", message, sep, *objects)
253
252
 
254
253
  return self.log_console.print(
255
- _("[bold yellow]warn:[/] {message}").format(message=message),
254
+ f"[bold yellow]warn:[/] {message}",
256
255
  *objects,
257
256
  sep=sep,
258
257
  end=end,
@@ -264,10 +263,10 @@ def humanize_list(
264
263
  *,
265
264
  sep: str = ", ",
266
265
  item_color: str | None = None,
267
- empty_prompt: str | None = None,
266
+ empty_prompt: str = "(none)",
268
267
  ) -> str:
269
268
  if not obj:
270
- return empty_prompt if empty_prompt is not None else _("(none)")
269
+ return empty_prompt
271
270
  if item_color is None:
272
271
  return sep.join(obj)
273
272
  return sep.join(f"[{item_color}]{x}[/]" for x in obj)