Kaydet (Commit) f7a78f9b authored tarafından Huu Nguyen's avatar Huu Nguyen Kaydeden (comit) Tim Graham

Fixed #22791 -- Invoke interactive questioner only for conflicts in specified apps.

Thanks bendavis78 for the report and Tim Graham for the review.
üst efe87d3e
...@@ -10,6 +10,7 @@ from django.db.migrations.autodetector import MigrationAutodetector ...@@ -10,6 +10,7 @@ from django.db.migrations.autodetector import MigrationAutodetector
from django.db.migrations.questioner import MigrationQuestioner, InteractiveMigrationQuestioner from django.db.migrations.questioner import MigrationQuestioner, InteractiveMigrationQuestioner
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.six import iteritems
from django.utils.six.moves import reduce from django.utils.six.moves import reduce
...@@ -56,6 +57,14 @@ class Command(BaseCommand): ...@@ -56,6 +57,14 @@ class Command(BaseCommand):
# Before anything else, see if there's conflicting apps and drop out # Before anything else, see if there's conflicting apps and drop out
# hard if there are any and they don't want to merge # hard if there are any and they don't want to merge
conflicts = loader.detect_conflicts() conflicts = loader.detect_conflicts()
# If app_labels is specified, filter out conflicting migrations for unspecified apps
if app_labels:
conflicts = dict(
(app_label, conflict) for app_label, conflict in iteritems(conflicts)
if app_label in app_labels
)
if conflicts and not self.merge: if conflicts and not self.merge:
name_str = "; ".join( name_str = "; ".join(
"%s in %s" % (", ".join(names), app) "%s in %s" % (", ".join(names), app)
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
operations = [
migrations.CreateModel(
"Author",
[
("id", models.AutoField(primary_key=True)),
("name", models.CharField(max_length=255)),
("slug", models.SlugField(null=True)),
("age", models.IntegerField(default=0)),
("silly_field", models.BooleanField(default=False)),
],
),
migrations.CreateModel(
"Tribble",
[
("id", models.AutoField(primary_key=True)),
("fluffy", models.BooleanField(default=True)),
],
)
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("unspecified_app_with_conflict", "0001_initial")]
operations = [
migrations.CreateModel(
"Something",
[
("id", models.AutoField(primary_key=True)),
],
)
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("unspecified_app_with_conflict", "0001_initial")]
operations = [
migrations.DeleteModel("Tribble"),
migrations.RemoveField("Author", "silly_field"),
migrations.AddField("Author", "rating", models.IntegerField(default=0)),
migrations.CreateModel(
"Book",
[
("id", models.AutoField(primary_key=True)),
],
)
]
...@@ -493,3 +493,49 @@ class MakeMigrationsTests(MigrationTestBase): ...@@ -493,3 +493,49 @@ class MakeMigrationsTests(MigrationTestBase):
if os.path.exists(merge_file): if os.path.exists(merge_file):
os.remove(merge_file) os.remove(merge_file)
self.assertNotIn("Created new merge migration", stdout.getvalue()) self.assertNotIn("Created new merge migration", stdout.getvalue())
@override_system_checks([])
@override_settings(
MIGRATION_MODULES={"migrations": "migrations.test_migrations_no_changes"},
INSTALLED_APPS=[
"migrations",
"migrations.migrations_test_apps.unspecified_app_with_conflict"])
def test_makemigrations_unspecified_app_with_conflict_no_merge(self):
"""
Makes sure that makemigrations does not raise a CommandError when an
unspecified app has conflicting migrations.
"""
try:
call_command("makemigrations", "migrations", merge=False, verbosity=0)
except CommandError:
self.fail("Makemigrations fails resolving conflicts in an unspecified app")
@override_system_checks([])
@override_settings(
INSTALLED_APPS=[
"migrations.migrations_test_apps.migrated_app",
"migrations.migrations_test_apps.unspecified_app_with_conflict"])
def test_makemigrations_unspecified_app_with_conflict_merge(self):
"""
Makes sure that makemigrations does not create a merge for an
unspecified app even if it has conflicting migrations.
"""
# Monkeypatch interactive questioner to auto accept
old_input = questioner.input
questioner.input = lambda _: "y"
stdout = six.StringIO()
merge_file = os.path.join(self.test_dir,
'migrations_test_apps',
'unspecified_app_with_conflict',
'migrations',
'0003_merge.py')
try:
call_command("makemigrations", "migrated_app", merge=True, interactive=True, stdout=stdout)
self.assertFalse(os.path.exists(merge_file))
self.assertIn("No conflicts detected to merge.", stdout.getvalue())
except CommandError:
self.fail("Makemigrations fails resolving conflicts in an unspecified app")
finally:
questioner.input = old_input
if os.path.exists(merge_file):
os.remove(merge_file)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment