浏览代码

Fixed #25604 -- Added makemigrations --check option.

Command exits with non-zero status if changes without migrations exist.
Jon Dufresne 9 年之前
父节点
当前提交
3c7d2ee881

+ 17 - 6
django/core/management/commands/makemigrations.py

@@ -1,5 +1,6 @@
 import os
 import sys
+import warnings
 from itertools import takewhile
 
 from django.apps import apps
@@ -13,6 +14,7 @@ from django.db.migrations.questioner import (
 )
 from django.db.migrations.state import ProjectState
 from django.db.migrations.writer import MigrationWriter
+from django.utils.deprecation import RemovedInDjango20Warning
 from django.utils.six import iteritems
 from django.utils.six.moves import zip
 
@@ -35,10 +37,12 @@ class Command(BaseCommand):
         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.')
+            help='Exit with error code 1 if no changes needing migrations are found. '
+            'Deprecated, use the --check option instead.')
+        parser.add_argument('--check', action='store_true', dest='check_changes',
+            help='Exit with a non-zero status if model changes are missing migrations.')
 
     def handle(self, *app_labels, **options):
-
         self.verbosity = options.get('verbosity')
         self.interactive = options.get('interactive')
         self.dry_run = options.get('dry_run', False)
@@ -46,6 +50,13 @@ class Command(BaseCommand):
         self.empty = options.get('empty', False)
         self.migration_name = options.get('name')
         self.exit_code = options.get('exit_code', False)
+        check_changes = options['check_changes']
+
+        if self.exit_code:
+            warnings.warn(
+                "The --exit option is deprecated in favor of the --check option.",
+                RemovedInDjango20Warning
+            )
 
         # Make sure the app they asked for exists
         app_labels = set(app_labels)
@@ -144,10 +155,10 @@ class Command(BaseCommand):
 
             if self.exit_code:
                 sys.exit(1)
-            else:
-                return
-
-        self.write_migration_files(changes)
+        else:
+            self.write_migration_files(changes)
+            if check_changes:
+                sys.exit(1)
 
     def write_migration_files(self, changes):
         """

+ 5 - 0
docs/internals/deprecation.txt

@@ -104,6 +104,11 @@ details on these changes.
   ``django.template.base.StringOrigin`` aliases for
   ``django.template.base.Origin`` will be removed.
 
+See the :ref:`Django 1.10 release notes <deprecated-features-1.10>` for more
+details on these changes.
+
+* The ``makemigrations --exit`` option will be removed.
+
 .. _deprecation-removed-in-1.10:
 
 1.10

+ 11 - 0
docs/ref/django-admin.txt

@@ -699,10 +699,21 @@ of a generated one.
 
 .. django-admin-option:: --exit, -e
 
+.. deprecated:: 1.10
+
+   Use the :djadminopt:`--check` option instead.
+
 The ``--exit`` option will cause ``makemigrations`` to exit with error code 1
 when no migrations are created (or would have been created, if combined with
 ``--dry-run``).
 
+.. django-admin-option:: --check
+
+.. versionadded:: 1.10
+
+The ``--check`` option makes ``makemigrations`` exit with a non-zero status
+when model changes without migrations are detected.
+
 migrate [<app_label> [<migrationname>]]
 ---------------------------------------
 

+ 6 - 1
docs/releases/1.10.txt

@@ -157,6 +157,10 @@ Management Commands
   allows specifying the message level that will cause the command to exit with
   a non-zero status.
 
+* The new :djadminopt:`makemigrations --check <--check>` option makes the
+  command exit with a non-zero status when model changes without migrations are
+  detected.
+
 Migrations
 ^^^^^^^^^^
 
@@ -268,7 +272,8 @@ Features deprecated in 1.10
 Miscellaneous
 ~~~~~~~~~~~~~
 
-* ...
+* The ``makemigrations --exit`` option is deprecated in favor of the
+  :djadminopt:`--check` option.
 
 .. _removed-features-1.10:
 

+ 15 - 1
tests/migrations/test_commands.py

@@ -9,8 +9,9 @@ from django.apps import apps
 from django.core.management import CommandError, call_command
 from django.db import DatabaseError, connection, models
 from django.db.migrations.recorder import MigrationRecorder
-from django.test import mock, override_settings
+from django.test import ignore_warnings, mock, override_settings
 from django.utils import six
+from django.utils.deprecation import RemovedInDjango20Warning
 from django.utils.encoding import force_text
 
 from .models import UnicodeModel, UnserializableModel
@@ -983,6 +984,7 @@ class MakeMigrationsTests(MigrationTestBase):
             self.assertIn("dependencies=[\n('migrations','0001_%s'),\n]" % migration_name_0001, content)
             self.assertIn("operations=[\n]", content)
 
+    @ignore_warnings(category=RemovedInDjango20Warning)
     def test_makemigrations_exit(self):
         """
         makemigrations --exit should exit with sys.exit(1) when there are no
@@ -995,6 +997,18 @@ class MakeMigrationsTests(MigrationTestBase):
             with self.assertRaises(SystemExit):
                 call_command("makemigrations", "--exit", "migrations", verbosity=0)
 
+    def test_makemigrations_check(self):
+        """
+        makemigrations --check should exit with a non-zero status when
+        there are changes to an app requiring migrations.
+        """
+        with self.temporary_migration_module():
+            with self.assertRaises(SystemExit):
+                call_command("makemigrations", "--check", "migrations", verbosity=0)
+
+        with self.temporary_migration_module(module="migrations.test_migrations_no_changes"):
+            call_command("makemigrations", "--check", "migrations", verbosity=0)
+
 
 class SquashMigrationsTests(MigrationTestBase):
     """