Skip to content

Commit

Permalink
Fixed #22862 -- Added --noinput option to makemigrations.
Browse files Browse the repository at this point in the history
Thanks artortenburger for the report.
  • Loading branch information
whoshuu authored and timgraham committed Jun 20, 2014
1 parent 608aa8d commit fbb684d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 16 deletions.
4 changes: 3 additions & 1 deletion django/core/management/commands/makemigrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def add_arguments(self, parser):
help="Enable fixing of migration conflicts.")
parser.add_argument('--empty', action='store_true', dest='empty', default=False,
help="Create an empty migration.")
parser.add_argument('--noinput', action='store_false', dest='interactive', default=True,
help='Tells Django to NOT prompt the user for input of any kind.')

def handle(self, *app_labels, **options):

Expand Down Expand Up @@ -154,7 +156,7 @@ def handle_merge(self, loader, conflicts):
if self.interactive:
questioner = InteractiveMigrationQuestioner()
else:
questioner = MigrationQuestioner()
questioner = MigrationQuestioner(defaults={'ask_merge': True})
for app_label, migration_names in conflicts.items():
# Grab out the migrations in question, and work out their
# common ancestor.
Expand Down
2 changes: 2 additions & 0 deletions docs/ref/django-admin.txt
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,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
of a ``ForeignKey``, for example).

The :djadminopt:`--noinput` option may be provided to suppress all user prompts.

.. django-admin-option:: --empty

The ``--empty`` option will cause ``makemigrations`` to output an empty
Expand Down
47 changes: 32 additions & 15 deletions tests/migrations/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,19 +231,6 @@ def test_makemigrations_conflict_exit(self):
with self.assertRaises(CommandError):
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_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"})
def test_makemigrations_merge_no_conflict(self):
Expand Down Expand Up @@ -386,13 +373,18 @@ def test_makemigrations_interactive_accept(self):
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_conflict"})
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()
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("Branch 0002_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_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_default"})
Expand Down Expand Up @@ -469,3 +461,28 @@ class Meta:
self.assertTrue(os.path.isfile(os.path.join(self.test_dir,
"test_migrations_path_doesnt_exist", "foo", "bar",
"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()
try:
call_command("makemigrations", "migrations", merge=True, stdout=stdout)
merge_file = os.path.join(self.test_dir, 'test_migrations_conflict', '0003_merge.py')
# 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())

0 comments on commit fbb684d

Please sign in to comment.