ErisPulse 2.4.7__tar.gz → 2.5.0.dev0__tar.gz
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-2.4.7 → erispulse-2.5.0.dev0}/PKG-INFO +1 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/pyproject.toml +1 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/base.py +3 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/base.pyi +3 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/cli.py +12 -6
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/cli.pyi +0 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/create.py +80 -23
- erispulse-2.5.0.dev0/src/ErisPulse/CLI/commands/create.pyi +97 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/init.py +170 -57
- erispulse-2.5.0.dev0/src/ErisPulse/CLI/commands/init.pyi +95 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/install.py +160 -2
- erispulse-2.5.0.dev0/src/ErisPulse/CLI/commands/install.pyi +80 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/list.py +24 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/list.pyi +22 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/list_remote.py +18 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/list_remote.pyi +16 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/run.py +118 -18
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/run.pyi +37 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/self_update.py +39 -0
- erispulse-2.5.0.dev0/src/ErisPulse/CLI/commands/self_update.pyi +70 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/uninstall.py +17 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/uninstall.pyi +11 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/upgrade.py +14 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/upgrade.pyi +8 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/console.py +16 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/console.pyi +16 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/registry.py +35 -6
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/registry.pyi +21 -4
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/utils/display.py +95 -1
- erispulse-2.5.0.dev0/src/ErisPulse/CLI/utils/display.pyi +115 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/utils/package_manager.py +328 -6
- erispulse-2.5.0.dev0/src/ErisPulse/CLI/utils/package_manager.pyi +365 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/adapter.py +72 -8
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/adapter.pyi +12 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/__init__.py +9 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/__init__.pyi +1 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/command.py +8 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/command.pyi +3 -2
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/wrapper.py +222 -153
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/wrapper.pyi +68 -18
- erispulse-2.5.0.dev0/src/ErisPulse/Core/__init__.py +86 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/adapter.py +148 -12
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/adapter.pyi +16 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/client.py +94 -44
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/client.pyi +1 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/constants.py +10 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/logger.py +150 -14
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/logger.pyi +55 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/router.py +106 -7
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/router.pyi +14 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/runtime/frame_config.py +4 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/runtime/frame_config.pyi +1 -1
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/sdk.py +67 -8
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/sdk.pyi +1 -1
- erispulse-2.4.7/src/ErisPulse/CLI/commands/create.pyi +0 -44
- erispulse-2.4.7/src/ErisPulse/CLI/commands/init.pyi +0 -44
- erispulse-2.4.7/src/ErisPulse/CLI/commands/install.pyi +0 -39
- erispulse-2.4.7/src/ErisPulse/CLI/commands/self_update.pyi +0 -37
- erispulse-2.4.7/src/ErisPulse/CLI/utils/display.pyi +0 -45
- erispulse-2.4.7/src/ErisPulse/CLI/utils/package_manager.pyi +0 -110
- erispulse-2.4.7/src/ErisPulse/Core/__init__.py +0 -86
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/.gitignore +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/LICENSE +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/README.md +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/__init__.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/__init__.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/__init__.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/commands/__init__.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/utils/__init__.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/CLI/utils/__init__.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/__init__.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/__init__.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/client.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/client.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/errors.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/errors.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/manager.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/manager.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/module.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/module.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/router.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/router.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/storage.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/storage.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/websocket.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Bases/websocket.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/base.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/base.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/message.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/message.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/message_builder.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/message_builder.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/meta.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/meta.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/notice.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/notice.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/request.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/request.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/session_type.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/Event/session_type.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/__init__.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/config.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/config.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/constants.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/lifecycle.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/lifecycle.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/module.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/module.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/storage.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/Core/storage.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/__init__.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/__init__.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/__main__.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/__main__.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/finders/__init__.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/finders/__init__.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/finders/adapter.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/finders/adapter.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/finders/bases/__init__.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/finders/bases/__init__.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/finders/bases/finder.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/finders/bases/finder.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/finders/module.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/finders/module.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/loaders/__init__.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/loaders/__init__.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/loaders/adapter.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/loaders/adapter.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/loaders/bases/__init__.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/loaders/bases/__init__.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/loaders/bases/loader.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/loaders/bases/loader.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/loaders/module.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/loaders/module.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/loaders/strategy.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/loaders/strategy.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/runtime/__init__.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/runtime/__init__.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/runtime/config_schema.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/runtime/config_schema.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/runtime/context.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/runtime/context.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/runtime/exceptions.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/runtime/exceptions.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/web_status/4xx.png +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/web_status/5xx.png +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/web_status/__init__.py +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/web_status/__init__.pyi +0 -0
- {erispulse-2.4.7 → erispulse-2.5.0.dev0}/src/ErisPulse/web_status/unknow.png +0 -0
|
@@ -17,12 +17,14 @@ class Command(ABC):
|
|
|
17
17
|
{!--< tips >!--}
|
|
18
18
|
1. 每个命令类必须实现 add_arguments 和 execute 方法
|
|
19
19
|
2. name 和 description 为类属性,必须在子类中定义
|
|
20
|
-
3.
|
|
20
|
+
3. aliases 为可选类属性,用于定义命令的简化形式
|
|
21
|
+
4. execute 方法接收解析后的 args 对象
|
|
21
22
|
{!--< /tips >!--}
|
|
22
23
|
"""
|
|
23
24
|
|
|
24
25
|
name: str = "" # 命令名称
|
|
25
26
|
description: str = "" # 命令描述
|
|
27
|
+
aliases: list = [] # 命令别名(简化形式,如 "install" -> ["i", "add"])
|
|
26
28
|
|
|
27
29
|
@abstractmethod
|
|
28
30
|
def add_arguments(self, parser: ArgumentParser):
|
|
@@ -22,11 +22,13 @@ class Command(ABC):
|
|
|
22
22
|
{!--< tips >!--}
|
|
23
23
|
1. 每个命令类必须实现 add_arguments 和 execute 方法
|
|
24
24
|
2. name 和 description 为类属性,必须在子类中定义
|
|
25
|
-
3.
|
|
25
|
+
3. aliases 为可选类属性,用于定义命令的简化形式
|
|
26
|
+
4. execute 方法接收解析后的 args 对象
|
|
26
27
|
{!--< /tips >!--}
|
|
27
28
|
"""
|
|
28
29
|
name: str
|
|
29
30
|
description: str
|
|
31
|
+
aliases: list
|
|
30
32
|
def add_arguments(self: object, parser: ArgumentParser) -> ...:
|
|
31
33
|
"""
|
|
32
34
|
添加命令参数
|
|
@@ -16,7 +16,6 @@ from rich.text import Text
|
|
|
16
16
|
from .console import console, print_banner
|
|
17
17
|
from .registry import CommandRegistry
|
|
18
18
|
from .base import Command
|
|
19
|
-
from .utils.display import section_header
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
class CLI:
|
|
@@ -117,9 +116,13 @@ class CLI:
|
|
|
117
116
|
"""注册所有内置命令(通过自动发现)"""
|
|
118
117
|
self._auto_discover_commands()
|
|
119
118
|
|
|
120
|
-
#
|
|
119
|
+
# 添加所有命令的参数(同时注册命令别名)
|
|
121
120
|
for command in self.registry.get_all():
|
|
122
|
-
parser = self.subparsers.add_parser(
|
|
121
|
+
parser = self.subparsers.add_parser(
|
|
122
|
+
command.name,
|
|
123
|
+
aliases=getattr(command, "aliases", None) or [],
|
|
124
|
+
help=command.description,
|
|
125
|
+
)
|
|
123
126
|
command.add_arguments(parser)
|
|
124
127
|
|
|
125
128
|
def _print_version(self):
|
|
@@ -158,16 +161,19 @@ class CLI:
|
|
|
158
161
|
self.parser.print_help()
|
|
159
162
|
return
|
|
160
163
|
|
|
161
|
-
|
|
164
|
+
# 将别名解析为规范命令名
|
|
165
|
+
canonical = self.registry.resolve(args.command) or args.command
|
|
166
|
+
|
|
167
|
+
if unknown and canonical not in ("install", "create"):
|
|
162
168
|
console.print(f"[warning]未识别的参数: {' '.join(unknown)}[/]")
|
|
163
169
|
|
|
164
170
|
try:
|
|
165
171
|
# 执行命令
|
|
166
|
-
command = self.registry.get(
|
|
172
|
+
command = self.registry.get(canonical)
|
|
167
173
|
if command:
|
|
168
174
|
console.print()
|
|
169
175
|
console.print(
|
|
170
|
-
Text(
|
|
176
|
+
Text(" ── ", style="dim"),
|
|
171
177
|
Text(command.description, style="bold"),
|
|
172
178
|
sep="",
|
|
173
179
|
)
|
|
@@ -14,7 +14,7 @@ from rich.text import Text
|
|
|
14
14
|
|
|
15
15
|
from ..console import console
|
|
16
16
|
from ..base import Command
|
|
17
|
-
from ..utils.display import section_header
|
|
17
|
+
from ..utils.display import section_header, prompt_validated
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
_LICENSE_TEMPLATE = """MIT License
|
|
@@ -474,6 +474,12 @@ token = ""
|
|
|
474
474
|
|
|
475
475
|
|
|
476
476
|
def _camel_to_snake(name: str) -> str:
|
|
477
|
+
"""
|
|
478
|
+
将 PascalCase/CamelCase 名称转换为 snake_case
|
|
479
|
+
|
|
480
|
+
:param name: [str] 原始名称
|
|
481
|
+
:return: [str] 转换后的 snake_case 名称
|
|
482
|
+
"""
|
|
477
483
|
import re
|
|
478
484
|
|
|
479
485
|
s = re.sub(r"(?<=[a-z0-9])([A-Z])", r"_\1", name)
|
|
@@ -482,10 +488,24 @@ def _camel_to_snake(name: str) -> str:
|
|
|
482
488
|
|
|
483
489
|
|
|
484
490
|
def _to_converter_name(name: str) -> str:
|
|
491
|
+
"""
|
|
492
|
+
根据适配器名称生成转换器类名
|
|
493
|
+
|
|
494
|
+
:param name: [str] 适配器名称
|
|
495
|
+
:return: [str] 转换器类名(名称后追加 Converter)
|
|
496
|
+
"""
|
|
485
497
|
return f"{name}Converter"
|
|
486
498
|
|
|
487
499
|
|
|
488
500
|
def _validate_name(name: str) -> bool:
|
|
501
|
+
"""
|
|
502
|
+
校验项目/模块/适配器名称是否合法
|
|
503
|
+
|
|
504
|
+
名称必须以字母开头,且只能包含字母、数字和下划线。
|
|
505
|
+
|
|
506
|
+
:param name: [str] 待校验的名称
|
|
507
|
+
:return: [bool] 合法返回 True,否则 False
|
|
508
|
+
"""
|
|
489
509
|
if not name:
|
|
490
510
|
return False
|
|
491
511
|
if not name[0].isalpha():
|
|
@@ -494,8 +514,15 @@ def _validate_name(name: str) -> bool:
|
|
|
494
514
|
|
|
495
515
|
|
|
496
516
|
class CreateCommand(Command):
|
|
517
|
+
"""
|
|
518
|
+
create 命令
|
|
519
|
+
|
|
520
|
+
脚手架工具,快速创建 Module / Adapter 项目模板
|
|
521
|
+
"""
|
|
522
|
+
|
|
497
523
|
name = "create"
|
|
498
524
|
description = "创建 Module / Adapter 项目脚手架"
|
|
525
|
+
aliases = ["c", "new"]
|
|
499
526
|
|
|
500
527
|
def add_arguments(self, parser: ArgumentParser):
|
|
501
528
|
parser.add_argument(
|
|
@@ -521,14 +548,16 @@ class CreateCommand(Command):
|
|
|
521
548
|
if not create_type:
|
|
522
549
|
create_type = self._interactive_select_type()
|
|
523
550
|
|
|
551
|
+
default_name = "MyModule" if create_type == "module" else "MyAdapter"
|
|
524
552
|
name = args.name
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
name =
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
553
|
+
# 名称校验:非法时保留输入并重新提示,而非直接退出
|
|
554
|
+
if not (name and _validate_name(name)):
|
|
555
|
+
name = prompt_validated(
|
|
556
|
+
" 名称 (PascalCase)",
|
|
557
|
+
default=name or default_name,
|
|
558
|
+
validate=_validate_name,
|
|
559
|
+
error_msg="名称必须以字母开头,只能包含字母、数字和下划线",
|
|
560
|
+
)
|
|
532
561
|
|
|
533
562
|
if create_type == "module":
|
|
534
563
|
self._create_module(args, name)
|
|
@@ -536,6 +565,11 @@ class CreateCommand(Command):
|
|
|
536
565
|
self._create_adapter(args, name)
|
|
537
566
|
|
|
538
567
|
def _interactive_select_type(self) -> str:
|
|
568
|
+
"""
|
|
569
|
+
交互式选择创建类型(Module 或 Adapter)
|
|
570
|
+
|
|
571
|
+
:return: [str] 返回 "module" 或 "adapter"
|
|
572
|
+
"""
|
|
539
573
|
section_header("选择创建类型")
|
|
540
574
|
console.print(" [bold]1.[/] Module [dim]— 自定义功能模块[/]")
|
|
541
575
|
console.print(" [bold]2.[/] Adapter [dim]— 平台适配器[/]")
|
|
@@ -547,12 +581,28 @@ class CreateCommand(Command):
|
|
|
547
581
|
def _ask_missing(
|
|
548
582
|
self, args, field_name: str, prompt_text: str, default: str = ""
|
|
549
583
|
) -> str:
|
|
584
|
+
"""
|
|
585
|
+
获取参数值,若缺失则交互式提示输入
|
|
586
|
+
|
|
587
|
+
:param args: [Any] 解析后的命令参数对象
|
|
588
|
+
:param field_name: [str] 参数字段名
|
|
589
|
+
:param prompt_text: [str] 提示文本
|
|
590
|
+
:param default: [str] 默认值 (默认: "")
|
|
591
|
+
:return: [str] 获取到的参数值
|
|
592
|
+
"""
|
|
550
593
|
val = getattr(args, field_name, None) or ""
|
|
551
594
|
if not val:
|
|
552
595
|
val = Prompt.ask(f" {prompt_text}", default=default)
|
|
553
596
|
return val
|
|
554
597
|
|
|
555
598
|
def _create_module(self, args, name: str):
|
|
599
|
+
"""
|
|
600
|
+
创建 Module 项目脚手架
|
|
601
|
+
|
|
602
|
+
:param args: [Any] 解析后的命令参数对象
|
|
603
|
+
:param name: [str] 模块名称
|
|
604
|
+
:return: [None] 无返回值
|
|
605
|
+
"""
|
|
556
606
|
description = self._ask_missing(
|
|
557
607
|
args, "description", "模块描述", f"一个非常哇塞的{name}模块"
|
|
558
608
|
)
|
|
@@ -604,24 +654,31 @@ class CreateCommand(Command):
|
|
|
604
654
|
console.print()
|
|
605
655
|
console.print(Text(" 项目结构:", style="bold"))
|
|
606
656
|
console.print(f" {name}/")
|
|
607
|
-
console.print(
|
|
608
|
-
console.print(
|
|
609
|
-
console.print(
|
|
657
|
+
console.print(" ├── pyproject.toml")
|
|
658
|
+
console.print(" ├── LICENSE")
|
|
659
|
+
console.print(" ├── README.md")
|
|
610
660
|
console.print(f" └── {name}/")
|
|
611
|
-
console.print(
|
|
612
|
-
console.print(
|
|
661
|
+
console.print(" ├── __init__.py")
|
|
662
|
+
console.print(" └── Core.py")
|
|
613
663
|
console.print()
|
|
614
664
|
console.print(Text(" 接下来:", style="bold"))
|
|
615
665
|
console.print(f" · cd {name}")
|
|
616
666
|
console.print(f" · 编辑 {name}/Core.py 实现模块逻辑")
|
|
617
|
-
console.print(
|
|
618
|
-
console.print(
|
|
667
|
+
console.print(" · pip install -e . (开发模式安装)")
|
|
668
|
+
console.print(" · epsdk run (运行测试)")
|
|
619
669
|
|
|
620
670
|
except Exception as e:
|
|
621
671
|
console.print(f"[error] 创建失败: {e}")
|
|
622
672
|
sys.exit(1)
|
|
623
673
|
|
|
624
674
|
def _create_adapter(self, args, name: str):
|
|
675
|
+
"""
|
|
676
|
+
创建 Adapter 项目脚手架
|
|
677
|
+
|
|
678
|
+
:param args: [Any] 解析后的命令参数对象
|
|
679
|
+
:param name: [str] 适配器名称
|
|
680
|
+
:return: [None] 无返回值
|
|
681
|
+
"""
|
|
625
682
|
description = self._ask_missing(
|
|
626
683
|
args, "description", "适配器描述", f"{name}平台适配器"
|
|
627
684
|
)
|
|
@@ -690,20 +747,20 @@ class CreateCommand(Command):
|
|
|
690
747
|
console.print()
|
|
691
748
|
console.print(Text(" 项目结构:", style="bold"))
|
|
692
749
|
console.print(f" {name}/")
|
|
693
|
-
console.print(
|
|
694
|
-
console.print(
|
|
695
|
-
console.print(
|
|
750
|
+
console.print(" ├── pyproject.toml")
|
|
751
|
+
console.print(" ├── LICENSE")
|
|
752
|
+
console.print(" ├── README.md")
|
|
696
753
|
console.print(f" └── {name}/")
|
|
697
|
-
console.print(
|
|
698
|
-
console.print(
|
|
699
|
-
console.print(
|
|
754
|
+
console.print(" ├── __init__.py")
|
|
755
|
+
console.print(" ├── Core.py")
|
|
756
|
+
console.print(" └── Converter.py")
|
|
700
757
|
console.print()
|
|
701
758
|
console.print(Text(" 接下来:", style="bold"))
|
|
702
759
|
console.print(f" · cd {name}")
|
|
703
760
|
console.print(f" · 编辑 {name}/Core.py 实现适配器逻辑")
|
|
704
761
|
console.print(f" · 编辑 {name}/Converter.py 实现消息格式转换")
|
|
705
|
-
console.print(
|
|
706
|
-
console.print(
|
|
762
|
+
console.print(" · pip install -e . (开发模式安装)")
|
|
763
|
+
console.print(" · epsdk run (运行测试)")
|
|
707
764
|
|
|
708
765
|
except Exception as e:
|
|
709
766
|
console.print(f"[error] 创建失败: {e}")
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# type: ignore
|
|
2
|
+
#
|
|
3
|
+
# Auto-generated type stub for create.py
|
|
4
|
+
# DO NOT EDIT MANUALLY - Generated by generate-type-stubs.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
Create 命令实现
|
|
9
|
+
|
|
10
|
+
脚手架工具,快速创建 Module / Adapter 项目模板
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import sys
|
|
14
|
+
import datetime
|
|
15
|
+
from argparse import ArgumentParser
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from rich.prompt import Prompt, IntPrompt
|
|
18
|
+
from rich.text import Text
|
|
19
|
+
from ..console import console
|
|
20
|
+
from ..base import Command
|
|
21
|
+
from ..utils.display import section_header, prompt_validated
|
|
22
|
+
|
|
23
|
+
def _camel_to_snake(name: str) -> str:
|
|
24
|
+
"""
|
|
25
|
+
将 PascalCase/CamelCase 名称转换为 snake_case
|
|
26
|
+
|
|
27
|
+
:param name: [str] 原始名称
|
|
28
|
+
:return: [str] 转换后的 snake_case 名称
|
|
29
|
+
"""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
def _to_converter_name(name: str) -> str:
|
|
33
|
+
"""
|
|
34
|
+
根据适配器名称生成转换器类名
|
|
35
|
+
|
|
36
|
+
:param name: [str] 适配器名称
|
|
37
|
+
:return: [str] 转换器类名(名称后追加 Converter)
|
|
38
|
+
"""
|
|
39
|
+
...
|
|
40
|
+
|
|
41
|
+
def _validate_name(name: str) -> bool:
|
|
42
|
+
"""
|
|
43
|
+
校验项目/模块/适配器名称是否合法
|
|
44
|
+
|
|
45
|
+
名称必须以字母开头,且只能包含字母、数字和下划线。
|
|
46
|
+
|
|
47
|
+
:param name: [str] 待校验的名称
|
|
48
|
+
:return: [bool] 合法返回 True,否则 False
|
|
49
|
+
"""
|
|
50
|
+
...
|
|
51
|
+
|
|
52
|
+
class CreateCommand(Command):
|
|
53
|
+
"""
|
|
54
|
+
create 命令
|
|
55
|
+
|
|
56
|
+
脚手架工具,快速创建 Module / Adapter 项目模板
|
|
57
|
+
"""
|
|
58
|
+
def add_arguments(self: object, parser: ArgumentParser) -> ...:
|
|
59
|
+
...
|
|
60
|
+
def execute(self: object, args: ...) -> ...:
|
|
61
|
+
...
|
|
62
|
+
def _interactive_select_type(self: object) -> str:
|
|
63
|
+
"""
|
|
64
|
+
交互式选择创建类型(Module 或 Adapter)
|
|
65
|
+
|
|
66
|
+
:return: [str] 返回 "module" 或 "adapter"
|
|
67
|
+
"""
|
|
68
|
+
...
|
|
69
|
+
def _ask_missing(self: object, args: ..., field_name: str, prompt_text: str, default: str = ...) -> str:
|
|
70
|
+
"""
|
|
71
|
+
获取参数值,若缺失则交互式提示输入
|
|
72
|
+
|
|
73
|
+
:param args: [Any] 解析后的命令参数对象
|
|
74
|
+
:param field_name: [str] 参数字段名
|
|
75
|
+
:param prompt_text: [str] 提示文本
|
|
76
|
+
:param default: [str] 默认值 (默认: "")
|
|
77
|
+
:return: [str] 获取到的参数值
|
|
78
|
+
"""
|
|
79
|
+
...
|
|
80
|
+
def _create_module(self: object, args: ..., name: str) -> ...:
|
|
81
|
+
"""
|
|
82
|
+
创建 Module 项目脚手架
|
|
83
|
+
|
|
84
|
+
:param args: [Any] 解析后的命令参数对象
|
|
85
|
+
:param name: [str] 模块名称
|
|
86
|
+
:return: [None] 无返回值
|
|
87
|
+
"""
|
|
88
|
+
...
|
|
89
|
+
def _create_adapter(self: object, args: ..., name: str) -> ...:
|
|
90
|
+
"""
|
|
91
|
+
创建 Adapter 项目脚手架
|
|
92
|
+
|
|
93
|
+
:param args: [Any] 解析后的命令参数对象
|
|
94
|
+
:param name: [str] 适配器名称
|
|
95
|
+
:return: [None] 无返回值
|
|
96
|
+
"""
|
|
97
|
+
...
|