[1.7.x] Fixed #22862 -- Added --noinput option to makemigrations.

Thanks artortenburger for the report.

Backport of fbb684d95e from master
This commit is contained in:
Huu Nguyen 2014-06-19 16:50:01 -07:00 committed by Tim Graham
parent 0b871ec22a
commit d9a83d597e
3 changed files with 37 additions and 16 deletions

View File

@ -22,6 +22,8 @@ class Command(BaseCommand):
help="Enable fixing of migration conflicts."), help="Enable fixing of migration conflicts."),
make_option('--empty', action='store_true', dest='empty', default=False, make_option('--empty', action='store_true', dest='empty', default=False,
help="Create an empty migration."), help="Create an empty migration."),
make_option('--noinput', action='store_false', dest='interactive', default=True,
help='Tells Django to NOT prompt the user for input of any kind.'),
) )
help = "Creates new migration(s) for apps." help = "Creates new migration(s) for apps."
@ -156,7 +158,7 @@ class Command(BaseCommand):
if self.interactive: if self.interactive:
questioner = InteractiveMigrationQuestioner() questioner = InteractiveMigrationQuestioner()
else: else:
questioner = MigrationQuestioner() questioner = MigrationQuestioner(defaults={'ask_merge': True})
for app_label, migration_names in conflicts.items(): for app_label, migration_names in conflicts.items():
# Grab out the migrations in question, and work out their # Grab out the migrations in question, and work out their
# common ancestor. # common ancestor.

View File

@ -642,6 +642,8 @@ Providing one or more app names as arguments will limit the migrations created
to the app(s) specified and any dependencies needed (the table at the other end to the app(s) specified and any dependencies needed (the table at the other end
of a ``ForeignKey``, for example). of a ``ForeignKey``, for example).
The :djadminopt:`--noinput` option may be provided to suppress all user prompts.
.. django-admin-option:: --empty .. django-admin-option:: --empty
The ``--empty`` option will cause ``makemigrations`` to output an empty The ``--empty`` option will cause ``makemigrations`` to output an empty

View File

@ -231,19 +231,6 @@ class MakeMigrationsTests(MigrationTestBase):
with self.assertRaises(CommandError): with self.assertRaises(CommandError):
call_command("makemigrations") call_command("makemigrations")
@override_system_checks([])
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_conflict"})
def test_makemigrations_merge_basic(self):
"""
Makes sure that makemigrations doesn't error if you ask for
merge mode with a conflict present. Doesn't test writing of the merge
file, as that requires temp directories.
"""
try:
call_command("makemigrations", merge=True, verbosity=0)
except CommandError:
self.fail("Makemigrations errored in merge mode with conflicts")
@override_system_checks([]) @override_system_checks([])
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"}) @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"})
def test_makemigrations_merge_no_conflict(self): def test_makemigrations_merge_no_conflict(self):
@ -386,13 +373,18 @@ class MakeMigrationsTests(MigrationTestBase):
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_conflict"}) @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_conflict"})
def test_makemigrations_handle_merge(self): def test_makemigrations_handle_merge(self):
""" """
Makes sure that makemigrations properly merges the conflicting migrations. Makes sure that makemigrations properly merges the conflicting migrations with --noinput.
""" """
stdout = six.StringIO() stdout = six.StringIO()
call_command("makemigrations", "migrations", merge=True, stdout=stdout) call_command("makemigrations", "migrations", merge=True, interactive=False, stdout=stdout)
self.assertIn("Merging migrations", stdout.getvalue()) self.assertIn("Merging migrations", stdout.getvalue())
self.assertIn("Branch 0002_second", stdout.getvalue()) self.assertIn("Branch 0002_second", stdout.getvalue())
self.assertIn("Branch 0002_conflicting_second", stdout.getvalue()) self.assertIn("Branch 0002_conflicting_second", stdout.getvalue())
merge_file = os.path.join(self.test_dir, 'test_migrations_conflict', '0003_merge.py')
self.assertTrue(os.path.exists(merge_file))
os.remove(merge_file)
self.assertFalse(os.path.exists(merge_file))
self.assertIn("Created new merge migration", stdout.getvalue())
@override_system_checks([]) @override_system_checks([])
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_default"}) @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_default"})
@ -469,3 +461,28 @@ class MakeMigrationsTests(MigrationTestBase):
self.assertTrue(os.path.isfile(os.path.join(self.test_dir, self.assertTrue(os.path.isfile(os.path.join(self.test_dir,
"test_migrations_path_doesnt_exist", "foo", "bar", "test_migrations_path_doesnt_exist", "foo", "bar",
"0001_initial.py"))) "0001_initial.py")))
@override_system_checks([])
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_conflict"})
def test_makemigrations_interactive_by_default(self):
"""
Makes sure that the user is prompted to merge by default if there are
conflicts and merge is True. Answer negative to differentiate it from
behavior when --noinput is specified.
"""
# Monkeypatch interactive questioner to auto reject
old_input = questioner.input
questioner.input = lambda _: "N"
stdout = six.StringIO()
merge_file = os.path.join(self.test_dir, 'test_migrations_conflict', '0003_merge.py')
try:
call_command("makemigrations", "migrations", merge=True, stdout=stdout)
# This will fail if interactive is False by default
self.assertFalse(os.path.exists(merge_file))
except CommandError:
self.fail("Makemigrations failed while running interactive questioner")
finally:
questioner.input = old_input
if os.path.exists(merge_file):
os.remove(merge_file)
self.assertNotIn("Created new merge migration", stdout.getvalue())