Refs #29501 -- Allowed customizing exit status for management commands.
This commit is contained in:
parent
6cad911674
commit
8e8c3f964e
|
@ -26,7 +26,9 @@ class CommandError(Exception):
|
||||||
error) is the preferred way to indicate that something has gone
|
error) is the preferred way to indicate that something has gone
|
||||||
wrong in the execution of a command.
|
wrong in the execution of a command.
|
||||||
"""
|
"""
|
||||||
pass
|
def __init__(self, *args, returncode=1, **kwargs):
|
||||||
|
self.returncode = returncode
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class SystemCheckError(CommandError):
|
class SystemCheckError(CommandError):
|
||||||
|
@ -335,7 +337,7 @@ class BaseCommand:
|
||||||
self.stderr.write(str(e), lambda x: x)
|
self.stderr.write(str(e), lambda x: x)
|
||||||
else:
|
else:
|
||||||
self.stderr.write('%s: %s' % (e.__class__.__name__, e))
|
self.stderr.write('%s: %s' % (e.__class__.__name__, e))
|
||||||
sys.exit(1)
|
sys.exit(e.returncode)
|
||||||
finally:
|
finally:
|
||||||
try:
|
try:
|
||||||
connections.close_all()
|
connections.close_all()
|
||||||
|
|
|
@ -340,7 +340,7 @@ Rather than implementing :meth:`~BaseCommand.handle`, subclasses must implement
|
||||||
Command exceptions
|
Command exceptions
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
.. exception:: CommandError
|
.. exception:: CommandError(returncode=1)
|
||||||
|
|
||||||
Exception class indicating a problem while executing a management command.
|
Exception class indicating a problem while executing a management command.
|
||||||
|
|
||||||
|
@ -348,8 +348,14 @@ If this exception is raised during the execution of a management command from a
|
||||||
command line console, it will be caught and turned into a nicely-printed error
|
command line console, it will be caught and turned into a nicely-printed error
|
||||||
message to the appropriate output stream (i.e., stderr); as a result, raising
|
message to the appropriate output stream (i.e., stderr); as a result, raising
|
||||||
this exception (with a sensible description of the error) is the preferred way
|
this exception (with a sensible description of the error) is the preferred way
|
||||||
to indicate that something has gone wrong in the execution of a command.
|
to indicate that something has gone wrong in the execution of a command. It
|
||||||
|
accepts the optional ``returncode`` argument to customize the exit status for
|
||||||
|
the management command to exit with, using :func:`sys.exit`.
|
||||||
|
|
||||||
If a management command is called from code through
|
If a management command is called from code through
|
||||||
:func:`~django.core.management.call_command`, it's up to you to catch the
|
:func:`~django.core.management.call_command`, it's up to you to catch the
|
||||||
exception when needed.
|
exception when needed.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.1
|
||||||
|
|
||||||
|
The ``returncode`` argument was added.
|
||||||
|
|
|
@ -313,6 +313,10 @@ Management Commands
|
||||||
* The new :option:`migrate --check` option makes the command exit with a
|
* The new :option:`migrate --check` option makes the command exit with a
|
||||||
non-zero status when unapplied migrations are detected.
|
non-zero status when unapplied migrations are detected.
|
||||||
|
|
||||||
|
* The new ``returncode`` argument for
|
||||||
|
:attr:`~django.core.management.CommandError` allows customizing the exit
|
||||||
|
status for management commands.
|
||||||
|
|
||||||
Migrations
|
Migrations
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ class Command(BaseCommand):
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
example = options["example"]
|
example = options["example"]
|
||||||
if example == "raise":
|
if example == "raise":
|
||||||
raise CommandError()
|
raise CommandError(returncode=3)
|
||||||
if options['verbosity'] > 0:
|
if options['verbosity'] > 0:
|
||||||
self.stdout.write("I don't feel like dancing %s." % options["style"])
|
self.stdout.write("I don't feel like dancing %s." % options["style"])
|
||||||
self.stdout.write(','.join(options))
|
self.stdout.write(','.join(options))
|
||||||
|
|
|
@ -57,12 +57,14 @@ class CommandTests(SimpleTestCase):
|
||||||
""" Exception raised in a command should raise CommandError with
|
""" Exception raised in a command should raise CommandError with
|
||||||
call_command, but SystemExit when run from command line
|
call_command, but SystemExit when run from command line
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(CommandError):
|
with self.assertRaises(CommandError) as cm:
|
||||||
management.call_command('dance', example="raise")
|
management.call_command('dance', example="raise")
|
||||||
|
self.assertEqual(cm.exception.returncode, 3)
|
||||||
dance.Command.requires_system_checks = False
|
dance.Command.requires_system_checks = False
|
||||||
try:
|
try:
|
||||||
with captured_stderr() as stderr, self.assertRaises(SystemExit):
|
with captured_stderr() as stderr, self.assertRaises(SystemExit) as cm:
|
||||||
management.ManagementUtility(['manage.py', 'dance', '--example=raise']).execute()
|
management.ManagementUtility(['manage.py', 'dance', '--example=raise']).execute()
|
||||||
|
self.assertEqual(cm.exception.code, 3)
|
||||||
finally:
|
finally:
|
||||||
dance.Command.requires_system_checks = True
|
dance.Command.requires_system_checks = True
|
||||||
self.assertIn("CommandError", stderr.getvalue())
|
self.assertIn("CommandError", stderr.getvalue())
|
||||||
|
|
Loading…
Reference in New Issue