From d410c2eaf0e48cbac9d049a6082f08dde717adb4 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Fri, 6 Aug 2021 14:07:57 +0100 Subject: [PATCH] Add create-max-migration-files --recreate (#99) Fixes #79. --- HISTORY.rst | 5 +++++ README.rst | 17 +++++++++++++- .../commands/create-max-migration-files.py | 18 ++++++++++----- tests/test_create_max_migration_files.py | 22 +++++++++++++++++++ 4 files changed, 55 insertions(+), 7 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 67469cb..b91210d 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -2,6 +2,11 @@ History ======= +* Added ``--recreate`` flag to ``create-max-migration-files``. + + Thanks to Gordon Wrigley for the feature request in `Issue #79 + `__. + 1.6.0 (2021-04-08) ------------------ diff --git a/README.rst b/README.rst index 2fa198b..3636ce2 100644 --- a/README.rst +++ b/README.rst @@ -96,7 +96,7 @@ If you see any apps listed that *aren’t* part of your project, define the list python manage.py create-max-migration-files In the future, when you add a new app to your project, you’ll need to create its ``max_migration.txt`` file. -If you defined ``FIRST_PARTY_APPS``, add it there, then rerun the creation command for the new app by specifying its label: +Add the new app to ``INSTALLED_APPS`` or ``FIRST_PARTY_APPS`` as appropriate, then rerun the creation command for the new app by specifying its label: .. code-block:: sh @@ -123,6 +123,21 @@ These are: * ``dlm.E003``: ````'s max_migration.txt points to non-existent migration '````'. * ``dlm.E004``: ````'s max_migration.txt contains '````', but the latest migration is '````'. +``create-max-migration-files`` command +-------------------------------------- + +.. code-block:: sh + + python manage.py create-max-migration-files [app_label [app_label ...]] + +This management command creates ``max_migration.txt`` files for all first party apps, or the given labels. +It’s used in initial installation of django-linear-migrations, and for recreating. + +Pass the ``--dry-run`` flag to only list the ``max_migration.txt`` files that would be created. + +Pass the ``--recreate`` flag to re-create files that already exist. +This may be useful after altering migrations with merges or manually. + ``rebase-migration`` command ---------------------------- diff --git a/src/django_linear_migrations/management/commands/create-max-migration-files.py b/src/django_linear_migrations/management/commands/create-max-migration-files.py index cf92ac6..9e9d4bd 100644 --- a/src/django_linear_migrations/management/commands/create-max-migration-files.py +++ b/src/django_linear_migrations/management/commands/create-max-migration-files.py @@ -8,10 +8,7 @@ class Command(BaseCommand): - help = ( - "Generate max_migration.txt files for first-party apps that don't" - + " have one." - ) + help = "Generate max_migration.txt files for first-party apps." # Checks disabled because the django-linear-migrations' checks would # prevent us continuing @@ -33,8 +30,17 @@ def add_arguments(self, parser): default=False, help="Actually create the files.", ) + parser.add_argument( + "--recreate", + action="store_true", + default=False, + help=( + "Recreate existing files. By default only non-existing files" + + " will be created." + ), + ) - def handle(self, *app_labels, dry_run, **options): + def handle(self, *app_labels, dry_run, recreate, **options): # Copied check from makemigrations app_labels = set(app_labels) has_bad_labels = False @@ -57,7 +63,7 @@ def handle(self, *app_labels, dry_run, **options): continue max_migration_txt = migration_details.dir / "max_migration.txt" - if not max_migration_txt.exists(): + if recreate or not max_migration_txt.exists(): if not dry_run: max_migration_name = max(migration_details.names) max_migration_txt.write_text(max_migration_name + "\n") diff --git a/tests/test_create_max_migration_files.py b/tests/test_create_max_migration_files.py index 19dbcb3..671dedc 100644 --- a/tests/test_create_max_migration_files.py +++ b/tests/test_create_max_migration_files.py @@ -114,6 +114,28 @@ def test_success_already_exists(self): assert err == "" assert returncode == 0 + def test_success_recreate(self): + (self.migrations_dir / "__init__.py").touch() + (self.migrations_dir / "0001_initial.py").touch() + (self.migrations_dir / "max_migration.txt").write_text("0001_initial\n") + + out, err, returncode = self.call_command("--recreate") + + assert out == "Created max_migration.txt for testapp.\n" + assert err == "" + assert returncode == 0 + + def test_success_recreate_dry_run(self): + (self.migrations_dir / "__init__.py").touch() + (self.migrations_dir / "0001_initial.py").touch() + (self.migrations_dir / "max_migration.txt").write_text("0001_initial\n") + + out, err, returncode = self.call_command("--recreate", "--dry-run") + + assert out == "Would create max_migration.txt for testapp.\n" + assert err == "" + assert returncode == 0 + def test_success_specific_app_label(self): (self.migrations_dir / "__init__.py").touch() (self.migrations_dir / "0001_initial.py").touch()