mirror of https://github.com/django/django.git
Fixed #29301 -- Added custom help formatter to BaseCommand class
This partially reverts c3055242c8
.
Thanks Adam Johnson and Carlton Gibson for the reviews.
This commit is contained in:
parent
e9bd1a3e12
commit
ce3351b950
|
@ -4,7 +4,7 @@ be executed through ``django-admin`` or ``manage.py``).
|
|||
"""
|
||||
import os
|
||||
import sys
|
||||
from argparse import ArgumentParser
|
||||
from argparse import ArgumentParser, HelpFormatter
|
||||
from io import TextIOBase
|
||||
|
||||
import django
|
||||
|
@ -88,6 +88,29 @@ def no_translations(handle_func):
|
|||
return wrapped
|
||||
|
||||
|
||||
class DjangoHelpFormatter(HelpFormatter):
|
||||
"""
|
||||
Customized formatter so that command-specific arguments appear in the
|
||||
--help output before arguments common to all commands.
|
||||
"""
|
||||
show_last = {
|
||||
'--version', '--verbosity', '--traceback', '--settings', '--pythonpath',
|
||||
'--no-color',
|
||||
}
|
||||
|
||||
def _reordered_actions(self, actions):
|
||||
return sorted(
|
||||
actions,
|
||||
key=lambda a: set(a.option_strings) & self.show_last != set()
|
||||
)
|
||||
|
||||
def add_usage(self, usage, actions, *args, **kwargs):
|
||||
super().add_usage(usage, self._reordered_actions(actions), *args, **kwargs)
|
||||
|
||||
def add_arguments(self, actions):
|
||||
super().add_arguments(self._reordered_actions(actions))
|
||||
|
||||
|
||||
class OutputWrapper(TextIOBase):
|
||||
"""
|
||||
Wrapper around stdout/stderr
|
||||
|
@ -229,12 +252,10 @@ class BaseCommand:
|
|||
parser = CommandParser(
|
||||
prog='%s %s' % (os.path.basename(prog_name), subcommand),
|
||||
description=self.help or None,
|
||||
formatter_class=DjangoHelpFormatter,
|
||||
missing_args_message=getattr(self, 'missing_args_message', None),
|
||||
called_from_command_line=getattr(self, '_called_from_command_line', None),
|
||||
)
|
||||
# Add command-specific arguments first so that they appear in the
|
||||
# --help output before arguments common to all commands.
|
||||
self.add_arguments(parser)
|
||||
parser.add_argument('--version', action='version', version=self.get_version())
|
||||
parser.add_argument(
|
||||
'-v', '--verbosity', action='store', dest='verbosity', default=1,
|
||||
|
@ -258,6 +279,7 @@ class BaseCommand:
|
|||
'--no-color', action='store_true', dest='no_color',
|
||||
help="Don't colorize the command output.",
|
||||
)
|
||||
self.add_arguments(parser)
|
||||
return parser
|
||||
|
||||
def add_arguments(self, parser):
|
||||
|
|
|
@ -145,6 +145,11 @@ Management Commands
|
|||
* The new :option:`inspectdb --include-views` option allows creating models
|
||||
for database views.
|
||||
|
||||
* The :class:`~django.core.management.BaseCommand` class now uses a custom help
|
||||
formatter so that the standard options like ``--verbosity`` or ``--settings``
|
||||
appear last in the help output, giving a more prominent position to subclassed
|
||||
command's options.
|
||||
|
||||
Migrations
|
||||
~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
from argparse import ArgumentError
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
def add_arguments(self, parser):
|
||||
try:
|
||||
parser.add_argument('--version', action='version', version='A.B.C')
|
||||
except ArgumentError:
|
||||
pass
|
||||
else:
|
||||
raise CommandError('--version argument does no yet exist')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
return 'Detected that --version already exists'
|
|
@ -205,6 +205,11 @@ class CommandTests(SimpleTestCase):
|
|||
self.assertIn('need_me', out.getvalue())
|
||||
self.assertIn('needme2', out.getvalue())
|
||||
|
||||
def test_command_add_arguments_after_common_arguments(self):
|
||||
out = StringIO()
|
||||
management.call_command('common_args', stdout=out)
|
||||
self.assertIn('Detected that --version already exists', out.getvalue())
|
||||
|
||||
def test_subparser(self):
|
||||
out = StringIO()
|
||||
management.call_command('subparser', 'foo', 12, stdout=out)
|
||||
|
|
Loading…
Reference in New Issue