mirror of https://github.com/django/django.git
Fixed #30031 -- Added --no-header option to makemigrations/squashmigrations.
This commit is contained in:
parent
b514dc14f4
commit
8d3147e130
|
@ -48,6 +48,10 @@ class Command(BaseCommand):
|
||||||
'-n', '--name',
|
'-n', '--name',
|
||||||
help="Use this name for migration file(s).",
|
help="Use this name for migration file(s).",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--no-header', action='store_false', dest='include_header',
|
||||||
|
help='Do not add header comments to new migration file(s).',
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--check', action='store_true', dest='check_changes',
|
'--check', action='store_true', dest='check_changes',
|
||||||
help='Exit with a non-zero status if model changes are missing migrations.',
|
help='Exit with a non-zero status if model changes are missing migrations.',
|
||||||
|
@ -63,6 +67,7 @@ class Command(BaseCommand):
|
||||||
self.migration_name = options['name']
|
self.migration_name = options['name']
|
||||||
if self.migration_name and not self.migration_name.isidentifier():
|
if self.migration_name and not self.migration_name.isidentifier():
|
||||||
raise CommandError('The migration name must be a valid Python identifier.')
|
raise CommandError('The migration name must be a valid Python identifier.')
|
||||||
|
self.include_header = options['include_header']
|
||||||
check_changes = options['check_changes']
|
check_changes = options['check_changes']
|
||||||
|
|
||||||
# Make sure the app they asked for exists
|
# Make sure the app they asked for exists
|
||||||
|
@ -188,7 +193,7 @@ class Command(BaseCommand):
|
||||||
self.stdout.write(self.style.MIGRATE_HEADING("Migrations for '%s':" % app_label) + "\n")
|
self.stdout.write(self.style.MIGRATE_HEADING("Migrations for '%s':" % app_label) + "\n")
|
||||||
for migration in app_migrations:
|
for migration in app_migrations:
|
||||||
# Describe the migration
|
# Describe the migration
|
||||||
writer = MigrationWriter(migration)
|
writer = MigrationWriter(migration, self.include_header)
|
||||||
if self.verbosity >= 1:
|
if self.verbosity >= 1:
|
||||||
# Display a relative path if it's below the current working
|
# Display a relative path if it's below the current working
|
||||||
# directory, or an absolute path otherwise.
|
# directory, or an absolute path otherwise.
|
||||||
|
@ -288,7 +293,7 @@ class Command(BaseCommand):
|
||||||
self.migration_name or ("merge_%s" % get_migration_name_timestamp())
|
self.migration_name or ("merge_%s" % get_migration_name_timestamp())
|
||||||
)
|
)
|
||||||
new_migration = subclass(migration_name, app_label)
|
new_migration = subclass(migration_name, app_label)
|
||||||
writer = MigrationWriter(new_migration)
|
writer = MigrationWriter(new_migration, self.include_header)
|
||||||
|
|
||||||
if not self.dry_run:
|
if not self.dry_run:
|
||||||
# Write the merge migrations file to the disk
|
# Write the merge migrations file to the disk
|
||||||
|
|
|
@ -37,6 +37,10 @@ class Command(BaseCommand):
|
||||||
'--squashed-name',
|
'--squashed-name',
|
||||||
help='Sets the name of the new squashed migration.',
|
help='Sets the name of the new squashed migration.',
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--no-header', action='store_false', dest='include_header',
|
||||||
|
help='Do not add a header comment to the new squashed migration.',
|
||||||
|
)
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, **options):
|
||||||
|
|
||||||
|
@ -47,6 +51,7 @@ class Command(BaseCommand):
|
||||||
migration_name = options['migration_name']
|
migration_name = options['migration_name']
|
||||||
no_optimize = options['no_optimize']
|
no_optimize = options['no_optimize']
|
||||||
squashed_name = options['squashed_name']
|
squashed_name = options['squashed_name']
|
||||||
|
include_header = options['include_header']
|
||||||
# Validate app_label.
|
# Validate app_label.
|
||||||
try:
|
try:
|
||||||
apps.get_app_config(app_label)
|
apps.get_app_config(app_label)
|
||||||
|
@ -178,7 +183,7 @@ class Command(BaseCommand):
|
||||||
new_migration.initial = True
|
new_migration.initial = True
|
||||||
|
|
||||||
# Write out the new migration file
|
# Write out the new migration file
|
||||||
writer = MigrationWriter(new_migration)
|
writer = MigrationWriter(new_migration, include_header)
|
||||||
with open(writer.path, "w", encoding='utf-8') as fh:
|
with open(writer.path, "w", encoding='utf-8') as fh:
|
||||||
fh.write(writer.as_string())
|
fh.write(writer.as_string())
|
||||||
|
|
||||||
|
|
|
@ -132,8 +132,9 @@ class MigrationWriter:
|
||||||
of the migration file from it.
|
of the migration file from it.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, migration):
|
def __init__(self, migration, include_header=True):
|
||||||
self.migration = migration
|
self.migration = migration
|
||||||
|
self.include_header = include_header
|
||||||
self.needs_manual_porting = False
|
self.needs_manual_porting = False
|
||||||
|
|
||||||
def as_string(self):
|
def as_string(self):
|
||||||
|
@ -195,10 +196,13 @@ class MigrationWriter:
|
||||||
if self.migration.replaces:
|
if self.migration.replaces:
|
||||||
items['replaces_str'] = "\n replaces = %s\n" % self.serialize(self.migration.replaces)[0]
|
items['replaces_str'] = "\n replaces = %s\n" % self.serialize(self.migration.replaces)[0]
|
||||||
# Hinting that goes into comment
|
# Hinting that goes into comment
|
||||||
items.update(
|
if self.include_header:
|
||||||
version=get_version(),
|
items['migration_header'] = MIGRATION_HEADER_TEMPLATE % {
|
||||||
timestamp=now().strftime("%Y-%m-%d %H:%M"),
|
'version': get_version(),
|
||||||
)
|
'timestamp': now().strftime("%Y-%m-%d %H:%M"),
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
items['migration_header'] = ""
|
||||||
|
|
||||||
if self.migration.initial:
|
if self.migration.initial:
|
||||||
items['initial_str'] = "\n initial = True\n"
|
items['initial_str'] = "\n initial = True\n"
|
||||||
|
@ -279,10 +283,14 @@ class MigrationWriter:
|
||||||
return serializer_factory(value).serialize()
|
return serializer_factory(value).serialize()
|
||||||
|
|
||||||
|
|
||||||
MIGRATION_TEMPLATE = """\
|
MIGRATION_HEADER_TEMPLATE = """\
|
||||||
# Generated by Django %(version)s on %(timestamp)s
|
# Generated by Django %(version)s on %(timestamp)s
|
||||||
|
|
||||||
%(imports)s
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
MIGRATION_TEMPLATE = """\
|
||||||
|
%(migration_header)s%(imports)s
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
%(replaces_str)s%(initial_str)s
|
%(replaces_str)s%(initial_str)s
|
||||||
|
|
|
@ -776,6 +776,12 @@ Enables fixing of migration conflicts.
|
||||||
Allows naming the generated migration(s) instead of using a generated name. The
|
Allows naming the generated migration(s) instead of using a generated name. The
|
||||||
name must be a valid Python :ref:`identifier <python:identifiers>`.
|
name must be a valid Python :ref:`identifier <python:identifiers>`.
|
||||||
|
|
||||||
|
.. django-admin-option:: --no-header
|
||||||
|
|
||||||
|
.. versionadded:: 2.2
|
||||||
|
|
||||||
|
Generate migration files without Django version and timestamp header.
|
||||||
|
|
||||||
.. django-admin-option:: --check
|
.. django-admin-option:: --check
|
||||||
|
|
||||||
Makes ``makemigrations`` exit with a non-zero status when model changes without
|
Makes ``makemigrations`` exit with a non-zero status when model changes without
|
||||||
|
@ -1156,6 +1162,12 @@ Suppresses all user prompts.
|
||||||
Sets the name of the squashed migration. When omitted, the name is based on the
|
Sets the name of the squashed migration. When omitted, the name is based on the
|
||||||
first and last migration, with ``_squashed_`` in between.
|
first and last migration, with ``_squashed_`` in between.
|
||||||
|
|
||||||
|
.. django-admin-option:: --no-header
|
||||||
|
|
||||||
|
.. versionadded:: 2.2
|
||||||
|
|
||||||
|
Generate squashed migration file without Django version and timestamp header.
|
||||||
|
|
||||||
``startapp``
|
``startapp``
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,10 @@ Management Commands
|
||||||
* On Oracle, :djadmin:`dbshell` is wrapped with ``rlwrap``, if available.
|
* On Oracle, :djadmin:`dbshell` is wrapped with ``rlwrap``, if available.
|
||||||
``rlwrap`` provides a command history and editing of keyboard input.
|
``rlwrap`` provides a command history and editing of keyboard input.
|
||||||
|
|
||||||
|
* The new :option:`makemigrations --no-header` option avoids writing header
|
||||||
|
comments in generated migration file(s). This option is also available for
|
||||||
|
:djadmin:`squashmigrations`.
|
||||||
|
|
||||||
Migrations
|
Migrations
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -613,16 +613,21 @@ class WriterTests(SimpleTestCase):
|
||||||
})
|
})
|
||||||
dt = datetime.datetime(2015, 7, 31, 4, 40, 0, 0, tzinfo=utc)
|
dt = datetime.datetime(2015, 7, 31, 4, 40, 0, 0, tzinfo=utc)
|
||||||
with mock.patch('django.db.migrations.writer.now', lambda: dt):
|
with mock.patch('django.db.migrations.writer.now', lambda: dt):
|
||||||
writer = MigrationWriter(migration)
|
for include_header in (True, False):
|
||||||
output = writer.as_string()
|
with self.subTest(include_header=include_header):
|
||||||
|
writer = MigrationWriter(migration, include_header)
|
||||||
|
output = writer.as_string()
|
||||||
|
|
||||||
self.assertTrue(
|
self.assertEqual(
|
||||||
output.startswith(
|
include_header,
|
||||||
"# Generated by Django %(version)s on 2015-07-31 04:40\n" % {
|
output.startswith(
|
||||||
'version': get_version(),
|
"# Generated by Django %s on 2015-07-31 04:40\n\n" % get_version()
|
||||||
}
|
)
|
||||||
)
|
)
|
||||||
)
|
if not include_header:
|
||||||
|
# Make sure the output starts with something that's not
|
||||||
|
# a comment or indentation or blank line
|
||||||
|
self.assertRegex(output.splitlines(keepends=True)[0], r"^[^#\s]+")
|
||||||
|
|
||||||
def test_models_import_omitted(self):
|
def test_models_import_omitted(self):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue