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 os
|
||||||
import sys
|
import sys
|
||||||
from optparse import OptionParser, NO_DEFAULT
|
from optparse import OptionParser, NO_DEFAULT
|
||||||
|
@ -5,6 +6,7 @@ import imp
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand, CommandError, handle_default_options
|
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
|
from django.utils.importlib import import_module
|
||||||
|
|
||||||
# For backwards compatibility: get_version() used to be in this 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.argv = argv or sys.argv[:]
|
||||||
self.prog_name = os.path.basename(self.argv[0])
|
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.
|
Returns the script's main help text, as a string.
|
||||||
"""
|
"""
|
||||||
usage = ['',"Type '%s help <subcommand>' for help on a specific subcommand." % self.prog_name,'']
|
if commands_only:
|
||||||
usage.append('Available subcommands:')
|
usage = sorted(get_commands().keys())
|
||||||
commands = get_commands().keys()
|
else:
|
||||||
commands.sort()
|
usage = [
|
||||||
for cmd in commands:
|
"",
|
||||||
usage.append(' %s' % cmd)
|
"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)
|
return '\n'.join(usage)
|
||||||
|
|
||||||
def fetch_command(self, subcommand):
|
def fetch_command(self, subcommand):
|
||||||
|
@ -340,12 +358,15 @@ class ManagementUtility(object):
|
||||||
subcommand = 'help' # Display help if no arguments were given.
|
subcommand = 'help' # Display help if no arguments were given.
|
||||||
|
|
||||||
if subcommand == 'help':
|
if subcommand == 'help':
|
||||||
if len(args) > 2:
|
if len(args) <= 2:
|
||||||
self.fetch_command(args[2]).print_help(self.prog_name, args[2])
|
|
||||||
else:
|
|
||||||
parser.print_lax_help()
|
parser.print_lax_help()
|
||||||
sys.stdout.write(self.main_help_text() + '\n')
|
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
|
# Special-cases: We want 'django-admin.py --version' and
|
||||||
# 'django-admin.py --help' to work, for backwards compatibility.
|
# 'django-admin.py --help' to work, for backwards compatibility.
|
||||||
elif self.argv[1:] == ['--version']:
|
elif self.argv[1:] == ['--version']:
|
||||||
|
|
|
@ -47,11 +47,16 @@ for the given command.
|
||||||
Getting runtime help
|
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`` to display usage information and a list of the
|
||||||
Run ``django-admin.py help <command>`` to display a description of the
|
commands provided by each application.
|
||||||
given command and a list of its available options.
|
|
||||||
|
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
|
App names
|
||||||
---------
|
---------
|
||||||
|
@ -63,9 +68,9 @@ contains the string ``'mysite.blog'``, the app name is ``blog``.
|
||||||
Determining the version
|
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::
|
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()``
|
subclassing ``DjangoTestRunner`` and overriding its ``teardown_databases()``
|
||||||
method.
|
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
|
Features deprecated in 1.4
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,10 @@ class AdminScriptTestCase(unittest.TestCase):
|
||||||
"Utility assertion: assert that the given message exists in the output"
|
"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))
|
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
|
# DJANGO ADMIN TESTS
|
||||||
# This first series of test classes checks the environment processing
|
# This first series of test classes checks the environment processing
|
||||||
|
@ -1173,25 +1177,47 @@ class CommandTypes(AdminScriptTestCase):
|
||||||
self.remove_settings('settings.py')
|
self.remove_settings('settings.py')
|
||||||
|
|
||||||
def test_version(self):
|
def test_version(self):
|
||||||
"--version is handled as a special case"
|
"version is handled as a special case"
|
||||||
args = ['--version']
|
args = ['version']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, get_version())
|
self.assertOutput(out, get_version())
|
||||||
|
|
||||||
def test_help(self):
|
def test_version_alternative(self):
|
||||||
"--help is handled as a special case"
|
"--version is equivalent to version"
|
||||||
args = ['--help']
|
args1, args2 = ['version'], ['--version']
|
||||||
out, err = self.run_manage(args)
|
self.assertEqual(self.run_manage(args1), self.run_manage(args2))
|
||||||
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_short_help(self):
|
def test_help(self):
|
||||||
"-h is handled as a short form of --help"
|
"help is handled as a special case"
|
||||||
args = ['-h']
|
args = ['help']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertOutput(out, "Usage: manage.py subcommand [options] [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, "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):
|
def test_specific_help(self):
|
||||||
"--help can be used on a specific command"
|
"--help can be used on a specific command"
|
||||||
|
|
Loading…
Reference in New Issue