ErisPulse 2.3.3.dev0__py3-none-any.whl → 2.3.4.dev0__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.
- ErisPulse/Core/Bases/__init__.pyi +14 -0
- ErisPulse/Core/Bases/adapter.py +13 -1
- ErisPulse/Core/Bases/adapter.pyi +140 -0
- ErisPulse/Core/Bases/module.pyi +52 -0
- ErisPulse/Core/Event/__init__.pyi +26 -0
- ErisPulse/Core/Event/base.pyi +62 -0
- ErisPulse/Core/Event/command.pyi +113 -0
- ErisPulse/Core/Event/exceptions.pyi +43 -0
- ErisPulse/Core/Event/message.pyi +93 -0
- ErisPulse/Core/Event/meta.pyi +92 -0
- ErisPulse/Core/Event/notice.pyi +108 -0
- ErisPulse/Core/Event/request.pyi +76 -0
- ErisPulse/Core/Event/wrapper.py +2 -3
- ErisPulse/Core/Event/wrapper.pyi +403 -0
- ErisPulse/Core/__init__.py +16 -13
- ErisPulse/Core/__init__.pyi +16 -0
- ErisPulse/Core/_self_config.pyi +72 -0
- ErisPulse/Core/adapter.pyi +229 -0
- ErisPulse/Core/config.pyi +70 -0
- ErisPulse/Core/exceptions.pyi +60 -0
- ErisPulse/Core/lifecycle.py +6 -1
- ErisPulse/Core/lifecycle.pyi +92 -0
- ErisPulse/Core/logger.pyi +168 -0
- ErisPulse/Core/module.pyi +178 -0
- ErisPulse/Core/router.pyi +120 -0
- ErisPulse/Core/storage.pyi +273 -0
- ErisPulse/__init__.py +10 -9
- ErisPulse/__init__.pyi +309 -0
- ErisPulse/__main__.pyi +24 -0
- ErisPulse/sdk_protocol.py +143 -0
- ErisPulse/sdk_protocol.pyi +97 -0
- ErisPulse/utils/__init__.py +1 -1
- ErisPulse/utils/__init__.pyi +16 -0
- ErisPulse/utils/cli/__init__.py +11 -0
- ErisPulse/utils/cli/__init__.pyi +13 -0
- ErisPulse/utils/cli/__main__.py +225 -0
- ErisPulse/utils/cli/__main__.pyi +81 -0
- ErisPulse/utils/cli/base.py +52 -0
- ErisPulse/utils/cli/base.pyi +50 -0
- ErisPulse/utils/cli/commands/__init__.py +6 -0
- ErisPulse/utils/cli/commands/__init__.pyi +12 -0
- ErisPulse/utils/cli/commands/init.py +400 -0
- ErisPulse/utils/cli/commands/init.pyi +82 -0
- ErisPulse/utils/cli/commands/install.py +307 -0
- ErisPulse/utils/cli/commands/install.pyi +70 -0
- ErisPulse/utils/cli/commands/list.py +165 -0
- ErisPulse/utils/cli/commands/list.pyi +56 -0
- ErisPulse/utils/cli/commands/list_remote.py +128 -0
- ErisPulse/utils/cli/commands/list_remote.pyi +47 -0
- ErisPulse/utils/cli/commands/run.py +112 -0
- ErisPulse/utils/cli/commands/run.pyi +48 -0
- ErisPulse/utils/cli/commands/self_update.py +237 -0
- ErisPulse/utils/cli/commands/self_update.pyi +59 -0
- ErisPulse/utils/cli/commands/uninstall.py +37 -0
- ErisPulse/utils/cli/commands/uninstall.pyi +37 -0
- ErisPulse/utils/cli/commands/upgrade.py +62 -0
- ErisPulse/utils/cli/commands/upgrade.pyi +38 -0
- ErisPulse/utils/cli/registry.py +112 -0
- ErisPulse/utils/cli/registry.pyi +99 -0
- ErisPulse/utils/console.pyi +20 -0
- ErisPulse/utils/package_manager.pyi +224 -0
- ErisPulse/utils/reload_handler.pyi +64 -0
- {erispulse-2.3.3.dev0.dist-info → erispulse-2.3.4.dev0.dist-info}/METADATA +6 -20
- erispulse-2.3.4.dev0.dist-info/RECORD +89 -0
- {erispulse-2.3.3.dev0.dist-info → erispulse-2.3.4.dev0.dist-info}/licenses/LICENSE +3 -3
- ErisPulse/Core/ux.py +0 -635
- ErisPulse/utils/cli.py +0 -1097
- erispulse-2.3.3.dev0.dist-info/RECORD +0 -35
- {erispulse-2.3.3.dev0.dist-info → erispulse-2.3.4.dev0.dist-info}/WHEEL +0 -0
- {erispulse-2.3.3.dev0.dist-info → erispulse-2.3.4.dev0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""
|
|
2
|
+
List-Remote 命令实现
|
|
3
|
+
|
|
4
|
+
列出远程可用的组件
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
from argparse import ArgumentParser
|
|
9
|
+
|
|
10
|
+
from rich.table import Table
|
|
11
|
+
from rich.box import SIMPLE
|
|
12
|
+
|
|
13
|
+
from ...package_manager import PackageManager
|
|
14
|
+
from ...console import console
|
|
15
|
+
from ..base import Command
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ListRemoteCommand(Command):
|
|
19
|
+
"""远程列表命令"""
|
|
20
|
+
|
|
21
|
+
name = "list-remote"
|
|
22
|
+
description = "列出远程可用的组件"
|
|
23
|
+
|
|
24
|
+
def __init__(self):
|
|
25
|
+
"""初始化命令"""
|
|
26
|
+
self.package_manager = PackageManager()
|
|
27
|
+
|
|
28
|
+
def add_arguments(self, parser: ArgumentParser):
|
|
29
|
+
"""添加命令参数"""
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
'--type', '-t',
|
|
32
|
+
choices=['modules', 'adapters', 'cli', 'all'],
|
|
33
|
+
default='all',
|
|
34
|
+
help='列出类型 (默认: all)'
|
|
35
|
+
)
|
|
36
|
+
parser.add_argument(
|
|
37
|
+
'--refresh', '-r',
|
|
38
|
+
action='store_true',
|
|
39
|
+
help='强制刷新远程包列表'
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
def execute(self, args):
|
|
43
|
+
"""执行命令"""
|
|
44
|
+
pkg_type = args.type
|
|
45
|
+
force_refresh = args.refresh
|
|
46
|
+
|
|
47
|
+
if pkg_type == "all":
|
|
48
|
+
self._print_remote_packages("modules", force_refresh)
|
|
49
|
+
self._print_remote_packages("adapters", force_refresh)
|
|
50
|
+
self._print_remote_packages("cli", force_refresh)
|
|
51
|
+
else:
|
|
52
|
+
self._print_remote_packages(pkg_type, force_refresh)
|
|
53
|
+
|
|
54
|
+
def _print_remote_packages(self, pkg_type: str, force_refresh: bool = False):
|
|
55
|
+
"""
|
|
56
|
+
打印远程包信息
|
|
57
|
+
|
|
58
|
+
:param pkg_type: 包类型 (modules/adapters/cli)
|
|
59
|
+
:param force_refresh: 是否强制刷新缓存
|
|
60
|
+
"""
|
|
61
|
+
remote_packages = asyncio.run(
|
|
62
|
+
self.package_manager.get_remote_packages(force_refresh=force_refresh)
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
if pkg_type == "modules" and remote_packages["modules"]:
|
|
66
|
+
table = Table(
|
|
67
|
+
title="远程模块",
|
|
68
|
+
box=SIMPLE,
|
|
69
|
+
header_style="module"
|
|
70
|
+
)
|
|
71
|
+
table.add_column("模块名", style="module")
|
|
72
|
+
table.add_column("包名")
|
|
73
|
+
table.add_column("最新版本")
|
|
74
|
+
table.add_column("描述")
|
|
75
|
+
|
|
76
|
+
for name, info in remote_packages["modules"].items():
|
|
77
|
+
table.add_row(
|
|
78
|
+
name,
|
|
79
|
+
info["package"],
|
|
80
|
+
info["version"],
|
|
81
|
+
info.get("description", "")
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
console.print(table)
|
|
85
|
+
|
|
86
|
+
elif pkg_type == "adapters" and remote_packages["adapters"]:
|
|
87
|
+
table = Table(
|
|
88
|
+
title="远程适配器",
|
|
89
|
+
box=SIMPLE,
|
|
90
|
+
header_style="adapter"
|
|
91
|
+
)
|
|
92
|
+
table.add_column("适配器名", style="adapter")
|
|
93
|
+
table.add_column("包名")
|
|
94
|
+
table.add_column("最新版本")
|
|
95
|
+
table.add_column("描述")
|
|
96
|
+
|
|
97
|
+
for name, info in remote_packages["adapters"].items():
|
|
98
|
+
table.add_row(
|
|
99
|
+
name,
|
|
100
|
+
info["package"],
|
|
101
|
+
info["version"],
|
|
102
|
+
info.get("description", "")
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
console.print(table)
|
|
106
|
+
|
|
107
|
+
elif pkg_type == "cli" and remote_packages.get("cli_extensions"):
|
|
108
|
+
table = Table(
|
|
109
|
+
title="远程CLI扩展",
|
|
110
|
+
box=SIMPLE,
|
|
111
|
+
header_style="cli"
|
|
112
|
+
)
|
|
113
|
+
table.add_column("命令名", style="cli")
|
|
114
|
+
table.add_column("包名")
|
|
115
|
+
table.add_column("最新版本")
|
|
116
|
+
table.add_column("描述")
|
|
117
|
+
|
|
118
|
+
for name, info in remote_packages["cli_extensions"].items():
|
|
119
|
+
table.add_row(
|
|
120
|
+
name,
|
|
121
|
+
info["package"],
|
|
122
|
+
info["version"],
|
|
123
|
+
info.get("description", "")
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
console.print(table)
|
|
127
|
+
elif not remote_packages.get(pkg_type.replace("cli", "cli_extensions"), {}):
|
|
128
|
+
console.print(f"[dim]远程没有找到 {pkg_type}[/]")
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# type: ignore
|
|
2
|
+
#
|
|
3
|
+
# Auto-generated type stub for list_remote.py
|
|
4
|
+
# DO NOT EDIT MANUALLY - Generated by generate-type-stubs.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
List-Remote 命令实现
|
|
9
|
+
|
|
10
|
+
列出远程可用的组件
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import asyncio
|
|
14
|
+
from argparse import ArgumentParser
|
|
15
|
+
from rich.table import Table
|
|
16
|
+
from rich.box import SIMPLE
|
|
17
|
+
from ...package_manager import PackageManager
|
|
18
|
+
from ...console import console
|
|
19
|
+
from ..base import Command
|
|
20
|
+
|
|
21
|
+
class ListRemoteCommand(Command):
|
|
22
|
+
"""
|
|
23
|
+
远程列表命令
|
|
24
|
+
"""
|
|
25
|
+
def __init__(self: None) -> ...:
|
|
26
|
+
"""
|
|
27
|
+
初始化命令
|
|
28
|
+
"""
|
|
29
|
+
...
|
|
30
|
+
def add_arguments(self: object, parser: ArgumentParser) -> ...:
|
|
31
|
+
"""
|
|
32
|
+
添加命令参数
|
|
33
|
+
"""
|
|
34
|
+
...
|
|
35
|
+
def execute(self: object, args: ...) -> ...:
|
|
36
|
+
"""
|
|
37
|
+
执行命令
|
|
38
|
+
"""
|
|
39
|
+
...
|
|
40
|
+
def _print_remote_packages(self: object, pkg_type: str, force_refresh: bool = ...) -> ...:
|
|
41
|
+
"""
|
|
42
|
+
打印远程包信息
|
|
43
|
+
|
|
44
|
+
:param pkg_type: 包类型 (modules/adapters/cli)
|
|
45
|
+
:param force_refresh: 是否强制刷新缓存
|
|
46
|
+
"""
|
|
47
|
+
...
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Run 命令实现
|
|
3
|
+
|
|
4
|
+
运行主程序
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import time
|
|
9
|
+
from argparse import ArgumentParser
|
|
10
|
+
from watchdog.observers import Observer
|
|
11
|
+
from rich.panel import Panel
|
|
12
|
+
|
|
13
|
+
from ...console import console
|
|
14
|
+
from ...reload_handler import ReloadHandler
|
|
15
|
+
from ..base import Command
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class RunCommand(Command):
|
|
19
|
+
"""运行命令"""
|
|
20
|
+
|
|
21
|
+
name = "run"
|
|
22
|
+
description = "运行主程序"
|
|
23
|
+
|
|
24
|
+
def add_arguments(self, parser: ArgumentParser):
|
|
25
|
+
"""添加命令参数"""
|
|
26
|
+
parser.add_argument(
|
|
27
|
+
'script',
|
|
28
|
+
nargs='?',
|
|
29
|
+
help='要运行的主程序路径 (默认: main.py)'
|
|
30
|
+
)
|
|
31
|
+
parser.add_argument(
|
|
32
|
+
'--reload',
|
|
33
|
+
action='store_true',
|
|
34
|
+
help='启用热重载模式'
|
|
35
|
+
)
|
|
36
|
+
parser.add_argument(
|
|
37
|
+
'--no-reload',
|
|
38
|
+
action='store_true',
|
|
39
|
+
help='禁用热重载模式'
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
def execute(self, args):
|
|
43
|
+
"""执行命令"""
|
|
44
|
+
script = args.script or "main.py"
|
|
45
|
+
|
|
46
|
+
# 检查脚本是否存在
|
|
47
|
+
if not os.path.exists(script):
|
|
48
|
+
from .... import _prepare_environment
|
|
49
|
+
import asyncio
|
|
50
|
+
asyncio.run(_prepare_environment())
|
|
51
|
+
|
|
52
|
+
reload_mode = args.reload and not args.no_reload
|
|
53
|
+
|
|
54
|
+
# 设置文件监控
|
|
55
|
+
self.observer = None
|
|
56
|
+
self.handler = None
|
|
57
|
+
self._setup_watchdog(script, reload_mode)
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
# 保持运行
|
|
61
|
+
console.print("\n[cyan]按 Ctrl+C 停止程序[/cyan]")
|
|
62
|
+
while True:
|
|
63
|
+
time.sleep(0.5)
|
|
64
|
+
except KeyboardInterrupt:
|
|
65
|
+
console.print("\n[info]正在安全关闭...[/]")
|
|
66
|
+
self._cleanup()
|
|
67
|
+
console.print("[success]已安全退出[/]")
|
|
68
|
+
|
|
69
|
+
def _setup_watchdog(self, script_path: str, reload_mode: bool):
|
|
70
|
+
"""
|
|
71
|
+
设置文件监控
|
|
72
|
+
|
|
73
|
+
:param script_path: 要监控的脚本路径
|
|
74
|
+
:param reload_mode: 是否启用重载模式
|
|
75
|
+
"""
|
|
76
|
+
watch_dirs = [
|
|
77
|
+
os.path.dirname(os.path.abspath(script_path)),
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
# 添加配置目录
|
|
81
|
+
config_dir = os.path.abspath(os.getcwd())
|
|
82
|
+
if config_dir not in watch_dirs:
|
|
83
|
+
watch_dirs.append(config_dir)
|
|
84
|
+
|
|
85
|
+
self.handler = ReloadHandler(script_path, reload_mode)
|
|
86
|
+
self.observer = Observer()
|
|
87
|
+
|
|
88
|
+
for d in watch_dirs:
|
|
89
|
+
if os.path.exists(d):
|
|
90
|
+
self.observer.schedule(
|
|
91
|
+
self.handler,
|
|
92
|
+
d,
|
|
93
|
+
recursive=reload_mode
|
|
94
|
+
)
|
|
95
|
+
console.print(f"[dim]监控目录: [path]{d}[/][/]")
|
|
96
|
+
|
|
97
|
+
self.observer.start()
|
|
98
|
+
|
|
99
|
+
mode_desc = "[bold]开发重载模式[/]" if reload_mode else "[bold]配置监控模式[/]"
|
|
100
|
+
console.print(Panel(
|
|
101
|
+
f"{mode_desc}\n监控目录: [path]{', '.join(watch_dirs)}[/]",
|
|
102
|
+
title="热重载已启动",
|
|
103
|
+
border_style="info"
|
|
104
|
+
))
|
|
105
|
+
|
|
106
|
+
def _cleanup(self):
|
|
107
|
+
"""清理资源"""
|
|
108
|
+
if self.observer:
|
|
109
|
+
self.observer.stop()
|
|
110
|
+
if self.handler and self.handler.process:
|
|
111
|
+
self.handler._terminate_process()
|
|
112
|
+
self.observer.join()
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# type: ignore
|
|
2
|
+
#
|
|
3
|
+
# Auto-generated type stub for run.py
|
|
4
|
+
# DO NOT EDIT MANUALLY - Generated by generate-type-stubs.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
Run 命令实现
|
|
9
|
+
|
|
10
|
+
运行主程序
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
import time
|
|
15
|
+
from argparse import ArgumentParser
|
|
16
|
+
from watchdog.observers import Observer
|
|
17
|
+
from rich.panel import Panel
|
|
18
|
+
from ...console import console
|
|
19
|
+
from ...reload_handler import ReloadHandler
|
|
20
|
+
from ..base import Command
|
|
21
|
+
|
|
22
|
+
class RunCommand(Command):
|
|
23
|
+
"""
|
|
24
|
+
运行命令
|
|
25
|
+
"""
|
|
26
|
+
def add_arguments(self: object, parser: ArgumentParser) -> ...:
|
|
27
|
+
"""
|
|
28
|
+
添加命令参数
|
|
29
|
+
"""
|
|
30
|
+
...
|
|
31
|
+
def execute(self: object, args: ...) -> ...:
|
|
32
|
+
"""
|
|
33
|
+
执行命令
|
|
34
|
+
"""
|
|
35
|
+
...
|
|
36
|
+
def _setup_watchdog(self: object, script_path: str, reload_mode: bool) -> ...:
|
|
37
|
+
"""
|
|
38
|
+
设置文件监控
|
|
39
|
+
|
|
40
|
+
:param script_path: 要监控的脚本路径
|
|
41
|
+
:param reload_mode: 是否启用重载模式
|
|
42
|
+
"""
|
|
43
|
+
...
|
|
44
|
+
def _cleanup(self: object) -> ...:
|
|
45
|
+
"""
|
|
46
|
+
清理资源
|
|
47
|
+
"""
|
|
48
|
+
...
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Self-Update 命令实现
|
|
3
|
+
|
|
4
|
+
更新 ErisPulse SDK 本身
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
import asyncio
|
|
9
|
+
from argparse import ArgumentParser
|
|
10
|
+
from rich.prompt import Confirm, Prompt
|
|
11
|
+
from rich.panel import Panel
|
|
12
|
+
|
|
13
|
+
from ...package_manager import PackageManager
|
|
14
|
+
from ...console import console
|
|
15
|
+
from ..base import Command
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SelfUpdateCommand(Command):
|
|
19
|
+
"""自更新命令"""
|
|
20
|
+
|
|
21
|
+
name = "self-update"
|
|
22
|
+
description = "更新 ErisPulse SDK 本身"
|
|
23
|
+
|
|
24
|
+
def __init__(self):
|
|
25
|
+
"""初始化命令"""
|
|
26
|
+
self.package_manager = PackageManager()
|
|
27
|
+
|
|
28
|
+
def add_arguments(self, parser: ArgumentParser):
|
|
29
|
+
"""添加命令参数"""
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
'version',
|
|
32
|
+
nargs='?',
|
|
33
|
+
help='要更新到的版本号 (可选,默认为最新版本)'
|
|
34
|
+
)
|
|
35
|
+
parser.add_argument(
|
|
36
|
+
'--pre',
|
|
37
|
+
action='store_true',
|
|
38
|
+
help='包含预发布版本'
|
|
39
|
+
)
|
|
40
|
+
parser.add_argument(
|
|
41
|
+
'--force', '-f',
|
|
42
|
+
action='store_true',
|
|
43
|
+
help='强制更新,即使版本相同'
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
def execute(self, args):
|
|
47
|
+
"""执行命令"""
|
|
48
|
+
current_version = self.package_manager.get_installed_version()
|
|
49
|
+
console.print(Panel(
|
|
50
|
+
f"[title]ErisPulse SDK 自更新[/]\n"
|
|
51
|
+
f"当前版本: [bold]{current_version}[/]",
|
|
52
|
+
title_align="left"
|
|
53
|
+
))
|
|
54
|
+
|
|
55
|
+
# 获取可用版本
|
|
56
|
+
with console.status("[bold green]正在获取版本信息...", spinner="dots"):
|
|
57
|
+
versions = asyncio.run(self.package_manager.get_pypi_versions())
|
|
58
|
+
|
|
59
|
+
if not versions:
|
|
60
|
+
console.print("[error]无法获取版本信息[/]")
|
|
61
|
+
sys.exit(1)
|
|
62
|
+
|
|
63
|
+
# 确定目标版本
|
|
64
|
+
target_version = self._select_target_version(versions, args.version, args.pre)
|
|
65
|
+
|
|
66
|
+
if target_version is None:
|
|
67
|
+
console.print("[info]操作已取消[/]")
|
|
68
|
+
sys.exit(0)
|
|
69
|
+
|
|
70
|
+
# 确认更新
|
|
71
|
+
if target_version == current_version and not args.force:
|
|
72
|
+
console.print(f"[info]当前已是目标版本 [bold]{current_version}[/][/]")
|
|
73
|
+
sys.exit(0)
|
|
74
|
+
elif not args.force:
|
|
75
|
+
if not Confirm.ask(
|
|
76
|
+
f"确认将ErisPulse SDK从 [bold]{current_version}[/] 更新到 [bold]{target_version}[/] 吗?",
|
|
77
|
+
default=False
|
|
78
|
+
):
|
|
79
|
+
console.print("[info]操作已取消[/]")
|
|
80
|
+
sys.exit(0)
|
|
81
|
+
|
|
82
|
+
# 执行更新
|
|
83
|
+
success = self.package_manager.update_self(target_version, args.force)
|
|
84
|
+
if not success:
|
|
85
|
+
sys.exit(1)
|
|
86
|
+
|
|
87
|
+
def _select_target_version(self, versions, specified_version: str = None,
|
|
88
|
+
include_pre: bool = False) -> str:
|
|
89
|
+
"""
|
|
90
|
+
选择目标版本
|
|
91
|
+
|
|
92
|
+
:param versions: 版本列表
|
|
93
|
+
:param specified_version: 用户指定的版本
|
|
94
|
+
:param include_pre: 是否包含预发布版本
|
|
95
|
+
:return: 目标版本号
|
|
96
|
+
"""
|
|
97
|
+
if specified_version:
|
|
98
|
+
# 用户已指定版本
|
|
99
|
+
if not any(v['version'] == specified_version for v in versions):
|
|
100
|
+
console.print(f"[warning]版本 {specified_version} 可能不存在[/]")
|
|
101
|
+
if not Confirm.ask("是否继续?", default=False):
|
|
102
|
+
return None
|
|
103
|
+
return specified_version
|
|
104
|
+
|
|
105
|
+
# 交互式选择
|
|
106
|
+
stable_versions = [v for v in versions if not v["pre_release"]]
|
|
107
|
+
pre_versions = [v for v in versions if v["pre_release"]]
|
|
108
|
+
|
|
109
|
+
latest_stable = stable_versions[0] if stable_versions else None
|
|
110
|
+
latest_pre = pre_versions[0] if pre_versions and include_pre else None
|
|
111
|
+
|
|
112
|
+
choices = []
|
|
113
|
+
choice_versions = {}
|
|
114
|
+
|
|
115
|
+
if latest_stable:
|
|
116
|
+
choice = f"最新稳定版 ({latest_stable['version']})"
|
|
117
|
+
choices.append(choice)
|
|
118
|
+
choice_versions[choice] = latest_stable['version']
|
|
119
|
+
|
|
120
|
+
if include_pre and latest_pre:
|
|
121
|
+
choice = f"最新预发布版 ({latest_pre['version']})"
|
|
122
|
+
choices.append(choice)
|
|
123
|
+
choice_versions[choice] = latest_pre['version']
|
|
124
|
+
|
|
125
|
+
# 添加其他选项
|
|
126
|
+
choices.append("查看所有版本")
|
|
127
|
+
choices.append("手动指定版本")
|
|
128
|
+
choices.append("取消")
|
|
129
|
+
|
|
130
|
+
# 显示选项
|
|
131
|
+
console.print("\n[info]请选择更新选项:[/]")
|
|
132
|
+
for i, choice in enumerate(choices, 1):
|
|
133
|
+
console.print(f" {i}. {choice}")
|
|
134
|
+
|
|
135
|
+
while True:
|
|
136
|
+
try:
|
|
137
|
+
selected_input = Prompt.ask(
|
|
138
|
+
"请输入选项编号",
|
|
139
|
+
default="1"
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
if selected_input.isdigit():
|
|
143
|
+
selected_index = int(selected_input)
|
|
144
|
+
if 1 <= selected_index <= len(choices):
|
|
145
|
+
selected = choices[selected_index - 1]
|
|
146
|
+
break
|
|
147
|
+
else:
|
|
148
|
+
console.print("[warning]请输入有效的选项编号[/]")
|
|
149
|
+
else:
|
|
150
|
+
if selected_input in choices:
|
|
151
|
+
selected = selected_input
|
|
152
|
+
break
|
|
153
|
+
else:
|
|
154
|
+
console.print("[warning]请输入有效的选项编号或选项名称[/]")
|
|
155
|
+
except KeyboardInterrupt:
|
|
156
|
+
console.print("\n[info]操作已取消[/]")
|
|
157
|
+
return None
|
|
158
|
+
|
|
159
|
+
if selected == "取消":
|
|
160
|
+
return None
|
|
161
|
+
elif selected == "手动指定版本":
|
|
162
|
+
target_version = Prompt.ask("请输入要更新到的版本号")
|
|
163
|
+
if not any(v['version'] == target_version for v in versions):
|
|
164
|
+
console.print(f"[warning]版本 {target_version} 可能不存在[/]")
|
|
165
|
+
if not Confirm.ask("是否继续?", default=False):
|
|
166
|
+
return None
|
|
167
|
+
return target_version
|
|
168
|
+
elif selected == "查看所有版本":
|
|
169
|
+
return self._select_from_version_list(versions, include_pre)
|
|
170
|
+
else:
|
|
171
|
+
return choice_versions[selected]
|
|
172
|
+
|
|
173
|
+
def _select_from_version_list(self, versions, include_pre: bool = False) -> str:
|
|
174
|
+
"""
|
|
175
|
+
从版本列表中选择
|
|
176
|
+
|
|
177
|
+
:param versions: 版本列表
|
|
178
|
+
:param include_pre: 是否包含预发布版本
|
|
179
|
+
:return: 选中的版本号
|
|
180
|
+
"""
|
|
181
|
+
from rich.table import Table
|
|
182
|
+
from rich.box import SIMPLE
|
|
183
|
+
|
|
184
|
+
table = Table(
|
|
185
|
+
title="可用版本",
|
|
186
|
+
box=SIMPLE,
|
|
187
|
+
header_style="info"
|
|
188
|
+
)
|
|
189
|
+
table.add_column("序号")
|
|
190
|
+
table.add_column("版本")
|
|
191
|
+
table.add_column("类型")
|
|
192
|
+
table.add_column("上传时间")
|
|
193
|
+
|
|
194
|
+
displayed = 0
|
|
195
|
+
version_list = []
|
|
196
|
+
for version_info in versions:
|
|
197
|
+
if not include_pre and version_info["pre_release"]:
|
|
198
|
+
continue
|
|
199
|
+
|
|
200
|
+
version_list.append(version_info)
|
|
201
|
+
version_type = "[yellow]预发布[/]" if version_info["pre_release"] else "[green]稳定版[/]"
|
|
202
|
+
table.add_row(
|
|
203
|
+
str(displayed + 1),
|
|
204
|
+
version_info["version"],
|
|
205
|
+
version_type,
|
|
206
|
+
version_info["uploaded"][:10] if version_info["uploaded"] else "未知"
|
|
207
|
+
)
|
|
208
|
+
displayed += 1
|
|
209
|
+
|
|
210
|
+
if displayed >= 10:
|
|
211
|
+
break
|
|
212
|
+
|
|
213
|
+
if displayed == 0:
|
|
214
|
+
console.print("[info]没有找到符合条件的版本[/]")
|
|
215
|
+
return None
|
|
216
|
+
|
|
217
|
+
console.print(table)
|
|
218
|
+
|
|
219
|
+
# 显示版本选择
|
|
220
|
+
console.print("\n[info]请选择要更新到的版本:[/]")
|
|
221
|
+
while True:
|
|
222
|
+
try:
|
|
223
|
+
version_input = Prompt.ask("请输入版本序号或版本号")
|
|
224
|
+
if version_input.isdigit():
|
|
225
|
+
version_index = int(version_input)
|
|
226
|
+
if 1 <= version_index <= len(version_list):
|
|
227
|
+
return version_list[version_index - 1]['version']
|
|
228
|
+
else:
|
|
229
|
+
console.print("[warning]请输入有效的版本序号[/]")
|
|
230
|
+
else:
|
|
231
|
+
if any(v['version'] == version_input for v in version_list):
|
|
232
|
+
return version_input
|
|
233
|
+
else:
|
|
234
|
+
console.print("[warning]请输入有效的版本序号或版本号[/]")
|
|
235
|
+
except KeyboardInterrupt:
|
|
236
|
+
console.print("\n[info]操作已取消[/]")
|
|
237
|
+
return None
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# type: ignore
|
|
2
|
+
#
|
|
3
|
+
# Auto-generated type stub for self_update.py
|
|
4
|
+
# DO NOT EDIT MANUALLY - Generated by generate-type-stubs.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
Self-Update 命令实现
|
|
9
|
+
|
|
10
|
+
更新 ErisPulse SDK 本身
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import sys
|
|
14
|
+
import asyncio
|
|
15
|
+
from argparse import ArgumentParser
|
|
16
|
+
from rich.prompt import Confirm, Prompt
|
|
17
|
+
from rich.panel import Panel
|
|
18
|
+
from ...package_manager import PackageManager
|
|
19
|
+
from ...console import console
|
|
20
|
+
from ..base import Command
|
|
21
|
+
|
|
22
|
+
class SelfUpdateCommand(Command):
|
|
23
|
+
"""
|
|
24
|
+
自更新命令
|
|
25
|
+
"""
|
|
26
|
+
def __init__(self: None) -> ...:
|
|
27
|
+
"""
|
|
28
|
+
初始化命令
|
|
29
|
+
"""
|
|
30
|
+
...
|
|
31
|
+
def add_arguments(self: object, parser: ArgumentParser) -> ...:
|
|
32
|
+
"""
|
|
33
|
+
添加命令参数
|
|
34
|
+
"""
|
|
35
|
+
...
|
|
36
|
+
def execute(self: object, args: ...) -> ...:
|
|
37
|
+
"""
|
|
38
|
+
执行命令
|
|
39
|
+
"""
|
|
40
|
+
...
|
|
41
|
+
def _select_target_version(self: object, versions: ..., specified_version: str = ..., include_pre: bool = ...) -> str:
|
|
42
|
+
"""
|
|
43
|
+
选择目标版本
|
|
44
|
+
|
|
45
|
+
:param versions: 版本列表
|
|
46
|
+
:param specified_version: 用户指定的版本
|
|
47
|
+
:param include_pre: 是否包含预发布版本
|
|
48
|
+
:return: 目标版本号
|
|
49
|
+
"""
|
|
50
|
+
...
|
|
51
|
+
def _select_from_version_list(self: object, versions: ..., include_pre: bool = ...) -> str:
|
|
52
|
+
"""
|
|
53
|
+
从版本列表中选择
|
|
54
|
+
|
|
55
|
+
:param versions: 版本列表
|
|
56
|
+
:param include_pre: 是否包含预发布版本
|
|
57
|
+
:return: 选中的版本号
|
|
58
|
+
"""
|
|
59
|
+
...
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Uninstall 命令实现
|
|
3
|
+
|
|
4
|
+
支持卸载模块、适配器、CLI 扩展
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
from argparse import ArgumentParser
|
|
9
|
+
|
|
10
|
+
from ...package_manager import PackageManager
|
|
11
|
+
from ...console import console
|
|
12
|
+
from ..base import Command
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class UninstallCommand(Command):
|
|
16
|
+
"""卸载命令"""
|
|
17
|
+
|
|
18
|
+
name = "uninstall"
|
|
19
|
+
description = "卸载模块/适配器包"
|
|
20
|
+
|
|
21
|
+
def __init__(self):
|
|
22
|
+
"""初始化命令"""
|
|
23
|
+
self.package_manager = PackageManager()
|
|
24
|
+
|
|
25
|
+
def add_arguments(self, parser: ArgumentParser):
|
|
26
|
+
"""添加命令参数"""
|
|
27
|
+
parser.add_argument(
|
|
28
|
+
'package',
|
|
29
|
+
nargs='+',
|
|
30
|
+
help='要卸载的包名(可指定多个)'
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
def execute(self, args):
|
|
34
|
+
"""执行命令"""
|
|
35
|
+
success = self.package_manager.uninstall_package(args.package)
|
|
36
|
+
if not success:
|
|
37
|
+
sys.exit(1)
|