Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #11745 -- Grouped commands by application in the output of `man…

…age.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
  • Loading branch information...
commit 175e6d77df526dea1ade94661e487072e7c7cd88 1 parent 09ad6d1
@aaugustin aaugustin authored
View
43 django/core/management/__init__.py
@@ -1,3 +1,4 @@
+import collections
import os
import sys
from optparse import OptionParser, NO_DEFAULT
@@ -5,6 +6,7 @@
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 @@ def __init__(self, argv=None):
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 @@ def execute(self):
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']:
View
17 docs/ref/django-admin.txt
@@ -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::
View
8 docs/releases/1.4.txt
@@ -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
==========================
View
44 tests/regressiontests/admin_scripts/tests.py
@@ -173,6 +173,10 @@ def assertOutput(self, stream, msg):
"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 @@ def tearDown(self):
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_version_alternative(self):
+ "--version is equivalent to version"
+ args1, args2 = ['version'], ['--version']
+ self.assertEqual(self.run_manage(args1), self.run_manage(args2))
+
def test_help(self):
- "--help is handled as a special case"
- args = ['--help']
+ "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_short_help(self):
- "-h is handled as a short form of --help"
- args = ['-h']
+ def test_help_commands(self):
+ "help --commands shows the list of all available commands"
+ args = ['help', '--commands']
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.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"
Please sign in to comment.
Something went wrong with that request. Please try again.