ruyi 0.39.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/__init__.py +21 -0
- ruyi/__main__.py +98 -0
- ruyi/cli/__init__.py +5 -0
- ruyi/cli/builtin_commands.py +14 -0
- ruyi/cli/cmd.py +224 -0
- ruyi/cli/completer.py +50 -0
- ruyi/cli/completion.py +26 -0
- ruyi/cli/config_cli.py +153 -0
- ruyi/cli/main.py +111 -0
- ruyi/cli/self_cli.py +295 -0
- ruyi/cli/user_input.py +127 -0
- ruyi/cli/version_cli.py +45 -0
- ruyi/config/__init__.py +401 -0
- ruyi/config/editor.py +92 -0
- ruyi/config/errors.py +76 -0
- ruyi/config/news.py +39 -0
- ruyi/config/schema.py +197 -0
- ruyi/device/__init__.py +0 -0
- ruyi/device/provision.py +591 -0
- ruyi/device/provision_cli.py +40 -0
- ruyi/log/__init__.py +272 -0
- ruyi/mux/.gitignore +1 -0
- ruyi/mux/__init__.py +0 -0
- ruyi/mux/runtime.py +213 -0
- ruyi/mux/venv/__init__.py +12 -0
- ruyi/mux/venv/emulator_cfg.py +41 -0
- ruyi/mux/venv/maker.py +782 -0
- ruyi/mux/venv/venv_cli.py +92 -0
- ruyi/mux/venv_cfg.py +214 -0
- ruyi/pluginhost/__init__.py +0 -0
- ruyi/pluginhost/api.py +206 -0
- ruyi/pluginhost/ctx.py +222 -0
- ruyi/pluginhost/paths.py +135 -0
- ruyi/pluginhost/plugin_cli.py +37 -0
- ruyi/pluginhost/unsandboxed.py +246 -0
- ruyi/py.typed +0 -0
- ruyi/resource_bundle/__init__.py +20 -0
- ruyi/resource_bundle/__main__.py +55 -0
- ruyi/resource_bundle/data.py +26 -0
- ruyi/ruyipkg/__init__.py +0 -0
- ruyi/ruyipkg/admin_checksum.py +88 -0
- ruyi/ruyipkg/admin_cli.py +83 -0
- ruyi/ruyipkg/atom.py +184 -0
- ruyi/ruyipkg/augmented_pkg.py +212 -0
- ruyi/ruyipkg/canonical_dump.py +320 -0
- ruyi/ruyipkg/checksum.py +39 -0
- ruyi/ruyipkg/cli_completion.py +42 -0
- ruyi/ruyipkg/distfile.py +208 -0
- ruyi/ruyipkg/entity.py +387 -0
- ruyi/ruyipkg/entity_cli.py +123 -0
- ruyi/ruyipkg/entity_provider.py +273 -0
- ruyi/ruyipkg/fetch.py +271 -0
- ruyi/ruyipkg/host.py +55 -0
- ruyi/ruyipkg/install.py +554 -0
- ruyi/ruyipkg/install_cli.py +150 -0
- ruyi/ruyipkg/list.py +126 -0
- ruyi/ruyipkg/list_cli.py +79 -0
- ruyi/ruyipkg/list_filter.py +173 -0
- ruyi/ruyipkg/msg.py +99 -0
- ruyi/ruyipkg/news.py +123 -0
- ruyi/ruyipkg/news_cli.py +78 -0
- ruyi/ruyipkg/news_store.py +183 -0
- ruyi/ruyipkg/pkg_manifest.py +657 -0
- ruyi/ruyipkg/profile.py +208 -0
- ruyi/ruyipkg/profile_cli.py +33 -0
- ruyi/ruyipkg/protocols.py +55 -0
- ruyi/ruyipkg/repo.py +763 -0
- ruyi/ruyipkg/state.py +345 -0
- ruyi/ruyipkg/unpack.py +369 -0
- ruyi/ruyipkg/unpack_method.py +91 -0
- ruyi/ruyipkg/update_cli.py +54 -0
- ruyi/telemetry/__init__.py +0 -0
- ruyi/telemetry/aggregate.py +72 -0
- ruyi/telemetry/event.py +41 -0
- ruyi/telemetry/node_info.py +192 -0
- ruyi/telemetry/provider.py +411 -0
- ruyi/telemetry/scope.py +43 -0
- ruyi/telemetry/store.py +238 -0
- ruyi/telemetry/telemetry_cli.py +127 -0
- ruyi/utils/__init__.py +0 -0
- ruyi/utils/ar.py +74 -0
- ruyi/utils/ci.py +63 -0
- ruyi/utils/frontmatter.py +38 -0
- ruyi/utils/git.py +169 -0
- ruyi/utils/global_mode.py +204 -0
- ruyi/utils/l10n.py +83 -0
- ruyi/utils/markdown.py +73 -0
- ruyi/utils/nuitka.py +33 -0
- ruyi/utils/porcelain.py +51 -0
- ruyi/utils/prereqs.py +77 -0
- ruyi/utils/ssl_patch.py +170 -0
- ruyi/utils/templating.py +34 -0
- ruyi/utils/toml.py +115 -0
- ruyi/utils/url.py +7 -0
- ruyi/utils/xdg_basedir.py +80 -0
- ruyi/version.py +67 -0
- ruyi-0.39.0.dist-info/LICENSE-Apache.txt +201 -0
- ruyi-0.39.0.dist-info/METADATA +403 -0
- ruyi-0.39.0.dist-info/RECORD +101 -0
- ruyi-0.39.0.dist-info/WHEEL +4 -0
- ruyi-0.39.0.dist-info/entry_points.txt +3 -0
ruyi/ruyipkg/profile.py
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
from os import PathLike
|
|
2
|
+
from typing import Any, Iterable, TypeGuard, cast
|
|
3
|
+
|
|
4
|
+
from ..pluginhost.ctx import PluginHostContext, SupportsEvalFunction
|
|
5
|
+
from .pkg_manifest import EmulatorFlavor
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class InvalidProfilePluginError(RuntimeError):
|
|
9
|
+
def __init__(self, s: str) -> None:
|
|
10
|
+
super().__init__(f"invalid arch profile plugin: {s}")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def validate_list_str(x: object) -> TypeGuard[list[str]]:
|
|
14
|
+
if not isinstance(x, list):
|
|
15
|
+
return False
|
|
16
|
+
x = cast(list[object], x)
|
|
17
|
+
return all(isinstance(y, str) for y in x)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def validate_list_str_or_none(x: object) -> TypeGuard[list[str] | None]:
|
|
21
|
+
return True if x is None else validate_list_str(x)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def validate_dict_str_str(x: object) -> TypeGuard[dict[str, str]]:
|
|
25
|
+
if not isinstance(x, dict):
|
|
26
|
+
return False
|
|
27
|
+
for k, v in cast(dict[object, object], x).items():
|
|
28
|
+
if not isinstance(k, str) or not isinstance(v, str):
|
|
29
|
+
return False
|
|
30
|
+
return True
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class PluginProfileProvider:
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
phctx: PluginHostContext[Any, SupportsEvalFunction],
|
|
37
|
+
plugin_id: str,
|
|
38
|
+
) -> None:
|
|
39
|
+
self._phctx = phctx
|
|
40
|
+
self._plugin_id = plugin_id
|
|
41
|
+
self._ev = phctx.make_evaluator()
|
|
42
|
+
|
|
43
|
+
def _must_get(self, name: str) -> object:
|
|
44
|
+
if v := self._phctx.get_from_plugin(self._plugin_id, name):
|
|
45
|
+
return v
|
|
46
|
+
raise InvalidProfilePluginError(
|
|
47
|
+
f"'{name}' not found in plugin '{self._plugin_id}'"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
def list_all_profile_ids(self) -> list[str]:
|
|
51
|
+
fn = self._must_get("list_all_profile_ids_v1")
|
|
52
|
+
ret = self._ev.eval_function(fn)
|
|
53
|
+
if not validate_list_str(ret):
|
|
54
|
+
raise InvalidProfilePluginError(
|
|
55
|
+
"list_all_profile_ids must return list[str]"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
return ret
|
|
59
|
+
|
|
60
|
+
def list_needed_quirks(self, profile_id: str) -> list[str] | None:
|
|
61
|
+
# For backward compatibility, try "list_needed_quirks_v1" first, then
|
|
62
|
+
# fall back to "list_needed_flavors_v1" if the former is not available.
|
|
63
|
+
fn = self._phctx.get_from_plugin(self._plugin_id, "list_needed_quirks_v1")
|
|
64
|
+
if fn is None:
|
|
65
|
+
fn = self._must_get("list_needed_flavors_v1")
|
|
66
|
+
|
|
67
|
+
ret = self._ev.eval_function(fn, profile_id)
|
|
68
|
+
if not validate_list_str_or_none(ret):
|
|
69
|
+
raise InvalidProfilePluginError(
|
|
70
|
+
"list_needed_quirks_v1 must return list[str] | None"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
return ret
|
|
74
|
+
|
|
75
|
+
def get_common_flags(self, profile_id: str, toolchain_quirks: list[str]) -> str:
|
|
76
|
+
result = self._maybe_get_common_flags_v2(profile_id, toolchain_quirks)
|
|
77
|
+
if result is not None:
|
|
78
|
+
return result
|
|
79
|
+
return self._get_common_flags_v1(profile_id)
|
|
80
|
+
|
|
81
|
+
def _get_common_flags_v1(self, profile_id: str) -> str:
|
|
82
|
+
fn = self._must_get("get_common_flags_v1")
|
|
83
|
+
ret = self._ev.eval_function(fn, profile_id)
|
|
84
|
+
if not isinstance(ret, str):
|
|
85
|
+
raise InvalidProfilePluginError("get_common_flags_v1 must return str")
|
|
86
|
+
|
|
87
|
+
return ret
|
|
88
|
+
|
|
89
|
+
def _maybe_get_common_flags_v2(
|
|
90
|
+
self,
|
|
91
|
+
profile_id: str,
|
|
92
|
+
toolchain_flavors: list[str],
|
|
93
|
+
) -> str | None:
|
|
94
|
+
fn = self._phctx.get_from_plugin(self._plugin_id, "get_common_flags_v2")
|
|
95
|
+
if fn is None:
|
|
96
|
+
return None
|
|
97
|
+
|
|
98
|
+
ret = self._ev.eval_function(fn, profile_id, toolchain_flavors)
|
|
99
|
+
if not isinstance(ret, str):
|
|
100
|
+
raise InvalidProfilePluginError("get_common_flags_v2 must return str")
|
|
101
|
+
|
|
102
|
+
return ret
|
|
103
|
+
|
|
104
|
+
def get_needed_emulator_pkg_flavors(
|
|
105
|
+
self,
|
|
106
|
+
profile_id: str,
|
|
107
|
+
flavor: EmulatorFlavor,
|
|
108
|
+
) -> Iterable[str]:
|
|
109
|
+
fn = self._must_get("get_needed_emulator_pkg_flavors_v1")
|
|
110
|
+
ret = self._ev.eval_function(
|
|
111
|
+
fn,
|
|
112
|
+
profile_id,
|
|
113
|
+
flavor,
|
|
114
|
+
)
|
|
115
|
+
if not validate_list_str(ret):
|
|
116
|
+
raise InvalidProfilePluginError(
|
|
117
|
+
"get_needed_emulator_pkg_flavors_v1 must return list[str]"
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
return ret
|
|
121
|
+
|
|
122
|
+
def check_emulator_flavor(
|
|
123
|
+
self,
|
|
124
|
+
profile_id: str,
|
|
125
|
+
flavor: EmulatorFlavor,
|
|
126
|
+
emulator_pkg_flavors: list[str] | None,
|
|
127
|
+
) -> bool:
|
|
128
|
+
fn = self._must_get("check_emulator_flavor_v1")
|
|
129
|
+
ret = self._ev.eval_function(
|
|
130
|
+
fn,
|
|
131
|
+
profile_id,
|
|
132
|
+
flavor,
|
|
133
|
+
emulator_pkg_flavors,
|
|
134
|
+
)
|
|
135
|
+
if not isinstance(ret, bool):
|
|
136
|
+
raise InvalidProfilePluginError("check_emulator_flavor_v1 must return bool")
|
|
137
|
+
|
|
138
|
+
return ret
|
|
139
|
+
|
|
140
|
+
def get_env_config_for_emu_flavor(
|
|
141
|
+
self,
|
|
142
|
+
profile_id: str,
|
|
143
|
+
flavor: EmulatorFlavor,
|
|
144
|
+
sysroot: PathLike[Any] | None,
|
|
145
|
+
) -> dict[str, str] | None:
|
|
146
|
+
fn = self._must_get("get_env_config_for_emu_flavor_v1")
|
|
147
|
+
ret = self._ev.eval_function(
|
|
148
|
+
fn,
|
|
149
|
+
profile_id,
|
|
150
|
+
flavor,
|
|
151
|
+
str(sysroot) if sysroot is not None else None,
|
|
152
|
+
)
|
|
153
|
+
if not validate_dict_str_str(ret):
|
|
154
|
+
raise InvalidProfilePluginError(
|
|
155
|
+
"get_env_config_for_emu_flavor_v1 must return dict[str, str]"
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
return ret
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class ProfileProxy:
|
|
162
|
+
def __init__(
|
|
163
|
+
self,
|
|
164
|
+
provider: PluginProfileProvider,
|
|
165
|
+
arch: str,
|
|
166
|
+
profile_id: str,
|
|
167
|
+
) -> None:
|
|
168
|
+
self._provider = provider
|
|
169
|
+
self._arch = arch
|
|
170
|
+
self._id = profile_id
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
def arch(self) -> str:
|
|
174
|
+
return self._arch
|
|
175
|
+
|
|
176
|
+
@property
|
|
177
|
+
def id(self) -> str:
|
|
178
|
+
return self._id
|
|
179
|
+
|
|
180
|
+
@property
|
|
181
|
+
def need_quirks(self) -> set[str]:
|
|
182
|
+
r = self._provider.list_needed_quirks(self._id)
|
|
183
|
+
return set(r) if r else set()
|
|
184
|
+
|
|
185
|
+
def get_common_flags(self, toolchain_flavors: list[str]) -> str:
|
|
186
|
+
return self._provider.get_common_flags(self._id, toolchain_flavors)
|
|
187
|
+
|
|
188
|
+
def get_needed_emulator_pkg_flavors(
|
|
189
|
+
self,
|
|
190
|
+
flavor: EmulatorFlavor,
|
|
191
|
+
) -> set[str]:
|
|
192
|
+
return set(self._provider.get_needed_emulator_pkg_flavors(self._id, flavor))
|
|
193
|
+
|
|
194
|
+
def check_emulator_flavor(
|
|
195
|
+
self,
|
|
196
|
+
flavor: EmulatorFlavor,
|
|
197
|
+
emulator_pkg_flavors: list[str] | None,
|
|
198
|
+
) -> bool:
|
|
199
|
+
return self._provider.check_emulator_flavor(
|
|
200
|
+
self._id, flavor, emulator_pkg_flavors
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def get_env_config_for_emu_flavor(
|
|
204
|
+
self,
|
|
205
|
+
flavor: EmulatorFlavor,
|
|
206
|
+
sysroot: PathLike[Any] | None,
|
|
207
|
+
) -> dict[str, str] | None:
|
|
208
|
+
return self._provider.get_env_config_for_emu_flavor(self._id, flavor, sysroot)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
from .list_cli import ListCommand
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from ..cli.completion import ArgumentParser
|
|
8
|
+
from ..config import GlobalConfig
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ListProfilesCommand(
|
|
12
|
+
ListCommand,
|
|
13
|
+
cmd="profiles",
|
|
14
|
+
help="List all available profiles",
|
|
15
|
+
):
|
|
16
|
+
@classmethod
|
|
17
|
+
def configure_args(cls, gc: "GlobalConfig", p: "ArgumentParser") -> None:
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def main(cls, cfg: "GlobalConfig", args: argparse.Namespace) -> int:
|
|
22
|
+
logger = cfg.logger
|
|
23
|
+
mr = cfg.repo
|
|
24
|
+
|
|
25
|
+
for arch in mr.get_supported_arches():
|
|
26
|
+
for p in mr.iter_profiles_for_arch(arch):
|
|
27
|
+
if not p.need_quirks:
|
|
28
|
+
logger.stdout(p.id)
|
|
29
|
+
continue
|
|
30
|
+
|
|
31
|
+
logger.stdout(f"{p.id} (needs quirks: {p.need_quirks})")
|
|
32
|
+
|
|
33
|
+
return 0
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from typing import Iterable, Protocol
|
|
2
|
+
|
|
3
|
+
from .pkg_manifest import BoundPackageManifest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ProvidesPackageManifests(Protocol):
|
|
7
|
+
"""A protocol that defines methods for providing package manifests."""
|
|
8
|
+
|
|
9
|
+
def get_pkg(
|
|
10
|
+
self,
|
|
11
|
+
name: str,
|
|
12
|
+
category: str,
|
|
13
|
+
ver: str,
|
|
14
|
+
) -> BoundPackageManifest | None:
|
|
15
|
+
"""Returns the package manifest by exact match, or None if not found."""
|
|
16
|
+
...
|
|
17
|
+
|
|
18
|
+
def iter_pkg_manifests(self) -> Iterable[BoundPackageManifest]:
|
|
19
|
+
"""Iterates over all package manifests provided by this store."""
|
|
20
|
+
...
|
|
21
|
+
|
|
22
|
+
def iter_pkgs(
|
|
23
|
+
self,
|
|
24
|
+
) -> Iterable[tuple[str, str, dict[str, BoundPackageManifest]]]:
|
|
25
|
+
"""Iterates over all package manifests provided by this store, returning
|
|
26
|
+
``(category, package_name, pkg_manifests_by_versions)``."""
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
def iter_pkg_vers(
|
|
30
|
+
self,
|
|
31
|
+
name: str,
|
|
32
|
+
category: str | None = None,
|
|
33
|
+
) -> Iterable[BoundPackageManifest]:
|
|
34
|
+
"""Iterates over all versions of a certain package provided by this store,
|
|
35
|
+
specified by name and optionally category."""
|
|
36
|
+
...
|
|
37
|
+
|
|
38
|
+
def get_pkg_latest_ver(
|
|
39
|
+
self,
|
|
40
|
+
name: str,
|
|
41
|
+
category: str | None = None,
|
|
42
|
+
include_prerelease_vers: bool = False,
|
|
43
|
+
) -> BoundPackageManifest:
|
|
44
|
+
"""Returns the latest version of a package provided by this store,
|
|
45
|
+
specified by name and optionally category.
|
|
46
|
+
|
|
47
|
+
If ``include_prerelease_vers`` is True, it will also consider prerelease
|
|
48
|
+
versions. Raises KeyError if no such package exists."""
|
|
49
|
+
...
|
|
50
|
+
|
|
51
|
+
# To be removed later along with slug support
|
|
52
|
+
def get_pkg_by_slug(self, slug: str) -> BoundPackageManifest | None:
|
|
53
|
+
"""Returns the package with the specified slug from this store, or None
|
|
54
|
+
if not found."""
|
|
55
|
+
...
|