Skip to content

Commit bc879bc

Browse files
committed
feat: add migrate data and schema options
1 parent 12e92ed commit bc879bc

22 files changed

+604
-84
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,6 @@ cython_debug/
168168
.idea
169169

170170
# Specific project gitignore
171-
migrations
171+
migrations/
172172
.migrations-state.json
173173
settings.py

Dockerfile

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS base
22

3-
COPY pyproject.toml uv.lock README.md ./mpt_tool/
4-
53
WORKDIR /mpt_tool
64

5+
COPY . ./
6+
77
RUN uv venv /opt/venv
88

99
ENV VIRTUAL_ENV=/opt/venv
@@ -13,8 +13,6 @@ FROM base AS build
1313

1414
RUN uv sync --frozen --no-cache --all-groups --active
1515

16-
COPY . .
17-
1816
FROM build AS dev
1917

2018
CMD ["bash"]

makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ build:
2222
$(DC) build
2323

2424
check:
25-
$(DC) run --rm app bash -c "ruff format --check . && ruff check . && flake8 . && uv lock --check"
25+
$(DC) run --rm app bash -c "ruff format --check . && ruff check . && flake8 . && mypy . && uv lock --check"
2626

2727
check-all:
2828
$(MAKE) check
@@ -38,7 +38,7 @@ review:
3838
coderabbit review --prompt-only
3939

4040
run:
41-
$(DC) run --rm -it app bash -c "mpt-tool --help && exec bash"
41+
$(DC) run --rm -it app bash -c "mpt-tool migrate --help && exec bash"
4242

4343
test:
4444
$(DC) run --rm app pytest $(if $(args),$(args),.)

mpt_tool/cli.py

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import datetime as dt
2+
import logging
23
from pathlib import Path
4+
from typing import Annotated
35

46
import typer
57

68
from mpt_tool.constants import MIGRATION_FOLDER
9+
from mpt_tool.enums import MigrationTypeEnum
10+
from mpt_tool.errors import RunMigrationError
711
from mpt_tool.templates import MIGRATION_SCAFFOLDING_TEMPLATE
12+
from mpt_tool.use_cases import RunMigrationsUseCase
813

914
app = typer.Typer(help="MPT CLI - Migration tool for extensions.", no_args_is_help=True)
1015

@@ -15,26 +20,46 @@ def callback() -> None:
1520

1621

1722
@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-
),
23+
def migrate( # noqa: C901, WPS238, WPS210, WPS213, WPS231
24+
data: Annotated[bool, typer.Option("--data", help="Run data migrations.")] = False, # noqa: FBT002
25+
schema: Annotated[bool, typer.Option("--schema", help="Run schema migrations.")] = False, # noqa: FBT002
26+
new_data: Annotated[
27+
str | None,
28+
typer.Option(
29+
"--new-data",
30+
metavar="FILENAME",
31+
help="Scaffold a new data migration script with the provided filename.",
32+
),
33+
] = None,
34+
new_schema: Annotated[
35+
str | None,
36+
typer.Option(
37+
"--new-schema",
38+
metavar="FILENAME",
39+
help="Scaffold a new schema migration script with the provided filename.",
40+
),
41+
] = None,
3142
) -> None:
3243
"""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-
)
44+
options = sum([bool(data), bool(schema), bool(new_data), bool(new_schema)]) # noqa: WPS221
45+
if options > 1:
46+
raise typer.BadParameter("Only one option can be used.", param_hint="migrate")
47+
if not options:
48+
raise typer.BadParameter("At least one option must be used.", param_hint="migrate")
49+
50+
if data or schema:
51+
migration_type = MigrationTypeEnum.DATA if data else MigrationTypeEnum.SCHEMA
52+
typer.echo(f"Running {migration_type} migrations...")
53+
54+
run_migration = RunMigrationsUseCase()
55+
try:
56+
run_migration.execute(migration_type)
57+
except RunMigrationError as error:
58+
typer.secho(f"Error running migrations: {error!s}", fg=typer.colors.RED)
59+
raise typer.Abort
60+
61+
typer.secho("Migrations completed successfully.", fg=typer.colors.GREEN)
62+
return
3863

3964
if new_schema or new_data:
4065
filename_suffix = new_data or new_schema
@@ -58,11 +83,9 @@ def migrate(
5883
),
5984
)
6085
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)
6486

6587

6688
def main() -> None:
6789
"""Entry point for the CLI."""
90+
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
6891
app()

mpt_tool/commands/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
from mpt_tool.commands.base import DataBaseCommand, SchemaBaseCommand
1+
from mpt_tool.commands.data_base import DataBaseCommand
2+
from mpt_tool.commands.schema_base import SchemaBaseCommand
23

34
__all__ = ["DataBaseCommand", "SchemaBaseCommand"]

mpt_tool/commands/base.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1+
import logging
12
from abc import ABC, abstractmethod
23

3-
from mpt_tool.commands.enums import MigrationTypeEnum
4+
from mpt_tool.enums import MigrationTypeEnum
5+
6+
logger = logging.getLogger(__name__)
47

58

69
class BaseCommand(ABC):
710
"""Abstract base class for all migration commands."""
811

12+
_type: MigrationTypeEnum
13+
14+
def __init__(self):
15+
self.log = logger
16+
17+
@property
18+
def type(self) -> MigrationTypeEnum:
19+
"""The type of migration this command represents."""
20+
return self._type
21+
922
@abstractmethod
1023
def run(self) -> None:
1124
"""Executes the command."""
1225
raise NotImplementedError
13-
14-
15-
class DataBaseCommand(BaseCommand, ABC):
16-
"""Base command for data migrations."""
17-
18-
_type = MigrationTypeEnum.DATA
19-
20-
21-
class SchemaBaseCommand(BaseCommand, ABC):
22-
"""Base command for schema migrations."""
23-
24-
_type = MigrationTypeEnum.SCHEMA

mpt_tool/commands/data_base.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from abc import ABC
2+
3+
from mpt_tool.commands.base import BaseCommand
4+
from mpt_tool.enums import MigrationTypeEnum
5+
6+
7+
class DataBaseCommand(BaseCommand, ABC):
8+
"""Base command for data migrations."""
9+
10+
_type = MigrationTypeEnum.DATA

mpt_tool/commands/schema_base.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from abc import ABC
2+
3+
from mpt_tool.commands.base import BaseCommand
4+
from mpt_tool.enums import MigrationTypeEnum
5+
6+
7+
class SchemaBaseCommand(BaseCommand, ABC):
8+
"""Base command for schema migrations."""
9+
10+
_type = MigrationTypeEnum.SCHEMA

mpt_tool/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
MIGRATION_FOLDER: str = "migrations"
2+
MIGRATION_STATE_FILE: str = ".migrations-state.json"

0 commit comments

Comments
 (0)