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

Command exits with non-zero status if changes without migrations exist.
This commit is contained in:
Jon Dufresne 2015-10-20 17:39:48 -07:00 committed by Tim Graham
parent a7bb5af50b
commit 3c7d2ee881
5 changed files with 54 additions and 8 deletions

View File

@ -1,5 +1,6 @@
import os import os
import sys import sys
import warnings
from itertools import takewhile from itertools import takewhile
from django.apps import apps 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.state import ProjectState
from django.db.migrations.writer import MigrationWriter from django.db.migrations.writer import MigrationWriter
from django.utils.deprecation import RemovedInDjango20Warning
from django.utils.six import iteritems from django.utils.six import iteritems
from django.utils.six.moves import zip 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, parser.add_argument('-n', '--name', action='store', dest='name', default=None,
help="Use this name for migration file(s).") help="Use this name for migration file(s).")
parser.add_argument('-e', '--exit', action='store_true', dest='exit_code', default=False, 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): def handle(self, *app_labels, **options):
self.verbosity = options.get('verbosity') self.verbosity = options.get('verbosity')
self.interactive = options.get('interactive') self.interactive = options.get('interactive')
self.dry_run = options.get('dry_run', False) self.dry_run = options.get('dry_run', False)
@ -46,6 +50,13 @@ class Command(BaseCommand):
self.empty = options.get('empty', False) self.empty = options.get('empty', False)
self.migration_name = options.get('name') self.migration_name = options.get('name')
self.exit_code = options.get('exit_code', False) 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 # Make sure the app they asked for exists
app_labels = set(app_labels) app_labels = set(app_labels)
@ -144,10 +155,10 @@ class Command(BaseCommand):
if self.exit_code: if self.exit_code:
sys.exit(1) sys.exit(1)
else: else:
return self.write_migration_files(changes)
if check_changes:
self.write_migration_files(changes) sys.exit(1)
def write_migration_files(self, changes): def write_migration_files(self, changes):
""" """

View File

@ -104,6 +104,11 @@ details on these changes.
``django.template.base.StringOrigin`` aliases for ``django.template.base.StringOrigin`` aliases for
``django.template.base.Origin`` will be removed. ``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: .. _deprecation-removed-in-1.10:
1.10 1.10

View File

@ -699,10 +699,21 @@ of a generated one.
.. django-admin-option:: --exit, -e .. 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 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 when no migrations are created (or would have been created, if combined with
``--dry-run``). ``--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>]] migrate [<app_label> [<migrationname>]]
--------------------------------------- ---------------------------------------

View File

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

View File

@ -9,8 +9,9 @@ from django.apps import apps
from django.core.management import CommandError, call_command from django.core.management import CommandError, call_command
from django.db import DatabaseError, connection, models from django.db import DatabaseError, connection, models
from django.db.migrations.recorder import MigrationRecorder 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 import six
from django.utils.deprecation import RemovedInDjango20Warning
from django.utils.encoding import force_text from django.utils.encoding import force_text
from .models import UnicodeModel, UnserializableModel 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("dependencies=[\n('migrations','0001_%s'),\n]" % migration_name_0001, content)
self.assertIn("operations=[\n]", content) self.assertIn("operations=[\n]", content)
@ignore_warnings(category=RemovedInDjango20Warning)
def test_makemigrations_exit(self): def test_makemigrations_exit(self):
""" """
makemigrations --exit should exit with sys.exit(1) when there are no makemigrations --exit should exit with sys.exit(1) when there are no
@ -995,6 +997,18 @@ class MakeMigrationsTests(MigrationTestBase):
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
call_command("makemigrations", "--exit", "migrations", verbosity=0) 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): class SquashMigrationsTests(MigrationTestBase):
""" """