101 lines
2.8 KiB
Python
101 lines
2.8 KiB
Python
import sys
|
|
from dataclasses import dataclass
|
|
|
|
from cli.core import (
|
|
DEFAULT_CORE_SERVICES,
|
|
CliApplicationBuilder,
|
|
CompletionDispatcher,
|
|
ProjectRuntimeLocator,
|
|
)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class CliImportArgvScope:
|
|
"""
|
|
CLI 导入期参数作用域。
|
|
|
|
该对象负责在根应用构建阶段暂时切换 `sys.argv`,只保留导入期
|
|
需要的最小参数集,避免该过程继续以内联 `try/finally` 形式散落
|
|
在入口运行器中。
|
|
|
|
:param project_runtime_locator: CLI 项目运行时定位器
|
|
"""
|
|
|
|
project_runtime_locator: ProjectRuntimeLocator
|
|
|
|
def run(self, callback: object) -> object:
|
|
"""
|
|
在导入期参数作用域内执行回调。
|
|
|
|
:param callback: 待执行回调
|
|
:return: 回调执行结果
|
|
"""
|
|
original_argv = list(sys.argv)
|
|
try:
|
|
sys.argv = self.project_runtime_locator.extract_import_argv(original_argv)
|
|
return callback()
|
|
finally:
|
|
sys.argv = original_argv
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class CliMainRunner:
|
|
"""
|
|
CLI 根入口运行器。
|
|
|
|
该运行器负责串联项目目录定位、导入期参数裁剪、根应用构建、
|
|
completion 分发与 Typer 应用启动,避免 `main.py` 继续停留在
|
|
模块级散乱编排状态。
|
|
|
|
:param project_runtime_locator: CLI 项目运行时定位器
|
|
:param completion_dispatcher: shell completion 分发器
|
|
:param application_builder: 根应用构建器
|
|
"""
|
|
|
|
project_runtime_locator: ProjectRuntimeLocator
|
|
completion_dispatcher: CompletionDispatcher
|
|
application_builder: CliApplicationBuilder
|
|
import_argv_scope: CliImportArgvScope
|
|
|
|
def build_cli(self) -> object:
|
|
"""
|
|
构建 CLI 根应用,并在导入期仅保留最小化参数集。
|
|
|
|
:return: Typer 根应用
|
|
"""
|
|
self.project_runtime_locator.ensure_backend_dir_on_sys_path()
|
|
return self.import_argv_scope.run(self.application_builder.build)
|
|
|
|
def run(self) -> None:
|
|
"""
|
|
执行 Typer CLI 根应用。
|
|
|
|
:return: None
|
|
"""
|
|
cli = self.build_cli()
|
|
self.completion_dispatcher.dispatch(cli)
|
|
cli(prog_name='shierfeng')
|
|
|
|
|
|
CLI_APPLICATION_BUILDER = CliApplicationBuilder(output_renderer=DEFAULT_CORE_SERVICES.output_renderer)
|
|
PROJECT_RUNTIME_LOCATOR = ProjectRuntimeLocator()
|
|
CLI_MAIN_RUNNER = CliMainRunner(
|
|
project_runtime_locator=PROJECT_RUNTIME_LOCATOR,
|
|
completion_dispatcher=CompletionDispatcher(),
|
|
application_builder=CLI_APPLICATION_BUILDER,
|
|
import_argv_scope=CliImportArgvScope(project_runtime_locator=PROJECT_RUNTIME_LOCATOR),
|
|
)
|
|
|
|
|
|
def main() -> None:
|
|
"""
|
|
执行 CLI 根入口运行器。
|
|
|
|
:return: None
|
|
"""
|
|
CLI_MAIN_RUNNER.run()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|