Commit d9a83d59 authored by Huu Nguyen's avatar Huu Nguyen Committed by Tim Graham
Browse files

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

Thanks artortenburger for the report.

Backport of fbb684d9 from master
parent 0b871ec2
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ class Command(BaseCommand):
            help="Enable fixing of migration conflicts."),
        make_option('--empty', action='store_true', dest='empty', default=False,
            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."
@@ -156,7 +158,7 @@ class Command(BaseCommand):
        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.
+2 −0
Original line number Diff line number Diff line
@@ -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
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
+32 −15
Original line number Diff line number Diff line
@@ -231,19 +231,6 @@ class MakeMigrationsTests(MigrationTestBase):
        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):
@@ -386,13 +373,18 @@ class MakeMigrationsTests(MigrationTestBase):
    @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"})
@@ -469,3 +461,28 @@ class MakeMigrationsTests(MigrationTestBase):
        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()
        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())