Fixed #27881 -- Added diffsettings --output option.
Thanks Haris Ibrahim K. V. for writng docs.
This commit is contained in:
parent
af1fa5e7da
commit
2f09a28558
|
@ -8,15 +8,17 @@ def module_to_dict(module, omittable=lambda k: k.startswith('_')):
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = """Displays differences between the current settings.py and Django's
|
help = """Displays differences between the current settings.py and Django's
|
||||||
default settings. Settings that don't appear in the defaults are
|
default settings."""
|
||||||
followed by "###"."""
|
|
||||||
|
|
||||||
requires_system_checks = False
|
requires_system_checks = False
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--all', action='store_true', dest='all',
|
'--all', action='store_true', dest='all',
|
||||||
help='Display all settings, regardless of their value. Default values are prefixed by "###".',
|
help=(
|
||||||
|
'Display all settings, regardless of their value. In "hash" '
|
||||||
|
'mode, default values are prefixed by "###".'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--default', dest='default', metavar='MODULE', default=None,
|
'--default', dest='default', metavar='MODULE', default=None,
|
||||||
|
@ -25,9 +27,18 @@ class Command(BaseCommand):
|
||||||
"compare against Django's default settings."
|
"compare against Django's default settings."
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--output', default='hash', choices=('hash', 'unified'), dest='output',
|
||||||
|
help=(
|
||||||
|
"Selects the output format. 'hash' mode displays each changed "
|
||||||
|
"setting, with the settings that don't appear in the defaults "
|
||||||
|
"followed by ###. 'unified' mode prefixes the default setting "
|
||||||
|
"with a minus sign, followed by the changed setting prefixed "
|
||||||
|
"with a plus sign."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, **options):
|
||||||
# Inspired by Postfix's "postconf -n".
|
|
||||||
from django.conf import settings, Settings, global_settings
|
from django.conf import settings, Settings, global_settings
|
||||||
|
|
||||||
# Because settings are imported lazily, we need to explicitly load them.
|
# Because settings are imported lazily, we need to explicitly load them.
|
||||||
|
@ -36,7 +47,14 @@ class Command(BaseCommand):
|
||||||
user_settings = module_to_dict(settings._wrapped)
|
user_settings = module_to_dict(settings._wrapped)
|
||||||
default = options['default']
|
default = options['default']
|
||||||
default_settings = module_to_dict(Settings(default) if default else global_settings)
|
default_settings = module_to_dict(Settings(default) if default else global_settings)
|
||||||
|
output_func = {
|
||||||
|
'hash': self.output_hash,
|
||||||
|
'unified': self.output_unified,
|
||||||
|
}[options['output']]
|
||||||
|
return '\n'.join(output_func(user_settings, default_settings, **options))
|
||||||
|
|
||||||
|
def output_hash(self, user_settings, default_settings, **options):
|
||||||
|
# Inspired by Postfix's "postconf -n".
|
||||||
output = []
|
output = []
|
||||||
for key in sorted(user_settings):
|
for key in sorted(user_settings):
|
||||||
if key not in default_settings:
|
if key not in default_settings:
|
||||||
|
@ -45,4 +63,16 @@ class Command(BaseCommand):
|
||||||
output.append("%s = %s" % (key, user_settings[key]))
|
output.append("%s = %s" % (key, user_settings[key]))
|
||||||
elif options['all']:
|
elif options['all']:
|
||||||
output.append("### %s = %s" % (key, user_settings[key]))
|
output.append("### %s = %s" % (key, user_settings[key]))
|
||||||
return '\n'.join(output)
|
return output
|
||||||
|
|
||||||
|
def output_unified(self, user_settings, default_settings, **options):
|
||||||
|
output = []
|
||||||
|
for key in sorted(user_settings):
|
||||||
|
if key not in default_settings:
|
||||||
|
output.append(self.style.SUCCESS("+ %s = %s" % (key, user_settings[key])))
|
||||||
|
elif user_settings[key] != default_settings[key]:
|
||||||
|
output.append(self.style.ERROR("- %s = %s" % (key, default_settings[key])))
|
||||||
|
output.append(self.style.SUCCESS("+ %s = %s" % (key, user_settings[key])))
|
||||||
|
elif options['all']:
|
||||||
|
output.append(" %s = %s" % (key, user_settings[key]))
|
||||||
|
return output
|
||||||
|
|
|
@ -240,6 +240,16 @@ are prefixed by ``"###"``.
|
||||||
The settings module to compare the current settings against. Leave empty to
|
The settings module to compare the current settings against. Leave empty to
|
||||||
compare against Django's default settings.
|
compare against Django's default settings.
|
||||||
|
|
||||||
|
.. django-admin-option:: --output {hash,unified}
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
Specifies the output format. Available values are ``hash`` and ``unified``.
|
||||||
|
``hash`` is the default mode that displays the output that's described above.
|
||||||
|
``unified`` displays the output similar to ``diff -u``. Default settings are
|
||||||
|
prefixed with a minus sign, followed by the changed setting prefixed with a
|
||||||
|
plus sign.
|
||||||
|
|
||||||
``dumpdata``
|
``dumpdata``
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,9 @@ Management Commands
|
||||||
|
|
||||||
* :djadmin:`loaddata` can now :ref:`read from stdin <loading-fixtures-stdin>`.
|
* :djadmin:`loaddata` can now :ref:`read from stdin <loading-fixtures-stdin>`.
|
||||||
|
|
||||||
|
* The new :option:`diffsettings --output` option allows formatting the output
|
||||||
|
in a unified diff format.
|
||||||
|
|
||||||
Migrations
|
Migrations
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -2120,6 +2120,32 @@ class DiffSettings(AdminScriptTestCase):
|
||||||
self.assertNotInOutput(out, "FOO")
|
self.assertNotInOutput(out, "FOO")
|
||||||
self.assertOutput(out, "BAR = 'bar2'")
|
self.assertOutput(out, "BAR = 'bar2'")
|
||||||
|
|
||||||
|
def test_unified(self):
|
||||||
|
"""--output=unified emits settings diff in unified mode."""
|
||||||
|
self.write_settings('settings_to_diff.py', sdict={'FOO': '"bar"'})
|
||||||
|
self.addCleanup(self.remove_settings, 'settings_to_diff.py')
|
||||||
|
args = ['diffsettings', '--settings=settings_to_diff', '--output=unified']
|
||||||
|
out, err = self.run_manage(args)
|
||||||
|
self.assertNoOutput(err)
|
||||||
|
self.assertOutput(out, "+ FOO = 'bar'")
|
||||||
|
self.assertOutput(out, "- SECRET_KEY = ''")
|
||||||
|
self.assertOutput(out, "+ SECRET_KEY = 'django_tests_secret_key'")
|
||||||
|
self.assertNotInOutput(out, " APPEND_SLASH = True")
|
||||||
|
|
||||||
|
def test_unified_all(self):
|
||||||
|
"""
|
||||||
|
--output=unified --all emits settings diff in unified mode and includes
|
||||||
|
settings with the default value.
|
||||||
|
"""
|
||||||
|
self.write_settings('settings_to_diff.py', sdict={'FOO': '"bar"'})
|
||||||
|
self.addCleanup(self.remove_settings, 'settings_to_diff.py')
|
||||||
|
args = ['diffsettings', '--settings=settings_to_diff', '--output=unified', '--all']
|
||||||
|
out, err = self.run_manage(args)
|
||||||
|
self.assertNoOutput(err)
|
||||||
|
self.assertOutput(out, " APPEND_SLASH = True")
|
||||||
|
self.assertOutput(out, "+ FOO = 'bar'")
|
||||||
|
self.assertOutput(out, "- SECRET_KEY = ''")
|
||||||
|
|
||||||
|
|
||||||
class Dumpdata(AdminScriptTestCase):
|
class Dumpdata(AdminScriptTestCase):
|
||||||
"""Tests for dumpdata management command."""
|
"""Tests for dumpdata management command."""
|
||||||
|
|
Loading…
Reference in New Issue