|
| 1 | +import datetime as dt |
1 | 2 | from pathlib import Path |
2 | 3 |
|
3 | 4 | import typer |
4 | 5 |
|
5 | | -app = typer.Typer(help="MPT CLI - Migration tool for extensions.", no_args_is_help=True) |
6 | | - |
7 | | - |
8 | | -@app.command() |
9 | | -def init() -> None: |
10 | | - """Initialize the migrations tool workspace.""" |
11 | | - root = Path.cwd() |
12 | | - |
13 | | - settings_file = root / "settings.py" |
14 | | - if not settings_file.exists(): |
15 | | - typer.secho("Settings file does not exist.", fg=typer.colors.RED) |
16 | | - raise typer.Exit(code=1) |
17 | | - |
18 | | - migrations_dir = root / "migrations" |
19 | | - if migrations_dir.exists(): |
20 | | - typer.secho("Migrations folder already exists.", fg=typer.colors.RED) |
21 | | - raise typer.Exit(code=1) |
| 6 | +from mpt_tool.constants import MIGRATION_FOLDER |
| 7 | +from mpt_tool.templates import MIGRATION_SCAFFOLDING_TEMPLATE |
22 | 8 |
|
23 | | - migrations_dir.mkdir(exist_ok=True) |
24 | | - |
25 | | - init_file = migrations_dir / "__init__.py" |
26 | | - init_file.touch(exist_ok=True) |
27 | | - |
28 | | - state_file = root / ".migrations-state.json" |
29 | | - if state_file.exists(): |
30 | | - typer.secho("State file already exists.", fg=typer.colors.RED) |
31 | | - raise typer.Exit(code=1) |
32 | | - |
33 | | - if not state_file.exists(): |
34 | | - state_file.write_text("{}\n") |
| 9 | +app = typer.Typer(help="MPT CLI - Migration tool for extensions.", no_args_is_help=True) |
35 | 10 |
|
36 | 11 |
|
37 | 12 | @app.callback() |
38 | 13 | def callback() -> None: |
39 | 14 | """MPT CLI - Migration tool for extensions.""" |
40 | 15 |
|
41 | 16 |
|
42 | | -@app.command() |
43 | | -def migrate() -> None: |
44 | | - """Run the migration process.""" |
45 | | - typer.echo("Hello World!") |
| 17 | +@app.command("migrate") |
| 18 | +def migrate( |
| 19 | + new_data: str | None = typer.Option( # noqa: WPS404 |
| 20 | + None, |
| 21 | + "--new-data", |
| 22 | + metavar="FILENAME", |
| 23 | + help="Scaffold a new data migration script with the provided filename.", |
| 24 | + ), |
| 25 | + new_schema: str | None = typer.Option( # noqa: WPS404 |
| 26 | + None, |
| 27 | + "--new-schema", |
| 28 | + metavar="FILENAME", |
| 29 | + help="Scaffold a new schema migration script with the provided filename.", |
| 30 | + ), |
| 31 | +) -> None: |
| 32 | + """Migrate command.""" |
| 33 | + if new_data and new_schema: |
| 34 | + raise typer.BadParameter( |
| 35 | + "Options --new-data and --new-schema cannot be combined.", |
| 36 | + param_hint="migrate", |
| 37 | + ) |
| 38 | + |
| 39 | + if new_schema or new_data: |
| 40 | + filename_suffix = new_data or new_schema |
| 41 | + typer.echo(f"Scaffolding migration: {filename_suffix}.") |
| 42 | + migration_folder = Path(MIGRATION_FOLDER) |
| 43 | + migration_folder.mkdir(parents=True, exist_ok=True) |
| 44 | + timestamp = dt.datetime.now(tz=dt.UTC).strftime("%Y%m%d%H%M%S") |
| 45 | + # TODO: add filename validation |
| 46 | + filename = f"{timestamp}_{filename_suffix}.py" |
| 47 | + full_filename_path = migration_folder / filename |
| 48 | + try: |
| 49 | + full_filename_path.touch(exist_ok=False) |
| 50 | + except FileExistsError: |
| 51 | + typer.secho(f"File already exists: {filename}", fg=typer.colors.RED) |
| 52 | + raise typer.Abort |
| 53 | + |
| 54 | + full_filename_path.write_text( |
| 55 | + encoding="utf-8", |
| 56 | + data=MIGRATION_SCAFFOLDING_TEMPLATE.substitute( |
| 57 | + command_name="DataBaseCommand" if new_data else "SchemaBaseCommand" |
| 58 | + ), |
| 59 | + ) |
| 60 | + typer.secho(f"Migration file: {filename} has been created.", fg=typer.colors.GREEN) |
| 61 | + return |
| 62 | + |
| 63 | + typer.secho("Running migrations is not implemented yet.", fg=typer.colors.YELLOW) |
46 | 64 |
|
47 | 65 |
|
48 | 66 | def main() -> None: |
|
0 commit comments