from __future__ import annotations import importlib.resources import shutil from pathlib import Path import click @click.group() def iti_system_cli() -> None: """iTi-System commands.""" @iti_system_cli.group() def seed() -> None: """Seed system-domain data.""" @seed.command("system") def seed_system() -> None: from flask import current_app from iti.modules import get_module_registry from .seeds.system import seed_system_data summary = seed_system_data(get_module_registry(current_app)) for name, result in summary.items(): click.echo( f"{name}: created {result['created']}, updated {result['updated']}, skipped {result['skipped']}" ) @iti_system_cli.group() def migrations() -> None: """System migration helpers.""" @migrations.command("sync") @click.option( "--target", default="migrations/versions", show_default=True, help="业务项目 migration versions 目录", ) def sync_migrations(target: str) -> None: """同步系统迁移到当前项目 migration 流。""" target_dir = Path(target) target_dir.mkdir(parents=True, exist_ok=True) synced: list[str] = [] skipped: list[str] = [] source_root = importlib.resources.files("iti_system.migrations").joinpath( "versions" ) for source in source_root.iterdir(): if not source.name.endswith(".py") or source.name == "__init__.py": continue target_file = target_dir / source.name if target_file.exists(): skipped.append(source.name) continue with importlib.resources.as_file(source) as source_path: shutil.copy2(source_path, target_file) synced.append(source.name) for name in synced: click.echo(f"synced: {name}") for name in skipped: click.echo(f"skipped: {name}") click.echo(f"summary: synced {len(synced)}, skipped {len(skipped)}")