ruyi 0.44.0b20251219__py3-none-any.whl → 0.45.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ruyi/__main__.py +16 -4
- ruyi/cli/cmd.py +6 -5
- ruyi/cli/config_cli.py +14 -11
- ruyi/cli/main.py +14 -4
- ruyi/cli/oobe.py +7 -3
- ruyi/cli/self_cli.py +48 -34
- ruyi/cli/user_input.py +42 -12
- ruyi/cli/version_cli.py +11 -5
- ruyi/config/__init__.py +26 -2
- ruyi/config/errors.py +19 -7
- ruyi/device/provision.py +116 -55
- ruyi/device/provision_cli.py +6 -3
- ruyi/i18n/__init__.py +129 -0
- ruyi/log/__init__.py +6 -5
- ruyi/mux/runtime.py +19 -6
- ruyi/mux/venv/maker.py +93 -35
- ruyi/mux/venv/venv_cli.py +13 -10
- ruyi/pluginhost/plugin_cli.py +4 -3
- ruyi/resource_bundle/__init__.py +22 -8
- ruyi/resource_bundle/__main__.py +6 -5
- ruyi/resource_bundle/data.py +13 -9
- ruyi/ruyipkg/admin_checksum.py +4 -1
- ruyi/ruyipkg/admin_cli.py +9 -6
- ruyi/ruyipkg/augmented_pkg.py +15 -14
- ruyi/ruyipkg/checksum.py +8 -2
- ruyi/ruyipkg/distfile.py +33 -9
- ruyi/ruyipkg/entity.py +12 -2
- ruyi/ruyipkg/entity_cli.py +20 -12
- ruyi/ruyipkg/entity_provider.py +11 -2
- ruyi/ruyipkg/fetcher.py +38 -9
- ruyi/ruyipkg/install.py +143 -42
- ruyi/ruyipkg/install_cli.py +18 -15
- ruyi/ruyipkg/list.py +27 -20
- ruyi/ruyipkg/list_cli.py +12 -7
- ruyi/ruyipkg/news.py +23 -11
- ruyi/ruyipkg/news_cli.py +10 -7
- ruyi/ruyipkg/profile_cli.py +8 -2
- ruyi/ruyipkg/repo.py +22 -8
- ruyi/ruyipkg/unpack.py +42 -8
- ruyi/ruyipkg/unpack_method.py +5 -1
- ruyi/ruyipkg/update_cli.py +8 -3
- ruyi/telemetry/provider.py +74 -29
- ruyi/telemetry/telemetry_cli.py +9 -8
- ruyi/utils/git.py +18 -11
- ruyi/utils/prereqs.py +10 -5
- ruyi/utils/ssl_patch.py +2 -1
- ruyi/version.py +9 -3
- {ruyi-0.44.0b20251219.dist-info → ruyi-0.45.0.dist-info}/METADATA +2 -1
- ruyi-0.45.0.dist-info/RECORD +103 -0
- {ruyi-0.44.0b20251219.dist-info → ruyi-0.45.0.dist-info}/WHEEL +1 -1
- ruyi-0.44.0b20251219.dist-info/RECORD +0 -102
- {ruyi-0.44.0b20251219.dist-info → ruyi-0.45.0.dist-info}/entry_points.txt +0 -0
- {ruyi-0.44.0b20251219.dist-info → ruyi-0.45.0.dist-info}/licenses/LICENSE-Apache.txt +0 -0
ruyi/ruyipkg/list.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from itertools import chain
|
|
2
2
|
|
|
3
3
|
from ..config import GlobalConfig
|
|
4
|
+
from ..i18n import _
|
|
4
5
|
from ..log import RuyiLogger
|
|
5
6
|
from ..utils.porcelain import PorcelainOutput
|
|
6
7
|
from .augmented_pkg import AugmentedPkg
|
|
@@ -22,9 +23,11 @@ def do_list(
|
|
|
22
23
|
# all packages either
|
|
23
24
|
return 1
|
|
24
25
|
|
|
25
|
-
logger.F("no filter specified for list operation")
|
|
26
|
+
logger.F(_("no filter specified for list operation"))
|
|
26
27
|
logger.I(
|
|
27
|
-
|
|
28
|
+
_(
|
|
29
|
+
"for the old behavior of listing all packages, try [yellow]ruyi list --name-contains ''[/]"
|
|
30
|
+
)
|
|
28
31
|
)
|
|
29
32
|
return 1
|
|
30
33
|
|
|
@@ -49,7 +52,7 @@ def _do_list_non_verbose(
|
|
|
49
52
|
logger: RuyiLogger,
|
|
50
53
|
augmented_pkgs: list[AugmentedPkg],
|
|
51
54
|
) -> int:
|
|
52
|
-
logger.stdout("List of available packages:\n")
|
|
55
|
+
logger.stdout(_("List of available packages:\n"))
|
|
53
56
|
|
|
54
57
|
for ap in augmented_pkgs:
|
|
55
58
|
logger.stdout(f"* [bold green]{ap.category}/{ap.name}[/]")
|
|
@@ -82,45 +85,49 @@ def _print_pkg_detail(
|
|
|
82
85
|
logger.stdout(f"[bold]## [green]{pm.category}/{pm.name}[/] [blue]{pm.ver}[/][/]\n")
|
|
83
86
|
|
|
84
87
|
if pm.slug is not None:
|
|
85
|
-
logger.stdout(
|
|
88
|
+
logger.stdout(_("* Slug: [yellow]{slug}[/]").format(slug=pm.slug))
|
|
86
89
|
else:
|
|
87
|
-
logger.stdout("* Slug: (none)")
|
|
88
|
-
logger.stdout(
|
|
89
|
-
logger.stdout(
|
|
90
|
+
logger.stdout(_("* Slug: (none)"))
|
|
91
|
+
logger.stdout(_("* Package kind: {kind}").format(kind=sorted(pm.kind)))
|
|
92
|
+
logger.stdout(_("* Vendor: {vendor}").format(vendor=pm.vendor_name))
|
|
90
93
|
if upstream_ver := pm.upstream_version:
|
|
91
|
-
logger.stdout(
|
|
94
|
+
logger.stdout(
|
|
95
|
+
_("* Upstream version number: {version}").format(version=upstream_ver)
|
|
96
|
+
)
|
|
92
97
|
else:
|
|
93
|
-
logger.stdout("* Upstream version number: (undeclared)")
|
|
98
|
+
logger.stdout(_("* Upstream version number: (undeclared)"))
|
|
94
99
|
logger.stdout("")
|
|
95
100
|
|
|
96
101
|
sv = pm.service_level
|
|
97
102
|
if sv.has_known_issues:
|
|
98
|
-
logger.stdout("\nPackage has known issue(s):\n")
|
|
103
|
+
logger.stdout(_("\nPackage has known issue(s):\n"))
|
|
99
104
|
for x in sv.render_known_issues(pm.repo.messages, lang_code):
|
|
100
105
|
logger.stdout(x, end="\n\n")
|
|
101
106
|
|
|
102
107
|
df = pm.distfiles
|
|
103
|
-
logger.stdout(
|
|
108
|
+
logger.stdout(_("Package declares {count} distfile(s):\n").format(count=len(df)))
|
|
104
109
|
for dd in df.values():
|
|
105
110
|
logger.stdout(f"* [green]{dd.name}[/]")
|
|
106
|
-
logger.stdout(
|
|
111
|
+
logger.stdout(_(" - Size: [yellow]{size}[/] bytes").format(size=dd.size))
|
|
107
112
|
for kind, csum in dd.checksums.items():
|
|
108
113
|
logger.stdout(f" - {kind.upper()}: [yellow]{csum}[/]")
|
|
109
114
|
|
|
110
115
|
if bm := pm.binary_metadata:
|
|
111
|
-
logger.stdout("\n### Binary artifacts\n")
|
|
116
|
+
logger.stdout(_("\n### Binary artifacts\n"))
|
|
112
117
|
for host, data in bm.data.items():
|
|
113
|
-
logger.stdout(
|
|
114
|
-
logger.stdout(
|
|
118
|
+
logger.stdout(_("* Host [green]{host}[/]:").format(host=host))
|
|
119
|
+
logger.stdout(
|
|
120
|
+
_(" - Distfiles: {distfiles}").format(distfiles=data["distfiles"])
|
|
121
|
+
)
|
|
115
122
|
if cmds := data.get("commands"):
|
|
116
|
-
logger.stdout(" - Available command(s):")
|
|
123
|
+
logger.stdout(_(" - Available command(s):"))
|
|
117
124
|
for k in sorted(cmds.keys()):
|
|
118
125
|
logger.stdout(f" - [green]{k}[/]")
|
|
119
126
|
|
|
120
127
|
if tm := pm.toolchain_metadata:
|
|
121
|
-
logger.stdout("\n### Toolchain metadata\n")
|
|
122
|
-
logger.stdout(
|
|
123
|
-
logger.stdout(
|
|
124
|
-
logger.stdout("* Components:")
|
|
128
|
+
logger.stdout(_("\n### Toolchain metadata\n"))
|
|
129
|
+
logger.stdout(_("* Target: [bold green]{target}[/]").format(target=tm.target))
|
|
130
|
+
logger.stdout(_("* Quirks: {quirks}").format(quirks=tm.quirks))
|
|
131
|
+
logger.stdout(_("* Components:"))
|
|
125
132
|
for tc in tm.components:
|
|
126
133
|
logger.stdout(f' - {tc["name"]} [bold green]{tc["version"]}[/]')
|
ruyi/ruyipkg/list_cli.py
CHANGED
|
@@ -2,6 +2,7 @@ import argparse
|
|
|
2
2
|
from typing import TYPE_CHECKING
|
|
3
3
|
|
|
4
4
|
from ..cli.cmd import RootCommand
|
|
5
|
+
from ..i18n import _
|
|
5
6
|
from .list_filter import ListFilter, ListFilterAction
|
|
6
7
|
|
|
7
8
|
if TYPE_CHECKING:
|
|
@@ -15,7 +16,7 @@ class ListCommand(
|
|
|
15
16
|
has_subcommands=True,
|
|
16
17
|
is_subcommand_required=False,
|
|
17
18
|
has_main=True,
|
|
18
|
-
help="List available packages in configured repository",
|
|
19
|
+
help=_("List available packages in configured repository"),
|
|
19
20
|
):
|
|
20
21
|
@classmethod
|
|
21
22
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -23,7 +24,7 @@ class ListCommand(
|
|
|
23
24
|
"--verbose",
|
|
24
25
|
"-v",
|
|
25
26
|
action="store_true",
|
|
26
|
-
help="Also show details for every package",
|
|
27
|
+
help=_("Also show details for every package"),
|
|
27
28
|
)
|
|
28
29
|
|
|
29
30
|
# filter expressions
|
|
@@ -32,28 +33,32 @@ class ListCommand(
|
|
|
32
33
|
action=ListFilterAction,
|
|
33
34
|
nargs=1,
|
|
34
35
|
dest="filters",
|
|
35
|
-
help=
|
|
36
|
+
help=_(
|
|
37
|
+
"Match packages that are installed (y/true/1) or not installed (n/false/0)"
|
|
38
|
+
),
|
|
36
39
|
)
|
|
37
40
|
p.add_argument(
|
|
38
41
|
"--category-contains",
|
|
39
42
|
action=ListFilterAction,
|
|
40
43
|
nargs=1,
|
|
41
44
|
dest="filters",
|
|
42
|
-
help=
|
|
45
|
+
help=_(
|
|
46
|
+
"Match packages from categories whose names contain the given string"
|
|
47
|
+
),
|
|
43
48
|
)
|
|
44
49
|
p.add_argument(
|
|
45
50
|
"--category-is",
|
|
46
51
|
action=ListFilterAction,
|
|
47
52
|
nargs=1,
|
|
48
53
|
dest="filters",
|
|
49
|
-
help="Match packages from the given category",
|
|
54
|
+
help=_("Match packages from the given category"),
|
|
50
55
|
)
|
|
51
56
|
p.add_argument(
|
|
52
57
|
"--name-contains",
|
|
53
58
|
action=ListFilterAction,
|
|
54
59
|
nargs=1,
|
|
55
60
|
dest="filters",
|
|
56
|
-
help="Match packages whose names contain the given string",
|
|
61
|
+
help=_("Match packages whose names contain the given string"),
|
|
57
62
|
)
|
|
58
63
|
|
|
59
64
|
if gc.is_experimental:
|
|
@@ -62,7 +67,7 @@ class ListCommand(
|
|
|
62
67
|
action=ListFilterAction,
|
|
63
68
|
nargs=1,
|
|
64
69
|
dest="filters",
|
|
65
|
-
help="Match packages related to the given entity",
|
|
70
|
+
help=_("Match packages related to the given entity"),
|
|
66
71
|
)
|
|
67
72
|
|
|
68
73
|
@classmethod
|
ruyi/ruyipkg/news.py
CHANGED
|
@@ -2,6 +2,7 @@ from rich import box
|
|
|
2
2
|
from rich.table import Table
|
|
3
3
|
|
|
4
4
|
from ..config import GlobalConfig
|
|
5
|
+
from ..i18n import _
|
|
5
6
|
from ..log import RuyiLogger
|
|
6
7
|
from ..utils.markdown import RuyiStyledMarkdown
|
|
7
8
|
from ..utils.porcelain import PorcelainOutput
|
|
@@ -14,9 +15,12 @@ def print_news_item_titles(
|
|
|
14
15
|
lang: str,
|
|
15
16
|
) -> None:
|
|
16
17
|
tbl = Table(box=box.SIMPLE, show_edge=False)
|
|
17
|
-
|
|
18
|
-
tbl.add_column("
|
|
19
|
-
|
|
18
|
+
# i18n NOTE: used as news item table title
|
|
19
|
+
tbl.add_column(_("No."))
|
|
20
|
+
# i18n NOTE: used as news item table title
|
|
21
|
+
tbl.add_column(_("ID"))
|
|
22
|
+
# i18n NOTE: used as news item table title
|
|
23
|
+
tbl.add_column(_("Title"))
|
|
20
24
|
|
|
21
25
|
for ni in newsitems:
|
|
22
26
|
unread = not ni.is_read
|
|
@@ -40,14 +44,20 @@ def maybe_notify_unread_news(
|
|
|
40
44
|
|
|
41
45
|
unread_newsitems = gc.repo.news_store().list(True)
|
|
42
46
|
if unread_newsitems:
|
|
43
|
-
gc.logger.stdout(
|
|
47
|
+
gc.logger.stdout(
|
|
48
|
+
_("\nThere are {count} new news item(s):\n").format(
|
|
49
|
+
count=len(unread_newsitems),
|
|
50
|
+
)
|
|
51
|
+
)
|
|
44
52
|
print_news_item_titles(gc.logger, unread_newsitems, gc.lang_code)
|
|
45
|
-
gc.logger.stdout("\nYou can read them with [yellow]ruyi news read[/].")
|
|
53
|
+
gc.logger.stdout(_("\nYou can read them with [yellow]ruyi news read[/]."))
|
|
46
54
|
return
|
|
47
55
|
|
|
48
56
|
if prompt_no_unread:
|
|
49
57
|
gc.logger.stdout(
|
|
50
|
-
|
|
58
|
+
_(
|
|
59
|
+
"\nAll news items have been read. To see a list of them, run [yellow]ruyi news list[/].\n"
|
|
60
|
+
)
|
|
51
61
|
)
|
|
52
62
|
|
|
53
63
|
|
|
@@ -65,9 +75,9 @@ def do_news_list(
|
|
|
65
75
|
po.emit(ni.to_porcelain())
|
|
66
76
|
return 0
|
|
67
77
|
|
|
68
|
-
logger.stdout("[bold green]News items:[/]\n")
|
|
78
|
+
logger.stdout(_("[bold green]News items:[/]\n"))
|
|
69
79
|
if not newsitems:
|
|
70
|
-
logger.stdout(" (no unread item)" if only_unread else " (no item)")
|
|
80
|
+
logger.stdout(_(" (no unread item)") if only_unread else _(" (no item)"))
|
|
71
81
|
return 0
|
|
72
82
|
|
|
73
83
|
print_news_item_titles(logger, newsitems, cfg.lang_code)
|
|
@@ -98,7 +108,7 @@ def do_news_read(
|
|
|
98
108
|
for ni in items:
|
|
99
109
|
print_news(logger, ni.get_content_for_lang(cfg.lang_code))
|
|
100
110
|
else:
|
|
101
|
-
logger.stdout("No news to display.")
|
|
111
|
+
logger.stdout(_("No news to display."))
|
|
102
112
|
|
|
103
113
|
# record read statuses
|
|
104
114
|
store.mark_as_read(*(ni.id for ni in items))
|
|
@@ -123,13 +133,15 @@ def filter_news_items_by_specs(
|
|
|
123
133
|
try:
|
|
124
134
|
ni_ord = int(i)
|
|
125
135
|
if ni_ord not in ni_by_ord:
|
|
126
|
-
logger.F(
|
|
136
|
+
logger.F(
|
|
137
|
+
_("there is no news item with ordinal {ord}").format(ord=ni_ord)
|
|
138
|
+
)
|
|
127
139
|
return None
|
|
128
140
|
items.append(ni_by_ord[ni_ord])
|
|
129
141
|
except ValueError:
|
|
130
142
|
# treat i as id
|
|
131
143
|
if i not in ni_by_id:
|
|
132
|
-
logger.F(
|
|
144
|
+
logger.F(_("there is no news item with ID '{id}'").format(id=i))
|
|
133
145
|
return None
|
|
134
146
|
items.append(ni_by_id[i])
|
|
135
147
|
|
ruyi/ruyipkg/news_cli.py
CHANGED
|
@@ -2,6 +2,7 @@ import argparse
|
|
|
2
2
|
from typing import TYPE_CHECKING
|
|
3
3
|
|
|
4
4
|
from ..cli.cmd import RootCommand
|
|
5
|
+
from ..i18n import _
|
|
5
6
|
|
|
6
7
|
if TYPE_CHECKING:
|
|
7
8
|
from ..cli.completion import ArgumentParser
|
|
@@ -14,7 +15,7 @@ class NewsCommand(
|
|
|
14
15
|
has_subcommands=True,
|
|
15
16
|
is_subcommand_required=False,
|
|
16
17
|
has_main=True,
|
|
17
|
-
help="List and read news items from configured repository",
|
|
18
|
+
help=_("List and read news items from configured repository"),
|
|
18
19
|
):
|
|
19
20
|
_my_parser: "ArgumentParser | None" = None
|
|
20
21
|
|
|
@@ -36,14 +37,14 @@ class NewsCommand(
|
|
|
36
37
|
class NewsListCommand(
|
|
37
38
|
NewsCommand,
|
|
38
39
|
cmd="list",
|
|
39
|
-
help="List news items",
|
|
40
|
+
help=_("List news items"),
|
|
40
41
|
):
|
|
41
42
|
@classmethod
|
|
42
43
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
43
44
|
p.add_argument(
|
|
44
45
|
"--new",
|
|
45
46
|
action="store_true",
|
|
46
|
-
help="List unread news items only",
|
|
47
|
+
help=_("List unread news items only"),
|
|
47
48
|
)
|
|
48
49
|
|
|
49
50
|
@classmethod
|
|
@@ -60,8 +61,10 @@ class NewsListCommand(
|
|
|
60
61
|
class NewsReadCommand(
|
|
61
62
|
NewsCommand,
|
|
62
63
|
cmd="read",
|
|
63
|
-
help="Read news items",
|
|
64
|
-
description=
|
|
64
|
+
help=_("Read news items"),
|
|
65
|
+
description=_(
|
|
66
|
+
"Outputs news item(s) to the console and mark as already read. Defaults to reading all unread items if no item is specified."
|
|
67
|
+
),
|
|
65
68
|
):
|
|
66
69
|
@classmethod
|
|
67
70
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -69,13 +72,13 @@ class NewsReadCommand(
|
|
|
69
72
|
"--quiet",
|
|
70
73
|
"-q",
|
|
71
74
|
action="store_true",
|
|
72
|
-
help="Do not output anything and only mark as read",
|
|
75
|
+
help=_("Do not output anything and only mark as read"),
|
|
73
76
|
)
|
|
74
77
|
p.add_argument(
|
|
75
78
|
"item",
|
|
76
79
|
type=str,
|
|
77
80
|
nargs="*",
|
|
78
|
-
help="Ordinal or ID of the news item(s) to read",
|
|
81
|
+
help=_("Ordinal or ID of the news item(s) to read"),
|
|
79
82
|
)
|
|
80
83
|
|
|
81
84
|
@classmethod
|
ruyi/ruyipkg/profile_cli.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
from typing import TYPE_CHECKING
|
|
3
3
|
|
|
4
|
+
from ..i18n import _
|
|
4
5
|
from .list_cli import ListCommand
|
|
5
6
|
|
|
6
7
|
if TYPE_CHECKING:
|
|
@@ -11,7 +12,7 @@ if TYPE_CHECKING:
|
|
|
11
12
|
class ListProfilesCommand(
|
|
12
13
|
ListCommand,
|
|
13
14
|
cmd="profiles",
|
|
14
|
-
help="List all available profiles",
|
|
15
|
+
help=_("List all available profiles"),
|
|
15
16
|
):
|
|
16
17
|
@classmethod
|
|
17
18
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -28,6 +29,11 @@ class ListProfilesCommand(
|
|
|
28
29
|
logger.stdout(p.id)
|
|
29
30
|
continue
|
|
30
31
|
|
|
31
|
-
logger.stdout(
|
|
32
|
+
logger.stdout(
|
|
33
|
+
_("{profile_id} (needs quirks: {need_quirks})").format(
|
|
34
|
+
profile_id=p.id,
|
|
35
|
+
need_quirks=p.need_quirks,
|
|
36
|
+
)
|
|
37
|
+
)
|
|
32
38
|
|
|
33
39
|
return 0
|
ruyi/ruyipkg/repo.py
CHANGED
|
@@ -19,6 +19,7 @@ from urllib import parse
|
|
|
19
19
|
from pygit2 import clone_repository
|
|
20
20
|
from pygit2.repository import Repository
|
|
21
21
|
|
|
22
|
+
from ..i18n import _
|
|
22
23
|
from ..log import RuyiLogger
|
|
23
24
|
from ..pluginhost.ctx import PluginHostContext
|
|
24
25
|
from ..telemetry.scope import TelemetryScopeConfig
|
|
@@ -167,7 +168,9 @@ class RepoConfig:
|
|
|
167
168
|
return [url]
|
|
168
169
|
case _:
|
|
169
170
|
# deny others
|
|
170
|
-
logger.W(
|
|
171
|
+
logger.W(
|
|
172
|
+
_("unrecognized dist URL scheme: {scheme}").format(scheme=u.scheme)
|
|
173
|
+
)
|
|
171
174
|
return []
|
|
172
175
|
|
|
173
176
|
def get_mirror_urls_for_file(self, mirror_id: str, path: str) -> list[str]:
|
|
@@ -286,9 +289,13 @@ class MetadataRepo(ProvidesPackageManifests):
|
|
|
286
289
|
return self.repo
|
|
287
290
|
|
|
288
291
|
self.logger.I(
|
|
289
|
-
|
|
292
|
+
_("the package repository does not exist at [yellow]{root}[/]").format(
|
|
293
|
+
root=self.root
|
|
294
|
+
)
|
|
295
|
+
)
|
|
296
|
+
self.logger.I(
|
|
297
|
+
_("cloning from [cyan link={remote}]{remote}[/]").format(remote=self.remote)
|
|
290
298
|
)
|
|
291
|
-
self.logger.I(f"cloning from [cyan link={self.remote}]{self.remote}[/]")
|
|
292
299
|
|
|
293
300
|
with RemoteGitProgressIndicator() as pr:
|
|
294
301
|
repo = clone_repository(
|
|
@@ -310,7 +317,7 @@ class MetadataRepo(ProvidesPackageManifests):
|
|
|
310
317
|
return self.repo
|
|
311
318
|
|
|
312
319
|
def sync(self) -> None:
|
|
313
|
-
self._gc.logger.I("updating the package repository")
|
|
320
|
+
self._gc.logger.I(_("updating the package repository"))
|
|
314
321
|
|
|
315
322
|
repo = self.ensure_git_repo()
|
|
316
323
|
|
|
@@ -327,7 +334,7 @@ class MetadataRepo(ProvidesPackageManifests):
|
|
|
327
334
|
allow_auto_management=allow_auto_management,
|
|
328
335
|
)
|
|
329
336
|
|
|
330
|
-
self._gc.logger.I("package repository is updated")
|
|
337
|
+
self._gc.logger.I(_("package repository is updated"))
|
|
331
338
|
|
|
332
339
|
@property
|
|
333
340
|
def global_config(self) -> "GlobalConfig":
|
|
@@ -605,7 +612,9 @@ class MetadataRepo(ProvidesPackageManifests):
|
|
|
605
612
|
contents = fp.read()
|
|
606
613
|
except UnicodeDecodeError:
|
|
607
614
|
self.logger.W(
|
|
608
|
-
|
|
615
|
+
_("UnicodeDecodeError: {path}").format(
|
|
616
|
+
path=os.path.join(news_dir, f)
|
|
617
|
+
)
|
|
609
618
|
)
|
|
610
619
|
continue
|
|
611
620
|
cache.add(f, contents) # may fail but failures are harmless
|
|
@@ -638,9 +647,14 @@ class MetadataRepo(ProvidesPackageManifests):
|
|
|
638
647
|
ret = self.eval_plugin_fn(plugin_entrypoint, args)
|
|
639
648
|
if not isinstance(ret, int):
|
|
640
649
|
self.logger.W(
|
|
641
|
-
|
|
650
|
+
_(
|
|
651
|
+
"unexpected return type of cmd plugin '{plugin_id}': {type} is not int."
|
|
652
|
+
).format(
|
|
653
|
+
plugin_id=plugin_id,
|
|
654
|
+
type=type(ret),
|
|
655
|
+
)
|
|
642
656
|
)
|
|
643
|
-
self.logger.I("forcing return code to 1; the plugin should be fixed")
|
|
657
|
+
self.logger.I(_("forcing return code to 1; the plugin should be fixed"))
|
|
644
658
|
ret = 1
|
|
645
659
|
return ret
|
|
646
660
|
|
ruyi/ruyipkg/unpack.py
CHANGED
|
@@ -4,6 +4,7 @@ import shutil
|
|
|
4
4
|
import subprocess
|
|
5
5
|
from typing import Any, BinaryIO, NoReturn, Protocol
|
|
6
6
|
|
|
7
|
+
from ..i18n import _
|
|
7
8
|
from ..log import RuyiLogger
|
|
8
9
|
from ..utils import ar, prereqs
|
|
9
10
|
from .unpack_method import (
|
|
@@ -192,7 +193,12 @@ def _do_unpack_tar(
|
|
|
192
193
|
retcode = p.wait()
|
|
193
194
|
|
|
194
195
|
if retcode != 0:
|
|
195
|
-
raise RuntimeError(
|
|
196
|
+
raise RuntimeError(
|
|
197
|
+
_("untar failed: command {cmd} returned {retcode}").format(
|
|
198
|
+
cmd=" ".join(argv),
|
|
199
|
+
retcode=retcode,
|
|
200
|
+
)
|
|
201
|
+
)
|
|
196
202
|
|
|
197
203
|
|
|
198
204
|
def _do_unpack_zip(
|
|
@@ -206,7 +212,12 @@ def _do_unpack_zip(
|
|
|
206
212
|
logger.D(f"about to call unzip: argv={argv}")
|
|
207
213
|
retcode = subprocess.call(argv, cwd=dest)
|
|
208
214
|
if retcode != 0:
|
|
209
|
-
raise RuntimeError(
|
|
215
|
+
raise RuntimeError(
|
|
216
|
+
_("unzip failed: command {cmd} returned {retcode}").format(
|
|
217
|
+
cmd=" ".join(argv),
|
|
218
|
+
retcode=retcode,
|
|
219
|
+
)
|
|
220
|
+
)
|
|
210
221
|
|
|
211
222
|
|
|
212
223
|
def _do_unpack_bare_gz(
|
|
@@ -226,7 +237,10 @@ def _do_unpack_bare_gz(
|
|
|
226
237
|
retcode = subprocess.call(argv, stdout=out)
|
|
227
238
|
if retcode != 0:
|
|
228
239
|
raise RuntimeError(
|
|
229
|
-
|
|
240
|
+
_("gunzip failed: command {cmd} returned {retcode}").format(
|
|
241
|
+
cmd=" ".join(argv),
|
|
242
|
+
retcode=retcode,
|
|
243
|
+
)
|
|
230
244
|
)
|
|
231
245
|
|
|
232
246
|
|
|
@@ -247,7 +261,10 @@ def _do_unpack_bare_bzip2(
|
|
|
247
261
|
retcode = subprocess.call(argv, stdout=out)
|
|
248
262
|
if retcode != 0:
|
|
249
263
|
raise RuntimeError(
|
|
250
|
-
|
|
264
|
+
_("bzip2 failed: command {cmd} returned {retcode}").format(
|
|
265
|
+
cmd=" ".join(argv),
|
|
266
|
+
retcode=retcode,
|
|
267
|
+
)
|
|
251
268
|
)
|
|
252
269
|
|
|
253
270
|
|
|
@@ -263,7 +280,12 @@ def _do_unpack_bare_lz4(
|
|
|
263
280
|
logger.D(f"about to call lz4: argv={argv}")
|
|
264
281
|
retcode = subprocess.call(argv, cwd=destdir)
|
|
265
282
|
if retcode != 0:
|
|
266
|
-
raise RuntimeError(
|
|
283
|
+
raise RuntimeError(
|
|
284
|
+
_("lz4 failed: command {cmd} returned {retcode}").format(
|
|
285
|
+
cmd=" ".join(argv),
|
|
286
|
+
retcode=retcode,
|
|
287
|
+
)
|
|
288
|
+
)
|
|
267
289
|
|
|
268
290
|
|
|
269
291
|
def _do_unpack_bare_xz(
|
|
@@ -283,7 +305,10 @@ def _do_unpack_bare_xz(
|
|
|
283
305
|
retcode = subprocess.call(argv, stdout=out)
|
|
284
306
|
if retcode != 0:
|
|
285
307
|
raise RuntimeError(
|
|
286
|
-
|
|
308
|
+
_("xz failed: command {cmd} returned {retcode}").format(
|
|
309
|
+
cmd=" ".join(argv),
|
|
310
|
+
retcode=retcode,
|
|
311
|
+
)
|
|
287
312
|
)
|
|
288
313
|
|
|
289
314
|
|
|
@@ -299,7 +324,12 @@ def _do_unpack_bare_zstd(
|
|
|
299
324
|
logger.D(f"about to call zstd: argv={argv}")
|
|
300
325
|
retcode = subprocess.call(argv, cwd=destdir)
|
|
301
326
|
if retcode != 0:
|
|
302
|
-
raise RuntimeError(
|
|
327
|
+
raise RuntimeError(
|
|
328
|
+
_("zstd failed: command {cmd} returned {retcode}").format(
|
|
329
|
+
cmd=" ".join(argv),
|
|
330
|
+
retcode=retcode,
|
|
331
|
+
)
|
|
332
|
+
)
|
|
303
333
|
|
|
304
334
|
|
|
305
335
|
def _do_unpack_deb(
|
|
@@ -321,7 +351,11 @@ def _do_unpack_deb(
|
|
|
321
351
|
a.open(f),
|
|
322
352
|
)
|
|
323
353
|
|
|
324
|
-
raise RuntimeError(
|
|
354
|
+
raise RuntimeError(
|
|
355
|
+
_("file '{filename}' does not appear to be a deb").format(
|
|
356
|
+
filename=filename,
|
|
357
|
+
)
|
|
358
|
+
)
|
|
325
359
|
|
|
326
360
|
|
|
327
361
|
def _get_unpack_cmds_for_method(m: UnpackMethod) -> list[str]:
|
ruyi/ruyipkg/unpack_method.py
CHANGED
|
@@ -3,6 +3,8 @@ import re
|
|
|
3
3
|
import sys
|
|
4
4
|
from typing import Final
|
|
5
5
|
|
|
6
|
+
from ..i18n import _
|
|
7
|
+
|
|
6
8
|
RE_TARBALL: Final = re.compile(r"\.tar(?:\.gz|\.bz2|\.lz4|\.xz|\.zst)?$")
|
|
7
9
|
|
|
8
10
|
|
|
@@ -60,7 +62,9 @@ class UnrecognizedPackFormatError(Exception):
|
|
|
60
62
|
self.filename = filename
|
|
61
63
|
|
|
62
64
|
def __str__(self) -> str:
|
|
63
|
-
return
|
|
65
|
+
return _("don't know how to unpack file {filename}").format(
|
|
66
|
+
filename=self.filename,
|
|
67
|
+
)
|
|
64
68
|
|
|
65
69
|
|
|
66
70
|
def determine_unpack_method(
|
ruyi/ruyipkg/update_cli.py
CHANGED
|
@@ -2,6 +2,7 @@ import argparse
|
|
|
2
2
|
from typing import TYPE_CHECKING
|
|
3
3
|
|
|
4
4
|
from ..cli.cmd import RootCommand
|
|
5
|
+
from ..i18n import _
|
|
5
6
|
|
|
6
7
|
if TYPE_CHECKING:
|
|
7
8
|
from ..cli.completion import ArgumentParser
|
|
@@ -11,7 +12,7 @@ if TYPE_CHECKING:
|
|
|
11
12
|
class UpdateCommand(
|
|
12
13
|
RootCommand,
|
|
13
14
|
cmd="update",
|
|
14
|
-
help="Update RuyiSDK repo and packages",
|
|
15
|
+
help=_("Update RuyiSDK repo and packages"),
|
|
15
16
|
):
|
|
16
17
|
@classmethod
|
|
17
18
|
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
@@ -32,16 +33,20 @@ class UpdateCommand(
|
|
|
32
33
|
|
|
33
34
|
if upgradable:
|
|
34
35
|
logger.stdout(
|
|
35
|
-
|
|
36
|
+
_(
|
|
37
|
+
"\nNewer versions are available for some of your installed packages:\n"
|
|
38
|
+
)
|
|
36
39
|
)
|
|
37
40
|
for pm, new_ver in upgradable:
|
|
38
41
|
logger.stdout(
|
|
39
42
|
f" - [bold]{pm.category}/{pm.name}[/]: [yellow]{pm.ver}[/] -> [green]{new_ver}[/]"
|
|
40
43
|
)
|
|
41
44
|
logger.stdout(
|
|
42
|
-
|
|
45
|
+
_(
|
|
46
|
+
"""
|
|
43
47
|
Re-run [yellow]ruyi install[/] to upgrade, and don't forget to re-create any affected
|
|
44
48
|
virtual environments."""
|
|
49
|
+
)
|
|
45
50
|
)
|
|
46
51
|
|
|
47
52
|
news.maybe_notify_unread_news(cfg, False)
|