from dataclasses import dataclass from cli.context import CliContext, OutputOption from cli.wizard.base import BaseCliWizardFlow @dataclass(frozen=True) class DbUpgradeWizardSelection: """ `wizard db-upgrade` 向导采集结果。 :param env: 运行环境 :param revision: 目标迁移版本 :param dry_run: 是否演练执行 :param allow_prod: 是否允许生产环境执行 """ env: str revision: str dry_run: bool allow_prod: bool class DbUpgradeWizardFlow(BaseCliWizardFlow[DbUpgradeWizardSelection]): """ `wizard db-upgrade` 向导流程。 :param default_env: 默认环境 :param default_revision: 默认目标 revision :param default_dry_run: 默认是否先执行 dry-run """ wizard_name = 'wizard db-upgrade' preview_title = 'wizard db-upgrade preview' failure_message = '数据库升级向导执行失败' def __init__( self, *, default_env: str = 'dev', default_revision: str = 'head', default_dry_run: bool = True, ) -> None: """ 初始化数据库升级向导流程。 :param default_env: 默认环境 :param default_revision: 默认目标 revision :param default_dry_run: 默认是否先执行 dry-run :return: None """ self.default_env = default_env self.default_revision = default_revision self.default_dry_run = default_dry_run def collect_selection(self) -> DbUpgradeWizardSelection: """ 采集数据库升级向导参数。 :return: 向导采集结果 """ env = self.prompt_service.prompt_env(self.default_env) revision = self.prompt_service.prompt_required_text('目标迁移版本', self.default_revision) dry_run = self.prompt_service.prompt_confirm('是否先执行 dry-run 预演', default_value=self.default_dry_run) allow_prod = ( self.prompt_service.prompt_confirm('当前为 prod 环境,是否允许继续执行', default_value=False) if env == 'prod' else False ) return DbUpgradeWizardSelection(env=env, revision=revision, dry_run=dry_run, allow_prod=allow_prod) def prepare_context(self, selection: DbUpgradeWizardSelection, output: OutputOption) -> CliContext: """ 构建数据库升级向导上下文。 :param selection: 向导采集结果 :param output: 输出格式 :return: CLI 上下文 """ return self.build_regular_context( selection.env, output, allow_prod=selection.allow_prod, yes=True, dry_run=selection.dry_run, ) def build_preview_summary(self, selection: DbUpgradeWizardSelection) -> dict[str, str]: """ 构建数据库升级预览摘要。 :param selection: 向导采集结果 :return: 预览摘要 """ return { 'env': selection.env, 'revision': selection.revision, 'dry_run': str(selection.dry_run).lower(), 'allow_prod': str(selection.allow_prod).lower(), } def build_preview_command(self, selection: DbUpgradeWizardSelection) -> list[str]: """ 构建数据库升级预览命令。 :param selection: 向导采集结果 :return: 用户视角命令参数 """ command = ['shierfeng', 'db', 'upgrade', f'--env={selection.env}', f'--revision={selection.revision}'] if selection.dry_run: command.append('--dry-run') if selection.allow_prod: command.append('--allow-prod') return command def confirm_prompt(self, selection: DbUpgradeWizardSelection) -> str: """ 返回数据库升级最终确认提示。 :param selection: 向导采集结果 :return: 确认提示 """ del selection return '确认执行数据库升级向导吗' def build_execute_arguments(self, selection: DbUpgradeWizardSelection, output: OutputOption) -> list[str]: """ 构建数据库升级内部 CLI 参数。 :param selection: 向导采集结果 :param output: 输出格式 :return: 内部 CLI 参数 """ arguments = [ 'db', 'upgrade', f'--env={selection.env}', f'--output={output}', f'--revision={selection.revision}', '--yes', ] if selection.dry_run: arguments.append('--dry-run') if selection.allow_prod: arguments.append('--allow-prod') return arguments def run_db_upgrade_wizard( output: OutputOption = 'text', *, default_env: str = 'dev', default_revision: str = 'head', default_dry_run: bool = True, ) -> None: """ 执行 `wizard db-upgrade` 向导。 :param output: 输出格式 :param default_env: 默认环境 :param default_revision: 默认目标 revision :param default_dry_run: 默认是否先 dry-run :return: None """ DbUpgradeWizardFlow( default_env=default_env, default_revision=default_revision, default_dry_run=default_dry_run, ).run(output)