Commit 347cab4f authored by Andrew Godwin's avatar Andrew Godwin
Browse files

Merge pull request #2744 from mmardini/MIGRATION_MODULES

Fixed #22682 -- `makemigrations` will create `MIGRATION_MODULES` package
parents 67d9f70e 56cfa508
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ import decimal
import collections
from importlib import import_module
import os
import sys
import types

from django.apps import apps
@@ -158,7 +159,18 @@ class MigrationWriter(object):
            if '%s.%s' % (app_config.name, migrations_package_basename) == migrations_package_name:
                basedir = os.path.join(app_config.path, migrations_package_basename)
            else:
                raise ImportError("Cannot open migrations module %s for app %s" % (migrations_package_name, self.migration.app_label))
                # In case of using MIGRATION_MODULES setting and the custom
                # package doesn't exist, create one.
                package_dirs = migrations_package_name.split(".")
                create_path = os.path.join(sys.path[0], *package_dirs)
                if not os.path.isdir(create_path):
                    os.makedirs(create_path)
                for i in range(1, len(package_dirs) + 1):
                    init_dir = os.path.join(sys.path[0], *package_dirs[:i])
                    init_path = os.path.join(init_dir, "__init__.py")
                    if not os.path.isfile(init_path):
                        open(init_path, "w").close()
                return os.path.join(create_path, self.filename)
        return os.path.join(basedir, self.filename)

    @classmethod
+3 −0
Original line number Diff line number Diff line
@@ -1757,6 +1757,9 @@ Example::

In this case, migrations pertaining to the ``blog`` app will be contained in the ``blog.db_migrations`` package.

:djadmin:`makemigrations` will automatically create the package if it doesn't
already exist.

.. setting:: MONTH_DAY_FORMAT

MONTH_DAY_FORMAT
+35 −0
Original line number Diff line number Diff line
@@ -413,3 +413,38 @@ class MakeMigrationsTests(MigrationTestBase):
        self.assertIn("migrations.AddField(", stdout.getvalue())
        self.assertIn("model_name='sillymodel',", stdout.getvalue())
        self.assertIn("name='silly_char',", stdout.getvalue())

    @override_system_checks([])
    @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_path_doesnt_exist.foo.bar"})
    def test_makemigrations_migrations_modules_path_not_exist(self):
        """
        Ticket #22682 -- Makemigrations fails when specifying custom location
        for migration files (using MIGRATION_MODULES) if the custom path
        doesn't already exist.
        """

        class SillyModel(models.Model):
            silly_field = models.BooleanField(default=False)

            class Meta:
                app_label = "migrations"

        stdout = six.StringIO()
        call_command("makemigrations", "migrations", stdout=stdout)

        # Command output indicates the migration is created.
        self.assertIn(" - Create model SillyModel", stdout.getvalue())

        # Migrations file is actually created in the expected path.
        self.assertTrue(os.path.isfile(os.path.join(self.test_dir,
                       "test_migrations_path_doesnt_exist", "foo", "bar",
                       "0001_initial.py")))

        os.chdir(self.test_dir)
        try:
            self._rmrf(os.path.join(self.test_dir,
                       "test_migrations_path_doesnt_exist"))
            pass
        except OSError:
            pass
        os.chdir(self._cwd)