Fixed #11745 -- Grouped commands by application in the output of `manage.py help`. Made 'version' consistent with 'help' while I was in the area, and added tests. Thanks Jannis for the feedback and review.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@17462 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
09ad6d1b88
commit
175e6d77df
|
@ -1,3 +1,4 @@
|
|||
import collections
|
||||
import os
|
||||
import sys
|
||||
from optparse import OptionParser, NO_DEFAULT
|
||||
|
@ -5,6 +6,7 @@ import imp
|
|||
import warnings
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError, handle_default_options
|
||||
from django.core.management.color import color_style
|
||||
from django.utils.importlib import import_module
|
||||
|
||||
# For backwards compatibility: get_version() used to be in this module.
|
||||
|
@ -209,16 +211,32 @@ class ManagementUtility(object):
|
|||
self.argv = argv or sys.argv[:]
|
||||
self.prog_name = os.path.basename(self.argv[0])
|
||||
|
||||
def main_help_text(self):
|
||||
def main_help_text(self, commands_only=False):
|
||||
"""
|
||||
Returns the script's main help text, as a string.
|
||||
"""
|
||||
usage = ['',"Type '%s help <subcommand>' for help on a specific subcommand." % self.prog_name,'']
|
||||
usage.append('Available subcommands:')
|
||||
commands = get_commands().keys()
|
||||
commands.sort()
|
||||
for cmd in commands:
|
||||
usage.append(' %s' % cmd)
|
||||
if commands_only:
|
||||
usage = sorted(get_commands().keys())
|
||||
else:
|
||||
usage = [
|
||||
"",
|
||||
"Type '%s help <subcommand>' for help on a specific subcommand." % self.prog_name,
|
||||
"",
|
||||
"Available subcommands:",
|
||||
]
|
||||
commands_dict = collections.defaultdict(lambda: [])
|
||||
for name, app in get_commands().iteritems():
|
||||
if app == 'django.core':
|
||||
app = 'django'
|
||||
else:
|
||||
app = app.rpartition('.')[-1]
|
||||
commands_dict[app].append(name)
|
||||
style = color_style()
|
||||
for app in sorted(commands_dict.keys()):
|
||||
usage.append("")
|
||||
usage.append(style.NOTICE("[%s]" % app))
|
||||
for name in sorted(commands_dict[app]):
|
||||
usage.append(" %s" % name)
|
||||
return '\n'.join(usage)
|
||||
|
||||
def fetch_command(self, subcommand):
|
||||
|
@ -340,12 +358,15 @@ class ManagementUtility(object):
|
|||
subcommand = 'help' # Display help if no arguments were given.
|
||||
|
||||
if subcommand == 'help':
|
||||
if len(args) > 2:
|
||||
self.fetch_command(args[2]).print_help(self.prog_name, args[2])
|
||||
else:
|
||||
if len(args) <= 2:
|
||||
parser.print_lax_help()
|
||||
sys.stdout.write(self.main_help_text() + '\n')
|
||||
sys.exit(1)
|
||||
elif args[2] == '--commands':
|
||||
sys.stdout.write(self.main_help_text(commands_only=True) + '\n')
|
||||
else:
|
||||
self.fetch_command(args[2]).print_help(self.prog_name, args[2])
|
||||
elif subcommand == 'version':
|
||||
sys.stdout.write(parser.get_version() + '\n')
|
||||
# Special-cases: We want 'django-admin.py --version' and
|
||||
# 'django-admin.py --help' to work, for backwards compatibility.
|
||||
elif self.argv[1:] == ['--version']:
|
||||
|
|
|
@ -47,11 +47,16 @@ for the given command.
|
|||
Getting runtime help
|
||||
--------------------
|
||||
|
||||
.. django-admin-option:: --help
|
||||
.. django-admin:: help
|
||||
|
||||
Run ``django-admin.py help`` to display a list of all available commands.
|
||||
Run ``django-admin.py help <command>`` to display a description of the
|
||||
given command and a list of its available options.
|
||||
Run ``django-admin.py help`` to display usage information and a list of the
|
||||
commands provided by each application.
|
||||
|
||||
Run ``django-admin.py help --commands`` to display a list of all available
|
||||
commands.
|
||||
|
||||
Run ``django-admin.py help <command>`` to display a description of the given
|
||||
command and a list of its available options.
|
||||
|
||||
App names
|
||||
---------
|
||||
|
@ -63,9 +68,9 @@ contains the string ``'mysite.blog'``, the app name is ``blog``.
|
|||
Determining the version
|
||||
-----------------------
|
||||
|
||||
.. django-admin-option:: --version
|
||||
.. django-admin:: version
|
||||
|
||||
Run ``django-admin.py --version`` to display the current Django version.
|
||||
Run ``django-admin.py version`` to display the current Django version.
|
||||
|
||||
Examples of output::
|
||||
|
||||
|
|
|
@ -989,6 +989,14 @@ after tests' execution, then you can restore the previous behavior by
|
|||
subclassing ``DjangoTestRunner`` and overriding its ``teardown_databases()``
|
||||
method.
|
||||
|
||||
Output of :djadmin:`manage.py help <help>`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
:djadmin:`manage.py help <help>` now groups available commands by application.
|
||||
If you depended on its output, for instance if you parsed it, you must update
|
||||
your scripts. To obtain the list of all available management commands in a
|
||||
script, you can use :djadmin:`manage.py help --commands <help>` instead.
|
||||
|
||||
Features deprecated in 1.4
|
||||
==========================
|
||||
|
||||
|
|
|
@ -173,6 +173,10 @@ class AdminScriptTestCase(unittest.TestCase):
|
|||
"Utility assertion: assert that the given message exists in the output"
|
||||
self.assertTrue(msg in stream, "'%s' does not match actual output text '%s'" % (msg, stream))
|
||||
|
||||
def assertNotInOutput(self, stream, msg):
|
||||
"Utility assertion: assert that the given message doesn't exist in the output"
|
||||
self.assertFalse(msg in stream, "'%s' matches actual output text '%s'" % (msg, stream))
|
||||
|
||||
##########################################################################
|
||||
# DJANGO ADMIN TESTS
|
||||
# This first series of test classes checks the environment processing
|
||||
|
@ -1173,25 +1177,47 @@ class CommandTypes(AdminScriptTestCase):
|
|||
self.remove_settings('settings.py')
|
||||
|
||||
def test_version(self):
|
||||
"--version is handled as a special case"
|
||||
args = ['--version']
|
||||
"version is handled as a special case"
|
||||
args = ['version']
|
||||
out, err = self.run_manage(args)
|
||||
self.assertNoOutput(err)
|
||||
self.assertOutput(out, get_version())
|
||||
|
||||
def test_help(self):
|
||||
"--help is handled as a special case"
|
||||
args = ['--help']
|
||||
out, err = self.run_manage(args)
|
||||
self.assertOutput(out, "Usage: manage.py subcommand [options] [args]")
|
||||
self.assertOutput(out, "Type 'manage.py help <subcommand>' for help on a specific subcommand.")
|
||||
def test_version_alternative(self):
|
||||
"--version is equivalent to version"
|
||||
args1, args2 = ['version'], ['--version']
|
||||
self.assertEqual(self.run_manage(args1), self.run_manage(args2))
|
||||
|
||||
def test_short_help(self):
|
||||
"-h is handled as a short form of --help"
|
||||
args = ['-h']
|
||||
def test_help(self):
|
||||
"help is handled as a special case"
|
||||
args = ['help']
|
||||
out, err = self.run_manage(args)
|
||||
self.assertOutput(out, "Usage: manage.py subcommand [options] [args]")
|
||||
self.assertOutput(out, "Type 'manage.py help <subcommand>' for help on a specific subcommand.")
|
||||
self.assertOutput(out, '[django]')
|
||||
self.assertOutput(out, 'startapp')
|
||||
self.assertOutput(out, 'startproject')
|
||||
|
||||
def test_help_commands(self):
|
||||
"help --commands shows the list of all available commands"
|
||||
args = ['help', '--commands']
|
||||
out, err = self.run_manage(args)
|
||||
self.assertNotInOutput(out, 'Usage:')
|
||||
self.assertNotInOutput(out, 'Options:')
|
||||
self.assertNotInOutput(out, '[django]')
|
||||
self.assertOutput(out, 'startapp')
|
||||
self.assertOutput(out, 'startproject')
|
||||
self.assertNotInOutput(out, '\n\n')
|
||||
|
||||
def test_help_alternative(self):
|
||||
"--help is equivalent to help"
|
||||
args1, args2 = ['help'], ['--help']
|
||||
self.assertEqual(self.run_manage(args1), self.run_manage(args2))
|
||||
|
||||
def test_help_short_altert(self):
|
||||
"-h is handled as a short form of --help"
|
||||
args1, args2 = ['--help'], ['-h']
|
||||
self.assertEqual(self.run_manage(args1), self.run_manage(args2))
|
||||
|
||||
def test_specific_help(self):
|
||||
"--help can be used on a specific command"
|
||||
|
|
Loading…
Reference in New Issue