From deb607648ed7d484a90474b6da48642b4f39bca7 Mon Sep 17 00:00:00 2001 From: Tim Heap Date: Tue, 11 Nov 2014 15:41:55 +1100 Subject: [PATCH] Fixed #23728 -- Added the --exit option to makemigrations. If no changes that need migrations are found, `makemigrations --exit` exits with error code 1. --- AUTHORS | 1 + .../management/commands/makemigrations.py | 24 ++++++++++++------- docs/ref/django-admin.txt | 8 +++++++ docs/releases/1.8.txt | 3 +++ tests/migrations/test_commands.py | 12 ++++++++++ 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/AUTHORS b/AUTHORS index dd78347071..8d344d4241 100644 --- a/AUTHORS +++ b/AUTHORS @@ -649,6 +649,7 @@ answer newbie questions, and generally made Django that much better: Thomas Stromberg tibimicu@gmx.net Tim Graham + Tim Heap Tim Saylor Tobias McNulty tobias@neuyork.de diff --git a/django/core/management/commands/makemigrations.py b/django/core/management/commands/makemigrations.py index bc684f42b7..bc78ff5f84 100644 --- a/django/core/management/commands/makemigrations.py +++ b/django/core/management/commands/makemigrations.py @@ -30,6 +30,8 @@ class Command(BaseCommand): help='Tells Django to NOT prompt the user for input of any kind.') parser.add_argument('-n', '--name', action='store', dest='name', default=None, help="Use this name for migration file(s).") + parser.add_argument('-e', '--exit', action='store_true', dest='exit_code', default=False, + help='Exit with error code 1 if no changes needing migrations are found.') def handle(self, *app_labels, **options): @@ -39,6 +41,7 @@ class Command(BaseCommand): self.merge = options.get('merge', False) self.empty = options.get('empty', False) self.migration_name = options.get('name', None) + self.exit_code = options.get('exit_code', False) # Make sure the app they asked for exists app_labels = set(app_labels) @@ -120,15 +123,20 @@ class Command(BaseCommand): migration_name=self.migration_name, ) - # No changes? Tell them. - if not changes and self.verbosity >= 1: - if len(app_labels) == 1: - self.stdout.write("No changes detected in app '%s'" % app_labels.pop()) - elif len(app_labels) > 1: - self.stdout.write("No changes detected in apps '%s'" % ("', '".join(app_labels))) + if not changes: + # No changes? Tell them. + if self.verbosity >= 1: + if len(app_labels) == 1: + self.stdout.write("No changes detected in app '%s'" % app_labels.pop()) + elif len(app_labels) > 1: + self.stdout.write("No changes detected in apps '%s'" % ("', '".join(app_labels))) + else: + self.stdout.write("No changes detected") + + if self.exit_code: + sys.exit(1) else: - self.stdout.write("No changes detected") - return + return self.write_migration_files(changes) diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt index 07f7093634..85864d78b8 100644 --- a/docs/ref/django-admin.txt +++ b/docs/ref/django-admin.txt @@ -719,6 +719,14 @@ a merge. The ``--name`` option allows you to give the migration(s) a custom name instead of a generated one. +.. django-admin-option:: --exit, -e + +.. versionadded:: 1.8 + +The ``--exit`` option will cause ``makemigrations`` to exit with error code 1 +when no migration are created (or would have been created, if combined with +``--dry-run``). + migrate [ []] --------------------------------------- diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index 5df0cc1bd1..8f4053168d 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -333,6 +333,9 @@ Management Commands :setting:`FIXTURE_DIRS` contains duplicates or a default fixture directory path (``app_name/fixtures``), an exception is raised. +* :djadmin:`makemigrations` now supports an :djadminopt:`--exit` option to + exit with an error code if no migrations are created. + Middleware ^^^^^^^^^^ diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index ddbcfb343a..5995468e98 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -543,6 +543,18 @@ class MakeMigrationsTests(MigrationTestBase): self.assertIn("dependencies=[\n('migrations','0001_%s'),\n]" % migration_name_0001, content) self.assertIn("operations=[\n]", content) + def test_makemigrations_exit(self): + """ + makemigrations --exit should exit with sys.exit(1) when there are no + changes to an app. + """ + with self.settings(MIGRATION_MODULES={"migrations": self.migration_pkg}): + call_command("makemigrations", "--exit", "migrations", verbosity=0) + + with self.settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_changes"}): + with self.assertRaises(SystemExit): + call_command("makemigrations", "--exit", "migrations", verbosity=0) + class SquashMigrationsTest(MigrationTestBase): """