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/config/schema.py
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import sys
|
|
3
|
+
from typing import Final, Sequence
|
|
4
|
+
|
|
5
|
+
from .errors import (
|
|
6
|
+
InvalidConfigKeyError,
|
|
7
|
+
InvalidConfigSectionError,
|
|
8
|
+
InvalidConfigValueError,
|
|
9
|
+
InvalidConfigValueTypeError,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def parse_config_key(key: str | Sequence[str]) -> list[str]:
|
|
14
|
+
if isinstance(key, str):
|
|
15
|
+
return key.split(".")
|
|
16
|
+
return list(key)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
SECTION_INSTALLATION: Final = "installation"
|
|
20
|
+
KEY_INSTALLATION_EXTERNALLY_MANAGED: Final = "externally_managed"
|
|
21
|
+
|
|
22
|
+
SECTION_PACKAGES: Final = "packages"
|
|
23
|
+
KEY_PACKAGES_PRERELEASES: Final = "prereleases"
|
|
24
|
+
|
|
25
|
+
SECTION_REPO: Final = "repo"
|
|
26
|
+
KEY_REPO_BRANCH: Final = "branch"
|
|
27
|
+
KEY_REPO_LOCAL: Final = "local"
|
|
28
|
+
KEY_REPO_REMOTE: Final = "remote"
|
|
29
|
+
|
|
30
|
+
SECTION_TELEMETRY: Final = "telemetry"
|
|
31
|
+
KEY_TELEMETRY_MODE: Final = "mode"
|
|
32
|
+
KEY_TELEMETRY_PM_TELEMETRY_URL: Final = "pm_telemetry_url"
|
|
33
|
+
KEY_TELEMETRY_UPLOAD_CONSENT: Final = "upload_consent"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def validate_section(section: str) -> None:
|
|
37
|
+
if section not in (
|
|
38
|
+
SECTION_INSTALLATION,
|
|
39
|
+
SECTION_PACKAGES,
|
|
40
|
+
SECTION_REPO,
|
|
41
|
+
SECTION_TELEMETRY,
|
|
42
|
+
):
|
|
43
|
+
raise InvalidConfigSectionError(section)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def get_expected_type_for_config_key(key: str | Sequence[str]) -> type:
|
|
47
|
+
parsed_key = parse_config_key(key)
|
|
48
|
+
if len(parsed_key) != 2:
|
|
49
|
+
# for now there's no nested config option
|
|
50
|
+
raise InvalidConfigKeyError(key)
|
|
51
|
+
|
|
52
|
+
section, sel = parsed_key
|
|
53
|
+
if section == SECTION_INSTALLATION:
|
|
54
|
+
return _get_expected_type_for_section_installation(sel)
|
|
55
|
+
elif section == SECTION_PACKAGES:
|
|
56
|
+
return _get_expected_type_for_section_packages(sel)
|
|
57
|
+
elif section == SECTION_REPO:
|
|
58
|
+
return _get_expected_type_for_section_repo(sel)
|
|
59
|
+
elif section == SECTION_TELEMETRY:
|
|
60
|
+
return _get_expected_type_for_section_telemetry(sel)
|
|
61
|
+
else:
|
|
62
|
+
raise InvalidConfigKeyError(key)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _get_expected_type_for_section_installation(sel: str) -> type:
|
|
66
|
+
if sel == KEY_INSTALLATION_EXTERNALLY_MANAGED:
|
|
67
|
+
return bool
|
|
68
|
+
else:
|
|
69
|
+
raise InvalidConfigKeyError(sel)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _get_expected_type_for_section_packages(sel: str) -> type:
|
|
73
|
+
if sel == KEY_PACKAGES_PRERELEASES:
|
|
74
|
+
return bool
|
|
75
|
+
else:
|
|
76
|
+
raise InvalidConfigKeyError(sel)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _get_expected_type_for_section_repo(sel: str) -> type:
|
|
80
|
+
if sel == KEY_REPO_BRANCH:
|
|
81
|
+
return str
|
|
82
|
+
elif sel == KEY_REPO_LOCAL:
|
|
83
|
+
return str
|
|
84
|
+
elif sel == KEY_REPO_REMOTE:
|
|
85
|
+
return str
|
|
86
|
+
else:
|
|
87
|
+
raise InvalidConfigKeyError(sel)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _get_expected_type_for_section_telemetry(sel: str) -> type:
|
|
91
|
+
if sel == KEY_TELEMETRY_MODE:
|
|
92
|
+
return str
|
|
93
|
+
elif sel == KEY_TELEMETRY_PM_TELEMETRY_URL:
|
|
94
|
+
return str
|
|
95
|
+
elif sel == KEY_TELEMETRY_UPLOAD_CONSENT:
|
|
96
|
+
return datetime.datetime
|
|
97
|
+
else:
|
|
98
|
+
raise InvalidConfigKeyError(sel)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def ensure_valid_config_kv(
|
|
102
|
+
key: str | Sequence[str],
|
|
103
|
+
check_val: bool = False,
|
|
104
|
+
val: object | None = None,
|
|
105
|
+
) -> None:
|
|
106
|
+
parsed_key = parse_config_key(key)
|
|
107
|
+
if len(parsed_key) != 2:
|
|
108
|
+
# for now there's no nested config option
|
|
109
|
+
raise InvalidConfigKeyError(key)
|
|
110
|
+
|
|
111
|
+
expected_type = get_expected_type_for_config_key(parsed_key)
|
|
112
|
+
# validity of config key is already checked by get_expected_type_for_config_key
|
|
113
|
+
_ensure_value_type(key, check_val, val, expected_type)
|
|
114
|
+
|
|
115
|
+
if not check_val:
|
|
116
|
+
return
|
|
117
|
+
|
|
118
|
+
section, sel = parsed_key
|
|
119
|
+
if section == SECTION_TELEMETRY:
|
|
120
|
+
return _extra_validate_section_telemetry_kv(key, sel, val)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _ensure_value_type(
|
|
124
|
+
key: str | Sequence[str],
|
|
125
|
+
check_val: bool,
|
|
126
|
+
val: object | None,
|
|
127
|
+
expected: type,
|
|
128
|
+
) -> None:
|
|
129
|
+
if check_val and not isinstance(val, expected):
|
|
130
|
+
raise InvalidConfigValueTypeError(key, val, expected)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def _extra_validate_section_telemetry_kv(
|
|
134
|
+
key: str | Sequence[str],
|
|
135
|
+
sel: str,
|
|
136
|
+
val: object | None,
|
|
137
|
+
) -> None:
|
|
138
|
+
if sel == KEY_TELEMETRY_MODE:
|
|
139
|
+
# value type is already ensured earlier
|
|
140
|
+
if val not in ("local", "off", "on"):
|
|
141
|
+
raise InvalidConfigValueError(key, val)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def encode_value(v: object) -> str:
|
|
145
|
+
"""Encodes the given config value into a string representation suitable for
|
|
146
|
+
display or storage into TOML config files."""
|
|
147
|
+
|
|
148
|
+
if isinstance(v, bool):
|
|
149
|
+
return "true" if v else "false"
|
|
150
|
+
elif isinstance(v, int):
|
|
151
|
+
return str(v)
|
|
152
|
+
elif isinstance(v, str):
|
|
153
|
+
return v
|
|
154
|
+
elif isinstance(v, datetime.datetime):
|
|
155
|
+
if v.tzinfo is None:
|
|
156
|
+
raise ValueError("only timezone-aware datetimes are supported for safety")
|
|
157
|
+
s = v.isoformat()
|
|
158
|
+
if s.endswith("+00:00"):
|
|
159
|
+
# use the shorter 'Z' suffix for UTC
|
|
160
|
+
return f"{s[:-6]}Z"
|
|
161
|
+
return s
|
|
162
|
+
else:
|
|
163
|
+
raise NotImplementedError(f"invalid type for config value: {type(v)}")
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def decode_value(
|
|
167
|
+
key: str | Sequence[str] | type,
|
|
168
|
+
val: str,
|
|
169
|
+
) -> object:
|
|
170
|
+
"""Decodes the given string representation of a config value into a Python
|
|
171
|
+
value, directed by type information implied by the config key."""
|
|
172
|
+
|
|
173
|
+
if isinstance(key, type):
|
|
174
|
+
expected_type = key
|
|
175
|
+
else:
|
|
176
|
+
expected_type = get_expected_type_for_config_key(key)
|
|
177
|
+
|
|
178
|
+
if expected_type is bool:
|
|
179
|
+
if val in ("true", "yes", "1"):
|
|
180
|
+
return True
|
|
181
|
+
elif val in ("false", "no", "0"):
|
|
182
|
+
return False
|
|
183
|
+
else:
|
|
184
|
+
raise InvalidConfigValueError(key, val)
|
|
185
|
+
elif expected_type is int:
|
|
186
|
+
return int(val, 10)
|
|
187
|
+
elif expected_type is str:
|
|
188
|
+
return val
|
|
189
|
+
elif expected_type is datetime.datetime:
|
|
190
|
+
if sys.version_info < (3, 11) and val.endswith("Z"):
|
|
191
|
+
# datetime.fromisoformat() did not support the 'Z' suffix until
|
|
192
|
+
# Python 3.11
|
|
193
|
+
val = f"{val[:-1]}+00:00"
|
|
194
|
+
v = datetime.datetime.fromisoformat(val)
|
|
195
|
+
return v.astimezone() if v.tzinfo is None else v
|
|
196
|
+
else:
|
|
197
|
+
raise NotImplementedError(f"invalid type for config value: {expected_type}")
|
ruyi/device/__init__.py
ADDED
|
File without changes
|