def test___init__(self, scripts_dir): with pytest.raises(AmbixError) as err_info: MigrationHome(home_path=pathlib.Path("/not/a/valid/path")) assert "doesn't exist" in str(err_info.value) home = MigrationHome(scripts_dir) # Starting graph should look like this: # ....................... # . . # . aaaaaa . # . | . # . bbbbbb . # . / \ . # . / \ . # . ccccc dddddd . # . \ / \ . # . \ / \ . # . eeeee ffffff . # . \ / . # . \ / . # . gggggg . # . . # ....................... assert home.home_path == scripts_dir assert sorted([s for s in home.migrations]) == [ "aaaaaa", "bbbbbb", "cccccc", "dddddd", "eeeeee", "ffffff", "gggggg", ]
def test_rebase__normal_rebase(self, scripts_dir): home = MigrationHome(scripts_dir) home.migrations["gggggg"].change_down_revision("cccccc") home.migrations["eeeeee"].change_down_revision("dddddd") # now, the graph should look like this: # ....................... # . . # . aaaaaa . # . | . # . bbbbbb . # . / \ . # . / \ . # . ccccc dddddd . # . | / \ . # . | / \ . # . | eeeee ffffff . # . | . # . gggggg . # . . # . . # ....................... home.rebase("dddddd", "gggggg") assert home.generate_dependency_graph() == { "aaaaaa": {None}, "bbbbbb": {"aaaaaa"}, "cccccc": {"bbbbbb"}, "dddddd": {"gggggg"}, "eeeeee": {"dddddd"}, "ffffff": {"dddddd"}, "gggggg": {"cccccc"}, }
def flatten( alembic_home_dir: pathlib.Path = typer.Option( "etc/alembic/versions", exists=True, help="The directory where the alembic migrations live", ), ): home = MigrationHome(alembic_home_dir) home.flatten()
def test_generate_dependency_graph(self, scripts_dir): home = MigrationHome(scripts_dir) assert home.generate_dependency_graph() == { "aaaaaa": {None}, "bbbbbb": {"aaaaaa"}, "cccccc": {"bbbbbb"}, "dddddd": {"bbbbbb"}, "eeeeee": {"cccccc", "dddddd"}, "ffffff": {"dddddd"}, "gggggg": {"eeeeee", "ffffff"}, }
def test_move__multiple_new_base(self, scripts_dir): home = MigrationHome(scripts_dir) home.move("eeeeee", "ffffff", "dddddd") assert home.generate_dependency_graph() == { "aaaaaa": {None}, "bbbbbb": {"aaaaaa"}, "cccccc": {"bbbbbb"}, "dddddd": {"bbbbbb"}, "ffffff": {"dddddd"}, "gggggg": {"ffffff", "cccccc", "dddddd"}, "eeeeee": {"ffffff", "dddddd"}, }
def prune( revision: str = typer.Argument( ..., help="The revision hash to be moved", ), alembic_home_dir: pathlib.Path = typer.Option( "etc/alembic/versions", exists=True, help="The directory where the alembic migrations live", ), ): home = MigrationHome(alembic_home_dir) home.prune(revision)
def test_prune__delete_head(self, scripts_dir): home = MigrationHome(scripts_dir) assert scripts_dir.joinpath("gggggg-dummy-migration.py").exists() home.prune("gggggg") assert home.generate_dependency_graph() == { "aaaaaa": {None}, "bbbbbb": {"aaaaaa"}, "cccccc": {"bbbbbb"}, "dddddd": {"bbbbbb"}, "eeeeee": {"cccccc", "dddddd"}, "ffffff": {"dddddd"}, } assert not scripts_dir.joinpath("gggggg-dummy-migration.py").exists()
def test_prune__delete_complex_branch(self, scripts_dir): home = MigrationHome(scripts_dir) assert os.path.exists( os.path.join(scripts_dir, "dddddd-dummy-migration.py")) home.prune("dddddd") assert home.generate_dependency_graph() == { "aaaaaa": {None}, "bbbbbb": {"aaaaaa"}, "cccccc": {"bbbbbb"}, "eeeeee": {"bbbbbb", "cccccc"}, "ffffff": {"bbbbbb"}, "gggggg": {"eeeeee", "ffffff"}, } assert not os.path.exists( os.path.join(scripts_dir, "dddddd-dummy-migration.py"))
def test_ancestors(self, scripts_dir): home = MigrationHome(scripts_dir) assert list(home.ancestors("eeeeee")) == [ "aaaaaa", "bbbbbb", "cccccc", "dddddd", ] assert list(home.ancestors("eeeeee")) == [ "aaaaaa", "bbbbbb", "cccccc", "dddddd", ]
def render( alembic_home_dir: pathlib.Path = typer.Option( "etc/alembic/versions", exists=True, help="The directory where the alembic migrations live", ), ): home = MigrationHome(alembic_home_dir) graph = home.generate_dependency_graph() print("strict digraph {") for (key, value) in graph.items(): for child in value: if child is None: continue print(f" {key} -> {child}") print("}")
def move( revision: str = typer.Argument( ..., help="The revision hash to be moved", ), new_bases: typing.List[str] = typer.Argument( ..., help="The new base(s) to base the revision upon", ), alembic_home_dir: pathlib.Path = typer.Option( "etc/alembic/versions", exists=True, help="The directory where the alembic migrations live", ), ): home = MigrationHome(alembic_home_dir) home.move(revision, *new_bases)
def test_rebase__fails_if_new_ancestry_is_incoherent(self, scripts_dir): home = MigrationHome(scripts_dir) with pytest.raises(AmbixError, match="Cannot rebase"): home.rebase("dddddd", "gggggg")
def test_heads(self, scripts_dir): home = MigrationHome(scripts_dir) assert home.heads() == {"gggggg"} home.prune("gggggg") assert home.heads() == {"eeeeee", "ffffff"}