调整部分前端布局和后端增删改逻辑
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
from cli.metadata.command_specs import COMPLETION_SHELL_SPEC_REGISTRY, CompletionShellSpec, CompletionShellSpecRegistry
|
||||
from cli.metadata.option_specs import ENVIRONMENT_OPTION_SERVICE, EnvironmentOptionService
|
||||
|
||||
__all__ = [
|
||||
'COMPLETION_SHELL_SPEC_REGISTRY',
|
||||
'ENVIRONMENT_OPTION_SERVICE',
|
||||
'CompletionShellSpec',
|
||||
'CompletionShellSpecRegistry',
|
||||
'EnvironmentOptionService',
|
||||
]
|
||||
@@ -0,0 +1,98 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Literal
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class CompletionShellSpec:
|
||||
"""
|
||||
Shell completion 元数据定义。
|
||||
|
||||
name: shell 名称
|
||||
description: shell 描述文本
|
||||
generator: 脚本生成方式
|
||||
default_target: 默认脚本落盘路径,相对于用户 home 目录
|
||||
default_rc_file: 默认 rc 文件路径,相对于用户 home 目录
|
||||
auto_discovery: 是否会被 shell 自动发现
|
||||
supported: 当前版本是否已支持
|
||||
"""
|
||||
|
||||
name: str
|
||||
description: str
|
||||
generator: Literal['click', 'custom', 'unsupported']
|
||||
default_target: str
|
||||
default_rc_file: str | None
|
||||
auto_discovery: bool
|
||||
supported: bool
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class CompletionShellSpecRegistry:
|
||||
"""
|
||||
completion shell 元数据注册表。
|
||||
|
||||
该注册表集中维护 CLI 当前支持的 shell completion 元数据,
|
||||
供 installer、doctor 和 provider 等场景统一查询。
|
||||
|
||||
:param specs: 按 shell 名称索引的元数据表
|
||||
"""
|
||||
|
||||
specs: dict[str, CompletionShellSpec]
|
||||
|
||||
def get_spec(self, shell_name: str) -> CompletionShellSpec | None:
|
||||
"""
|
||||
获取指定 shell 的 completion 元数据。
|
||||
|
||||
:param shell_name: shell 名称
|
||||
:return: shell 元数据,不存在时返回 None
|
||||
"""
|
||||
return self.specs.get(shell_name)
|
||||
|
||||
def list_shell_names(self) -> list[str]:
|
||||
"""
|
||||
获取已注册的 shell 名称列表。
|
||||
|
||||
:return: shell 名称列表
|
||||
"""
|
||||
return list(self.specs)
|
||||
|
||||
|
||||
DEFAULT_COMPLETION_SHELL_SPECS: dict[str, CompletionShellSpec] = {
|
||||
'bash': CompletionShellSpec(
|
||||
name='bash',
|
||||
description='GNU Bash shell completion',
|
||||
generator='click',
|
||||
default_target='.local/share/shierfeng/completion/shierfeng.bash',
|
||||
default_rc_file='.bashrc',
|
||||
auto_discovery=False,
|
||||
supported=True,
|
||||
),
|
||||
'zsh': CompletionShellSpec(
|
||||
name='zsh',
|
||||
description='Zsh shell completion',
|
||||
generator='click',
|
||||
default_target='.local/share/shierfeng/completion/shierfeng.zsh',
|
||||
default_rc_file='.zshrc',
|
||||
auto_discovery=False,
|
||||
supported=True,
|
||||
),
|
||||
'fish': CompletionShellSpec(
|
||||
name='fish',
|
||||
description='Fish shell completion',
|
||||
generator='click',
|
||||
default_target='.config/fish/completions/shierfeng.fish',
|
||||
default_rc_file=None,
|
||||
auto_discovery=True,
|
||||
supported=True,
|
||||
),
|
||||
'powershell': CompletionShellSpec(
|
||||
name='powershell',
|
||||
description='Windows PowerShell / PowerShell 7 completion',
|
||||
generator='custom',
|
||||
default_target='Documents/PowerShell/Profile/shierfeng.ps1',
|
||||
default_rc_file='Documents/PowerShell/Microsoft.PowerShell_profile.ps1',
|
||||
auto_discovery=False,
|
||||
supported=True,
|
||||
),
|
||||
}
|
||||
|
||||
COMPLETION_SHELL_SPEC_REGISTRY = CompletionShellSpecRegistry(specs=DEFAULT_COMPLETION_SHELL_SPECS)
|
||||
@@ -0,0 +1,36 @@
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
DEFAULT_ENVIRONMENTS = ('dev', 'prod', 'dockermy', 'dockerpg')
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class EnvironmentOptionService:
|
||||
"""
|
||||
CLI 环境选项服务。
|
||||
|
||||
该服务负责发现当前项目下可用的环境名称集合,供 completion、
|
||||
wizard 和诊断信息等场景复用。
|
||||
|
||||
:param default_environments: 默认内置环境名称列表
|
||||
"""
|
||||
|
||||
default_environments: tuple[str, ...] = DEFAULT_ENVIRONMENTS
|
||||
|
||||
def discover_env_names(self, project_dir: Path | None = None) -> list[str]:
|
||||
"""
|
||||
发现当前项目可用的环境名称列表。
|
||||
|
||||
:param project_dir: 后端项目目录,默认使用当前工作目录
|
||||
:return: 去重且排序后的环境名称列表
|
||||
"""
|
||||
resolved_project_dir = (project_dir or Path.cwd()).resolve()
|
||||
env_names = set(self.default_environments)
|
||||
for env_file in resolved_project_dir.glob('.env.*'):
|
||||
suffix = env_file.name.removeprefix('.env.').strip()
|
||||
if suffix:
|
||||
env_names.add(suffix)
|
||||
return sorted(env_names)
|
||||
|
||||
|
||||
ENVIRONMENT_OPTION_SERVICE = EnvironmentOptionService()
|
||||
@@ -0,0 +1,75 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Literal
|
||||
|
||||
from cli.guards import DEFAULT_DANGEROUS_COMMAND_RULE_REGISTRY, DangerousCommandRuleRegistry
|
||||
|
||||
CommandRiskLevel = Literal['readonly', 'normal', 'high']
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class CommandRiskSpec:
|
||||
"""
|
||||
CLI 命令风险元数据定义。
|
||||
|
||||
:param command_name: 命令唯一标识
|
||||
:param risk_level: 风险级别
|
||||
:param supports_dry_run: 是否支持演练执行
|
||||
"""
|
||||
|
||||
command_name: str
|
||||
risk_level: CommandRiskLevel
|
||||
supports_dry_run: bool
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class CommandRiskSpecRegistry:
|
||||
"""
|
||||
CLI 命令风险元数据注册表。
|
||||
|
||||
该注册表负责从危险命令规则注册表派生风险元数据,供 TUI、文档、
|
||||
诊断提示等只读场景统一查询。
|
||||
|
||||
:param specs: 按命令名索引的风险元数据表
|
||||
"""
|
||||
|
||||
specs: dict[str, CommandRiskSpec]
|
||||
|
||||
def get_spec(self, command_name: str) -> CommandRiskSpec | None:
|
||||
"""
|
||||
获取指定命令的风险元数据。
|
||||
|
||||
:param command_name: 命令唯一标识
|
||||
:return: 风险元数据,不存在时返回 None
|
||||
"""
|
||||
return self.specs.get(command_name)
|
||||
|
||||
|
||||
class CommandRiskSpecRegistryBuilder:
|
||||
"""
|
||||
CLI 命令风险元数据注册表构建器。
|
||||
|
||||
该构建器负责基于危险命令规则注册表生成命令风险元数据注册表,
|
||||
避免模块导入阶段散落重复的字典推导逻辑。
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def build(rule_registry: DangerousCommandRuleRegistry) -> CommandRiskSpecRegistry:
|
||||
"""
|
||||
基于危险命令规则注册表构建风险元数据注册表。
|
||||
|
||||
:param rule_registry: 危险命令规则注册表
|
||||
:return: 风险元数据注册表
|
||||
"""
|
||||
return CommandRiskSpecRegistry(
|
||||
specs={
|
||||
command_name: CommandRiskSpec(
|
||||
command_name=rule.command_name,
|
||||
risk_level=rule.risk_level,
|
||||
supports_dry_run=rule.supports_dry_run,
|
||||
)
|
||||
for command_name, rule in rule_registry.rules.items()
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
COMMAND_RISK_SPEC_REGISTRY = CommandRiskSpecRegistryBuilder.build(DEFAULT_DANGEROUS_COMMAND_RULE_REGISTRY)
|
||||
Reference in New Issue
Block a user