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/ruyipkg/fetcher.py
CHANGED
|
@@ -7,7 +7,6 @@ from typing import Any, Final
|
|
|
7
7
|
import requests
|
|
8
8
|
from rich import progress
|
|
9
9
|
|
|
10
|
-
from ..i18n import _
|
|
11
10
|
from ..log import RuyiLogger
|
|
12
11
|
|
|
13
12
|
ENV_OVERRIDE_FETCHER: Final = "RUYI_OVERRIDE_FETCHER"
|
|
@@ -41,31 +40,19 @@ class BaseFetcher:
|
|
|
41
40
|
) -> bool:
|
|
42
41
|
for t in range(retries):
|
|
43
42
|
if t > 0:
|
|
44
|
-
self._logger.I(
|
|
45
|
-
_("retrying download ({current} of {total} times)").format(
|
|
46
|
-
current=t + 1,
|
|
47
|
-
total=retries,
|
|
48
|
-
)
|
|
49
|
-
)
|
|
43
|
+
self._logger.I(f"retrying download ({t + 1} of {retries} times)")
|
|
50
44
|
if self.fetch_one(url, dest, resume):
|
|
51
45
|
return True
|
|
52
46
|
return False
|
|
53
47
|
|
|
54
48
|
def fetch(self, *, resume: bool = False, retries: int = 3) -> None:
|
|
55
49
|
for url in self.urls:
|
|
56
|
-
self._logger.I(
|
|
57
|
-
_("downloading {url} to {dest}").format(
|
|
58
|
-
url=url,
|
|
59
|
-
dest=self.dest,
|
|
60
|
-
)
|
|
61
|
-
)
|
|
50
|
+
self._logger.I(f"downloading {url} to {self.dest}")
|
|
62
51
|
if self.fetch_one_with_retry(url, self.dest, resume, retries):
|
|
63
52
|
return
|
|
64
53
|
# all URLs have been tried and all have failed
|
|
65
54
|
raise RuntimeError(
|
|
66
|
-
|
|
67
|
-
dest=self.dest,
|
|
68
|
-
)
|
|
55
|
+
f"failed to fetch '{self.dest}': all source URLs have failed"
|
|
69
56
|
)
|
|
70
57
|
|
|
71
58
|
@classmethod
|
|
@@ -91,7 +78,7 @@ def get_usable_fetcher_cls(logger: RuyiLogger) -> type[BaseFetcher]:
|
|
|
91
78
|
|
|
92
79
|
if _fetcher_cache_populated:
|
|
93
80
|
if _cached_usable_fetcher_class is None:
|
|
94
|
-
raise RuntimeError(
|
|
81
|
+
raise RuntimeError("no fetcher is available on the system")
|
|
95
82
|
return _cached_usable_fetcher_class
|
|
96
83
|
|
|
97
84
|
_fetcher_cache_populated = True
|
|
@@ -101,16 +88,10 @@ def get_usable_fetcher_cls(logger: RuyiLogger) -> type[BaseFetcher]:
|
|
|
101
88
|
|
|
102
89
|
cls = KNOWN_FETCHERS.get(override_name)
|
|
103
90
|
if cls is None:
|
|
104
|
-
raise RuntimeError(
|
|
105
|
-
_("unknown fetcher '{name}'").format(
|
|
106
|
-
name=override_name,
|
|
107
|
-
)
|
|
108
|
-
)
|
|
91
|
+
raise RuntimeError(f"unknown fetcher '{override_name}'")
|
|
109
92
|
if not cls.is_available(logger):
|
|
110
93
|
raise RuntimeError(
|
|
111
|
-
|
|
112
|
-
name=override_name,
|
|
113
|
-
)
|
|
94
|
+
f"the requested fetcher '{override_name}' is unavailable on the system"
|
|
114
95
|
)
|
|
115
96
|
_cached_usable_fetcher_class = cls
|
|
116
97
|
return cls
|
|
@@ -122,7 +103,7 @@ def get_usable_fetcher_cls(logger: RuyiLogger) -> type[BaseFetcher]:
|
|
|
122
103
|
_cached_usable_fetcher_class = cls
|
|
123
104
|
return cls
|
|
124
105
|
|
|
125
|
-
raise RuntimeError(
|
|
106
|
+
raise RuntimeError("no fetcher is available on the system")
|
|
126
107
|
|
|
127
108
|
|
|
128
109
|
class CurlFetcher(BaseFetcher):
|
|
@@ -171,12 +152,7 @@ class CurlFetcher(BaseFetcher):
|
|
|
171
152
|
retcode = subprocess.call(argv)
|
|
172
153
|
if retcode != 0:
|
|
173
154
|
self._logger.W(
|
|
174
|
-
|
|
175
|
-
"failed to fetch distfile: command '{cmd}' returned {retcode}"
|
|
176
|
-
).format(
|
|
177
|
-
cmd=" ".join(argv),
|
|
178
|
-
retcode=retcode,
|
|
179
|
-
)
|
|
155
|
+
f"failed to fetch distfile: command '{' '.join(argv)}' returned {retcode}"
|
|
180
156
|
)
|
|
181
157
|
return False
|
|
182
158
|
|
|
@@ -214,12 +190,7 @@ class WgetFetcher(BaseFetcher):
|
|
|
214
190
|
retcode = subprocess.call(argv)
|
|
215
191
|
if retcode != 0:
|
|
216
192
|
self._logger.W(
|
|
217
|
-
|
|
218
|
-
"failed to fetch distfile: command '{cmd}' returned {retcode}"
|
|
219
|
-
).format(
|
|
220
|
-
cmd=" ".join(argv),
|
|
221
|
-
retcode=retcode,
|
|
222
|
-
)
|
|
193
|
+
f"failed to fetch distfile: command '{' '.join(argv)}' returned {retcode}"
|
|
223
194
|
)
|
|
224
195
|
return False
|
|
225
196
|
|
ruyi/ruyipkg/install.py
CHANGED
|
@@ -8,7 +8,6 @@ from ruyi.ruyipkg.state import BoundInstallationStateStore
|
|
|
8
8
|
|
|
9
9
|
from ..cli.user_input import ask_for_yesno_confirmation
|
|
10
10
|
from ..config import GlobalConfig
|
|
11
|
-
from ..i18n import _
|
|
12
11
|
from ..telemetry.scope import TelemetryScope
|
|
13
12
|
from .atom import Atom
|
|
14
13
|
from .distfile import Distfile
|
|
@@ -44,16 +43,12 @@ def do_extract_atoms(
|
|
|
44
43
|
a = Atom.parse(a_str)
|
|
45
44
|
pm = a.match_in_repo(mr, cfg.include_prereleases)
|
|
46
45
|
if pm is None:
|
|
47
|
-
logger.F(
|
|
48
|
-
_("atom {atom} matches no package in the repository").format(
|
|
49
|
-
atom=a_str,
|
|
50
|
-
)
|
|
51
|
-
)
|
|
46
|
+
logger.F(f"atom {a_str} matches no package in the repository")
|
|
52
47
|
return 1
|
|
53
48
|
|
|
54
49
|
sv = pm.service_level
|
|
55
50
|
if sv.has_known_issues:
|
|
56
|
-
logger.W(
|
|
51
|
+
logger.W("package has known issue(s)")
|
|
57
52
|
for s in sv.render_known_issues(pm.repo.messages, cfg.lang_code):
|
|
58
53
|
logger.I(s)
|
|
59
54
|
|
|
@@ -102,20 +97,12 @@ def _do_extract_pkg(
|
|
|
102
97
|
bm = pm.binary_metadata
|
|
103
98
|
sm = pm.source_metadata
|
|
104
99
|
if bm is None and sm is None:
|
|
105
|
-
logger.F(
|
|
106
|
-
_("don't know how to extract package [green]{pkg}[/]").format(
|
|
107
|
-
pkg=pkg_name,
|
|
108
|
-
)
|
|
109
|
-
)
|
|
100
|
+
logger.F(f"don't know how to extract package [green]{pkg_name}[/]")
|
|
110
101
|
return 2
|
|
111
102
|
|
|
112
103
|
if bm is not None and sm is not None:
|
|
113
104
|
logger.F(
|
|
114
|
-
|
|
115
|
-
"cannot handle package [green]{pkg}[/]: package is both binary and source"
|
|
116
|
-
).format(
|
|
117
|
-
pkg=pkg_name,
|
|
118
|
-
)
|
|
105
|
+
f"cannot handle package [green]{pkg_name}[/]: package is both binary and source"
|
|
119
106
|
)
|
|
120
107
|
return 2
|
|
121
108
|
|
|
@@ -127,10 +114,7 @@ def _do_extract_pkg(
|
|
|
127
114
|
|
|
128
115
|
if not distfiles_for_host:
|
|
129
116
|
logger.F(
|
|
130
|
-
|
|
131
|
-
pkg=pkg_name,
|
|
132
|
-
host=canonicalized_host,
|
|
133
|
-
)
|
|
117
|
+
f"package [green]{pkg_name}[/] declares no distfile for host {canonicalized_host}"
|
|
134
118
|
)
|
|
135
119
|
return 2
|
|
136
120
|
|
|
@@ -146,21 +130,13 @@ def _do_extract_pkg(
|
|
|
146
130
|
logger.D("skipping extraction because [yellow]--fetch-only[/] is given")
|
|
147
131
|
continue
|
|
148
132
|
|
|
149
|
-
logger.I(
|
|
150
|
-
_("extracting [green]{distfile}[/] for package [green]{pkg}[/]").format(
|
|
151
|
-
distfile=df_name,
|
|
152
|
-
pkg=pkg_name,
|
|
153
|
-
)
|
|
154
|
-
)
|
|
133
|
+
logger.I(f"extracting [green]{df_name}[/] for package [green]{pkg_name}[/]")
|
|
155
134
|
# unpack into destination
|
|
156
135
|
df.unpack(dest_dir, logger)
|
|
157
136
|
|
|
158
137
|
if not fetch_only:
|
|
159
138
|
logger.I(
|
|
160
|
-
|
|
161
|
-
pkg=pkg_name,
|
|
162
|
-
dest_dir=dest_dir,
|
|
163
|
-
)
|
|
139
|
+
f"package [green]{pkg_name}[/] has been extracted to {dest_dir}",
|
|
164
140
|
)
|
|
165
141
|
|
|
166
142
|
return 0
|
|
@@ -182,15 +158,13 @@ def do_install_atoms(
|
|
|
182
158
|
a = Atom.parse(a_str)
|
|
183
159
|
pm = a.match_in_repo(mr, config.include_prereleases)
|
|
184
160
|
if pm is None:
|
|
185
|
-
logger.F(
|
|
186
|
-
_("atom {atom} matches no package in the repository").format(atom=a_str)
|
|
187
|
-
)
|
|
161
|
+
logger.F(f"atom {a_str} matches no package in the repository")
|
|
188
162
|
return 1
|
|
189
163
|
pkg_name = pm.name_for_installation
|
|
190
164
|
|
|
191
165
|
sv = pm.service_level
|
|
192
166
|
if sv.has_known_issues:
|
|
193
|
-
logger.W(
|
|
167
|
+
logger.W("package has known issue(s)")
|
|
194
168
|
for s in sv.render_known_issues(pm.repo.messages, config.lang_code):
|
|
195
169
|
logger.I(s)
|
|
196
170
|
|
|
@@ -239,11 +213,7 @@ def do_install_atoms(
|
|
|
239
213
|
return ret
|
|
240
214
|
continue
|
|
241
215
|
|
|
242
|
-
logger.F(
|
|
243
|
-
_("don't know how to handle non-binary package [green]{pkg}[/]").format(
|
|
244
|
-
pkg=pkg_name,
|
|
245
|
-
)
|
|
246
|
-
)
|
|
216
|
+
logger.F(f"don't know how to handle non-binary package [green]{pkg_name}[/]")
|
|
247
217
|
return 2
|
|
248
218
|
|
|
249
219
|
return 0
|
|
@@ -279,17 +249,11 @@ def _do_install_binary_pkg(
|
|
|
279
249
|
|
|
280
250
|
if is_installed:
|
|
281
251
|
if not reinstall:
|
|
282
|
-
logger.I(
|
|
283
|
-
_("skipping already installed package [green]{pkg}[/]").format(
|
|
284
|
-
pkg=pkg_name,
|
|
285
|
-
)
|
|
286
|
-
)
|
|
252
|
+
logger.I(f"skipping already installed package [green]{pkg_name}[/]")
|
|
287
253
|
return 0
|
|
288
254
|
|
|
289
255
|
logger.W(
|
|
290
|
-
|
|
291
|
-
"package [green]{pkg}[/] seems already installed; purging and re-installing due to [yellow]--reinstall[/]"
|
|
292
|
-
).format(pkg=pkg_name)
|
|
256
|
+
f"package [green]{pkg_name}[/] seems already installed; purging and re-installing due to [yellow]--reinstall[/]"
|
|
293
257
|
)
|
|
294
258
|
# Remove from state tracking before purging
|
|
295
259
|
rgs.remove_installation(
|
|
@@ -326,12 +290,7 @@ def _do_install_binary_pkg(
|
|
|
326
290
|
install_path=install_root,
|
|
327
291
|
)
|
|
328
292
|
|
|
329
|
-
logger.I(
|
|
330
|
-
_("package [green]{pkg}[/] installed to [yellow]{install_root}[/]").format(
|
|
331
|
-
pkg=pkg_name,
|
|
332
|
-
install_root=install_root,
|
|
333
|
-
)
|
|
334
|
-
)
|
|
293
|
+
logger.I(f"package [green]{pkg_name}[/] installed to [yellow]{install_root}[/]")
|
|
335
294
|
return 0
|
|
336
295
|
|
|
337
296
|
|
|
@@ -353,10 +312,7 @@ def _do_install_binary_pkg_to(
|
|
|
353
312
|
distfiles_for_host = bm.get_distfile_names_for_host(str(canonicalized_host))
|
|
354
313
|
if not distfiles_for_host:
|
|
355
314
|
logger.F(
|
|
356
|
-
|
|
357
|
-
pkg=pkg_name,
|
|
358
|
-
host=canonicalized_host,
|
|
359
|
-
)
|
|
315
|
+
f"package [green]{pkg_name}[/] declares no binary for host {canonicalized_host}"
|
|
360
316
|
)
|
|
361
317
|
return 2
|
|
362
318
|
|
|
@@ -367,17 +323,10 @@ def _do_install_binary_pkg_to(
|
|
|
367
323
|
df.ensure(logger)
|
|
368
324
|
|
|
369
325
|
if fetch_only:
|
|
370
|
-
logger.D(
|
|
371
|
-
_("skipping installation because [yellow]--fetch-only[/] is given")
|
|
372
|
-
)
|
|
326
|
+
logger.D("skipping installation because [yellow]--fetch-only[/] is given")
|
|
373
327
|
continue
|
|
374
328
|
|
|
375
|
-
logger.I(
|
|
376
|
-
_("extracting [green]{distfile}[/] for package [green]{pkg}[/]").format(
|
|
377
|
-
distfile=df_name,
|
|
378
|
-
pkg=pkg_name,
|
|
379
|
-
)
|
|
380
|
-
)
|
|
329
|
+
logger.I(f"extracting [green]{df_name}[/] for package [green]{pkg_name}[/]")
|
|
381
330
|
df.unpack(install_root, logger)
|
|
382
331
|
|
|
383
332
|
return 0
|
|
@@ -412,17 +361,11 @@ def _do_install_blob_pkg(
|
|
|
412
361
|
|
|
413
362
|
if is_installed:
|
|
414
363
|
if not reinstall:
|
|
415
|
-
logger.I(
|
|
416
|
-
_("skipping already installed package [green]{pkg}[/]").format(
|
|
417
|
-
pkg=pkg_name,
|
|
418
|
-
)
|
|
419
|
-
)
|
|
364
|
+
logger.I(f"skipping already installed package [green]{pkg_name}[/]")
|
|
420
365
|
return 0
|
|
421
366
|
|
|
422
367
|
logger.W(
|
|
423
|
-
|
|
424
|
-
"package [green]{pkg}[/] seems already installed; purging and re-installing due to [yellow]--reinstall[/]"
|
|
425
|
-
).format(pkg=pkg_name)
|
|
368
|
+
f"package [green]{pkg_name}[/] seems already installed; purging and re-installing due to [yellow]--reinstall[/]"
|
|
426
369
|
)
|
|
427
370
|
# Remove from state tracking before purging
|
|
428
371
|
rgs.remove_installation(
|
|
@@ -458,12 +401,7 @@ def _do_install_blob_pkg(
|
|
|
458
401
|
install_path=install_root,
|
|
459
402
|
)
|
|
460
403
|
|
|
461
|
-
logger.I(
|
|
462
|
-
_("package [green]{pkg}[/] installed to [yellow]{install_root}[/]").format(
|
|
463
|
-
pkg=pkg_name,
|
|
464
|
-
install_root=install_root,
|
|
465
|
-
)
|
|
466
|
-
)
|
|
404
|
+
logger.I(f"package [green]{pkg_name}[/] installed to [yellow]{install_root}[/]")
|
|
467
405
|
return 0
|
|
468
406
|
|
|
469
407
|
|
|
@@ -482,9 +420,7 @@ def _do_install_blob_pkg_to(
|
|
|
482
420
|
dfs = pm.distfiles
|
|
483
421
|
distfile_names = bm.get_distfile_names()
|
|
484
422
|
if not distfile_names:
|
|
485
|
-
logger.F(
|
|
486
|
-
_("package [green]{pkg}[/] declares no blob distfile").format(pkg=pkg_name)
|
|
487
|
-
)
|
|
423
|
+
logger.F(f"package [green]{pkg_name}[/] declares no blob distfile")
|
|
488
424
|
return 2
|
|
489
425
|
|
|
490
426
|
for df_name in distfile_names:
|
|
@@ -494,17 +430,10 @@ def _do_install_blob_pkg_to(
|
|
|
494
430
|
df.ensure(logger)
|
|
495
431
|
|
|
496
432
|
if fetch_only:
|
|
497
|
-
logger.D(
|
|
498
|
-
_("skipping installation because [yellow]--fetch-only[/] is given")
|
|
499
|
-
)
|
|
433
|
+
logger.D("skipping installation because [yellow]--fetch-only[/] is given")
|
|
500
434
|
continue
|
|
501
435
|
|
|
502
|
-
logger.I(
|
|
503
|
-
_("extracting [green]{distfile}[/] for package [green]{pkg}[/]").format(
|
|
504
|
-
distfile=df_name,
|
|
505
|
-
pkg=pkg_name,
|
|
506
|
-
)
|
|
507
|
-
)
|
|
436
|
+
logger.I(f"extracting [green]{df_name}[/] for package [green]{pkg_name}[/]")
|
|
508
437
|
df.unpack_or_symlink(install_root, logger)
|
|
509
438
|
|
|
510
439
|
return 0
|
|
@@ -528,31 +457,21 @@ def do_uninstall_atoms(
|
|
|
528
457
|
a = Atom.parse(a_str)
|
|
529
458
|
pm = a.match_in_repo(bis, config.include_prereleases)
|
|
530
459
|
if pm is None:
|
|
531
|
-
logger.F(
|
|
532
|
-
_("atom [yellow]{atom}[/] is non-existent or not installed").format(
|
|
533
|
-
atom=a_str,
|
|
534
|
-
)
|
|
535
|
-
)
|
|
460
|
+
logger.F(f"atom [yellow]{a_str}[/] is non-existent or not installed")
|
|
536
461
|
return 1
|
|
537
462
|
pms_to_uninstall.append((a_str, pm))
|
|
538
463
|
|
|
539
464
|
if not pms_to_uninstall:
|
|
540
|
-
logger.I(
|
|
465
|
+
logger.I("no packages to uninstall")
|
|
541
466
|
return 0
|
|
542
467
|
|
|
543
|
-
logger.I(
|
|
544
|
-
for
|
|
545
|
-
logger.I(
|
|
546
|
-
_(" - [green]{category}/{name}[/] ({version})").format(
|
|
547
|
-
category=pm.category,
|
|
548
|
-
name=pm.name,
|
|
549
|
-
version=pm.ver,
|
|
550
|
-
)
|
|
551
|
-
)
|
|
468
|
+
logger.I("the following packages will be uninstalled:")
|
|
469
|
+
for _, pm in pms_to_uninstall:
|
|
470
|
+
logger.I(f" - [green]{pm.category}/{pm.name}[/] ({pm.ver})")
|
|
552
471
|
|
|
553
472
|
if not assume_yes:
|
|
554
|
-
if not ask_for_yesno_confirmation(logger,
|
|
555
|
-
logger.I(
|
|
473
|
+
if not ask_for_yesno_confirmation(logger, "Proceed?", default=False):
|
|
474
|
+
logger.I("uninstallation aborted")
|
|
556
475
|
return 0
|
|
557
476
|
|
|
558
477
|
for a_str, pm in pms_to_uninstall:
|
|
@@ -585,11 +504,7 @@ def do_uninstall_atoms(
|
|
|
585
504
|
return ret
|
|
586
505
|
continue
|
|
587
506
|
|
|
588
|
-
logger.F(
|
|
589
|
-
_("don't know how to handle non-binary package [green]{pkg}[/]").format(
|
|
590
|
-
pkg=pkg_name,
|
|
591
|
-
)
|
|
592
|
-
)
|
|
507
|
+
logger.F(f"don't know how to handle non-binary package [green]{pkg_name}[/]")
|
|
593
508
|
return 2
|
|
594
509
|
|
|
595
510
|
return 0
|
|
@@ -619,29 +534,21 @@ def _do_uninstall_binary_pkg(
|
|
|
619
534
|
# Check directory existence if the PM state says the package is not installed
|
|
620
535
|
if not is_installed:
|
|
621
536
|
if not os.path.exists(install_root):
|
|
622
|
-
logger.I(
|
|
623
|
-
_("skipping not-installed package [green]{pkg}[/]").format(
|
|
624
|
-
pkg=pkg_name,
|
|
625
|
-
)
|
|
626
|
-
)
|
|
537
|
+
logger.I(f"skipping not-installed package [green]{pkg_name}[/]")
|
|
627
538
|
return 0
|
|
628
539
|
|
|
629
540
|
# There may be potentially user-generated data in the directory,
|
|
630
541
|
# let's be safe and fail the process.
|
|
631
542
|
logger.F(
|
|
632
|
-
|
|
633
|
-
"package [green]{pkg}[/] is not tracked as installed, but its directory [yellow]{install_root}[/] exists."
|
|
634
|
-
).format(pkg=pkg_name, install_root=install_root)
|
|
543
|
+
f"package [green]{pkg_name}[/] is not tracked as installed, but its directory [yellow]{install_root}[/] exists."
|
|
635
544
|
)
|
|
636
|
-
logger.I(
|
|
545
|
+
logger.I("Please remove it manually if you are sure it's safe to do so.")
|
|
637
546
|
logger.I(
|
|
638
|
-
|
|
639
|
-
"If you believe this is a bug, please file an issue at [yellow]https://github.com/ruyisdk/ruyi/issues[/]."
|
|
640
|
-
)
|
|
547
|
+
"If you believe this is a bug, please file an issue at [yellow]https://github.com/ruyisdk/ruyi/issues[/]."
|
|
641
548
|
)
|
|
642
549
|
return 1
|
|
643
550
|
|
|
644
|
-
logger.I(
|
|
551
|
+
logger.I(f"uninstalling package [green]{pkg_name}[/]")
|
|
645
552
|
if is_installed:
|
|
646
553
|
rgs.remove_installation(
|
|
647
554
|
pm.repo_id,
|
|
@@ -654,7 +561,7 @@ def _do_uninstall_binary_pkg(
|
|
|
654
561
|
if os.path.exists(install_root):
|
|
655
562
|
shutil.rmtree(install_root)
|
|
656
563
|
|
|
657
|
-
logger.I(
|
|
564
|
+
logger.I(f"package [green]{pkg_name}[/] uninstalled")
|
|
658
565
|
return 0
|
|
659
566
|
|
|
660
567
|
|
|
@@ -681,29 +588,21 @@ def _do_uninstall_blob_pkg(
|
|
|
681
588
|
# Check directory existence if the PM state says the package is not installed
|
|
682
589
|
if not is_installed:
|
|
683
590
|
if not os.path.exists(install_root):
|
|
684
|
-
logger.I(
|
|
685
|
-
_("skipping not-installed package [green]{pkg}[/]").format(
|
|
686
|
-
pkg=pkg_name,
|
|
687
|
-
)
|
|
688
|
-
)
|
|
591
|
+
logger.I(f"skipping not-installed package [green]{pkg_name}[/]")
|
|
689
592
|
return 0
|
|
690
593
|
|
|
691
594
|
# There may be potentially user-generated data in the directory,
|
|
692
595
|
# let's be safe and fail the process.
|
|
693
596
|
logger.F(
|
|
694
|
-
|
|
695
|
-
"package [green]{pkg}[/] is not tracked as installed, but its directory [yellow]{install_root}[/] exists."
|
|
696
|
-
).format(pkg=pkg_name, install_root=install_root)
|
|
597
|
+
f"package [green]{pkg_name}[/] is not tracked as installed, but its directory [yellow]{install_root}[/] exists."
|
|
697
598
|
)
|
|
698
|
-
logger.I(
|
|
599
|
+
logger.I("Please remove it manually if you are sure it's safe to do so.")
|
|
699
600
|
logger.I(
|
|
700
|
-
|
|
701
|
-
"If you believe this is a bug, please file an issue at [yellow]https://github.com/ruyisdk/ruyi/issues[/]."
|
|
702
|
-
)
|
|
601
|
+
"If you believe this is a bug, please file an issue at [yellow]https://github.com/ruyisdk/ruyi/issues[/]."
|
|
703
602
|
)
|
|
704
603
|
return 1
|
|
705
604
|
|
|
706
|
-
logger.I(
|
|
605
|
+
logger.I(f"uninstalling package [green]{pkg_name}[/]")
|
|
707
606
|
if is_installed:
|
|
708
607
|
rgs.remove_installation(
|
|
709
608
|
pm.repo_id,
|
|
@@ -716,5 +615,5 @@ def _do_uninstall_blob_pkg(
|
|
|
716
615
|
if os.path.exists(install_root):
|
|
717
616
|
shutil.rmtree(install_root)
|
|
718
617
|
|
|
719
|
-
logger.I(
|
|
618
|
+
logger.I(f"package [green]{pkg_name}[/] uninstalled")
|
|
720
619
|
return 0
|
ruyi/ruyipkg/install_cli.py
CHANGED
|
@@ -3,7 +3,6 @@ import pathlib
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
5
|
from ..cli.cmd import RootCommand
|
|
6
|
-
from ..i18n import _
|
|
7
6
|
from .cli_completion import package_completer_builder
|
|
8
7
|
from .host import get_native_host
|
|
9
8
|
|
|
@@ -15,7 +14,7 @@ if TYPE_CHECKING:
|
|
|
15
14
|
class ExtractCommand(
|
|
16
15
|
RootCommand,
|
|
17
16
|
cmd="extract",
|
|
18
|
-
help=
|
|
17
|
+
help="Fetch package(s) then extract to current directory",
|
|
19
18
|
):
|
|
20
19
|
@classmethod
|
|
21
20
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -23,7 +22,7 @@ class ExtractCommand(
|
|
|
23
22
|
"atom",
|
|
24
23
|
type=str,
|
|
25
24
|
nargs="+",
|
|
26
|
-
help=
|
|
25
|
+
help="Specifier (atom) of the package(s) to extract",
|
|
27
26
|
)
|
|
28
27
|
if gc.is_cli_autocomplete:
|
|
29
28
|
a.completer = package_completer_builder(gc)
|
|
@@ -34,26 +33,24 @@ class ExtractCommand(
|
|
|
34
33
|
type=str,
|
|
35
34
|
metavar="DESTDIR",
|
|
36
35
|
default=".",
|
|
37
|
-
help=
|
|
36
|
+
help="Destination directory to extract to (default: current directory)",
|
|
38
37
|
)
|
|
39
38
|
p.add_argument(
|
|
40
39
|
"--extract-without-subdir",
|
|
41
40
|
action="store_true",
|
|
42
|
-
help=
|
|
43
|
-
"Extract files directly into DESTDIR instead of package-named subdirectories"
|
|
44
|
-
),
|
|
41
|
+
help="Extract files directly into DESTDIR instead of package-named subdirectories",
|
|
45
42
|
)
|
|
46
43
|
p.add_argument(
|
|
47
44
|
"-f",
|
|
48
45
|
"--fetch-only",
|
|
49
46
|
action="store_true",
|
|
50
|
-
help=
|
|
47
|
+
help="Fetch distribution files only without installing",
|
|
51
48
|
)
|
|
52
49
|
p.add_argument(
|
|
53
50
|
"--host",
|
|
54
51
|
type=str,
|
|
55
52
|
default=get_native_host(),
|
|
56
|
-
help=
|
|
53
|
+
help="Override the host architecture (normally not needed)",
|
|
57
54
|
)
|
|
58
55
|
|
|
59
56
|
@classmethod
|
|
@@ -84,7 +81,7 @@ class InstallCommand(
|
|
|
84
81
|
RootCommand,
|
|
85
82
|
cmd="install",
|
|
86
83
|
aliases=["i"],
|
|
87
|
-
help=
|
|
84
|
+
help="Install package from configured repository",
|
|
88
85
|
):
|
|
89
86
|
@classmethod
|
|
90
87
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -92,7 +89,7 @@ class InstallCommand(
|
|
|
92
89
|
"atom",
|
|
93
90
|
type=str,
|
|
94
91
|
nargs="+",
|
|
95
|
-
help=
|
|
92
|
+
help="Specifier (atom) of the package to install",
|
|
96
93
|
)
|
|
97
94
|
if gc.is_cli_autocomplete:
|
|
98
95
|
a.completer = package_completer_builder(gc)
|
|
@@ -101,18 +98,18 @@ class InstallCommand(
|
|
|
101
98
|
"-f",
|
|
102
99
|
"--fetch-only",
|
|
103
100
|
action="store_true",
|
|
104
|
-
help=
|
|
101
|
+
help="Fetch distribution files only without installing",
|
|
105
102
|
)
|
|
106
103
|
p.add_argument(
|
|
107
104
|
"--host",
|
|
108
105
|
type=str,
|
|
109
106
|
default=get_native_host(),
|
|
110
|
-
help=
|
|
107
|
+
help="Override the host architecture (normally not needed)",
|
|
111
108
|
)
|
|
112
109
|
p.add_argument(
|
|
113
110
|
"--reinstall",
|
|
114
111
|
action="store_true",
|
|
115
|
-
help=
|
|
112
|
+
help="Force re-installation of already installed packages",
|
|
116
113
|
)
|
|
117
114
|
|
|
118
115
|
@classmethod
|
|
@@ -139,7 +136,7 @@ class UninstallCommand(
|
|
|
139
136
|
RootCommand,
|
|
140
137
|
cmd="uninstall",
|
|
141
138
|
aliases=["remove", "rm"],
|
|
142
|
-
help=
|
|
139
|
+
help="Uninstall installed packages",
|
|
143
140
|
):
|
|
144
141
|
@classmethod
|
|
145
142
|
def configure_args(cls, gc: "GlobalConfig", p: argparse.ArgumentParser) -> None:
|
|
@@ -147,20 +144,20 @@ class UninstallCommand(
|
|
|
147
144
|
"atom",
|
|
148
145
|
type=str,
|
|
149
146
|
nargs="+",
|
|
150
|
-
help=
|
|
147
|
+
help="Specifier (atom) of the package to uninstall",
|
|
151
148
|
)
|
|
152
149
|
p.add_argument(
|
|
153
150
|
"--host",
|
|
154
151
|
type=str,
|
|
155
152
|
default=get_native_host(),
|
|
156
|
-
help=
|
|
153
|
+
help="Override the host architecture (normally not needed)",
|
|
157
154
|
)
|
|
158
155
|
p.add_argument(
|
|
159
156
|
"-y",
|
|
160
157
|
"--yes",
|
|
161
158
|
action="store_true",
|
|
162
159
|
dest="assume_yes",
|
|
163
|
-
help=
|
|
160
|
+
help="Assume yes to all prompts",
|
|
164
161
|
)
|
|
165
162
|
|
|
166
163
|
@classmethod
|