Commit 7b57e575 authored by Jose L. Patino's avatar Jose L. Patino Committed by Tim Graham
Browse files

Fixed #19877 -- Added `--no-color` option to `BaseCommand` to avoid using output styles.

parent d4dd55e7
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ from optparse import make_option, OptionParser

import django
from django.core.exceptions import ImproperlyConfigured
from django.core.management.color import color_style
from django.core.management.color import color_style, no_style
from django.utils.encoding import force_str
from django.utils.six import StringIO

@@ -171,6 +171,8 @@ class BaseCommand(object):
            help='A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".'),
        make_option('--traceback', action='store_true',
            help='Raise on exception'),
        make_option('--no-color', action='store_true', dest='no_color', default=False,
            help="Don't colorize the command output."),
    )
    help = ''
    args = ''
@@ -254,6 +256,10 @@ class BaseCommand(object):
        ``self.requires_model_validation``, except if force-skipped).
        """
        self.stdout = OutputWrapper(options.get('stdout', sys.stdout))
        if options.get('no_color'):
            self.style = no_style()
            self.stderr = OutputWrapper(options.get('stderr', sys.stderr))
        else:
            self.stderr = OutputWrapper(options.get('stderr', sys.stderr), self.style.ERROR)

        if self.can_import_settings:
+1 −1
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ def color_style():
            class dummy: pass
            style = dummy()
            # The nocolor palette has all available roles.
            # Use that pallete as the basis for populating
            # Use that palette as the basis for populating
            # the palette as defined in the environment.
            for role in termcolors.PALETTES[termcolors.NOCOLOR_PALETTE]:
                format = color_settings.get(role,{})
+13 −0
Original line number Diff line number Diff line
@@ -1429,6 +1429,19 @@ that ``django-admin.py`` should print to the console.
* ``2`` means verbose output.
* ``3`` means *very* verbose output.

.. django-admin-option:: --no-color

.. versionadded:: 1.7

Example usage::

    django-admin.py sqlall --no-color

By default, ``django-admin.py`` will format the output to be colorized. For
example, errors will be printed to the console in red and SQL statements will
be syntax highlighted. To prevent this and have a plain text output, pass the
``--no-color`` option when running your command.

Common options
==============

+3 −0
Original line number Diff line number Diff line
@@ -92,6 +92,9 @@ Minor features
* :func:`~django.core.mail.send_mail` now accepts an ``html_message``
  parameter for sending a multipart ``text/plain`` and ``text/html`` email.

* The :djadminopt:`--no-color` option for ``django-admin.py`` allows you to
  disable the colorization of management command output.

Backwards incompatible changes in 1.7
=====================================

+42 −20
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ import unittest
import django
from django import conf, get_version
from django.conf import settings
from django.core.management import BaseCommand, CommandError
from django.core.management import BaseCommand, CommandError, call_command
from django.db import connection
from django.test.runner import DiscoverRunner
from django.utils.encoding import force_text
@@ -922,14 +922,21 @@ class ManageAlternateSettings(AdminScriptTestCase):
        "alternate: manage.py can execute user commands if settings are provided as argument"
        args = ['noargs_command', '--settings=alternate_settings']
        out, err = self.run_manage(args)
        self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('no_color', False), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
        self.assertNoOutput(err)

    def test_custom_command_with_environment(self):
        "alternate: manage.py can execute user commands if settings are provided in environment"
        args = ['noargs_command']
        out, err = self.run_manage(args, 'alternate_settings')
        self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertNoOutput(err)

    def test_custom_command_output_color(self):
        "alternate: manage.py output syntax color can be deactivated with the `--no-color` option"
        args = ['noargs_command', '--no-color', '--settings=alternate_settings']
        out, err = self.run_manage(args)
        self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('no_color', True), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
        self.assertNoOutput(err)


@@ -1272,40 +1279,55 @@ class CommandTypes(AdminScriptTestCase):
        self.assertNoOutput(err)
        self.assertOutput(out, "Prints the CREATE TABLE, custom SQL and CREATE INDEX SQL statements for the given model module name(s).")

    def test_no_color(self):
        "--no-color prevent colorization of the output"
        out = StringIO()
        call_command("sqlall", "admin_scripts", no_color=True, stdout=out)
        self.assertEqual(out.getvalue(), """BEGIN;
CREATE TABLE "admin_scripts_article" (
    "id" integer NOT NULL PRIMARY KEY,
    "headline" varchar(100) NOT NULL,
    "pub_date" datetime NOT NULL
)
;

COMMIT;
""")

    def test_base_command(self):
        "User BaseCommands can execute when a label is provided"
        args = ['base_command', 'testlabel']
        out, err = self.run_manage(args)
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")

    def test_base_command_no_label(self):
        "User BaseCommands can execute when no labels are provided"
        args = ['base_command']
        out, err = self.run_manage(args)
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:BaseCommand labels=(), options=[('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:BaseCommand labels=(), options=[('no_color', False), ('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")

    def test_base_command_multiple_label(self):
        "User BaseCommands can execute when no labels are provided"
        args = ['base_command', 'testlabel', 'anotherlabel']
        out, err = self.run_manage(args)
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel', 'anotherlabel'), options=[('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel', 'anotherlabel'), options=[('no_color', False), ('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")

    def test_base_command_with_option(self):
        "User BaseCommands can execute with options when a label is provided"
        args = ['base_command', 'testlabel', '--option_a=x']
        out, err = self.run_manage(args)
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")

    def test_base_command_with_options(self):
        "User BaseCommands can execute with multiple options when a label is provided"
        args = ['base_command', 'testlabel', '-a', 'x', '--option_b=y']
        out, err = self.run_manage(args)
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")

    def test_base_run_from_argv(self):
        """
@@ -1351,7 +1373,7 @@ class CommandTypes(AdminScriptTestCase):
        args = ['noargs_command']
        out, err = self.run_manage(args)
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")

    def test_noargs_with_args(self):
        "NoArg Commands raise an error if an argument is provided"
@@ -1366,7 +1388,7 @@ class CommandTypes(AdminScriptTestCase):
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'")
        self.assertOutput(out, os.sep.join(['django', 'contrib', 'auth', 'models.py']))
        self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "'>, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")

    def test_app_command_no_apps(self):
        "User AppCommands raise an error when no app name is provided"
@@ -1381,10 +1403,10 @@ class CommandTypes(AdminScriptTestCase):
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'")
        self.assertOutput(out, os.sep.join(['django', 'contrib', 'auth', 'models.py']))
        self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "'>, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.contenttypes.models'")
        self.assertOutput(out, os.sep.join(['django', 'contrib', 'contenttypes', 'models.py']))
        self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "'>, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")

    def test_app_command_invalid_appname(self):
        "User AppCommands can execute when a single app name is provided"
@@ -1403,7 +1425,7 @@ class CommandTypes(AdminScriptTestCase):
        args = ['label_command', 'testlabel']
        out, err = self.run_manage(args)
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:LabelCommand label=testlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:LabelCommand label=testlabel, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")

    def test_label_command_no_label(self):
        "User LabelCommands raise an error if no label is provided"
@@ -1416,8 +1438,8 @@ class CommandTypes(AdminScriptTestCase):
        args = ['label_command', 'testlabel', 'anotherlabel']
        out, err = self.run_manage(args)
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:LabelCommand label=testlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:LabelCommand label=anotherlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:LabelCommand label=testlabel, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:LabelCommand label=anotherlabel, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")

class ArgumentOrder(AdminScriptTestCase):
    """Tests for 2-stage argument parsing scheme.
@@ -1441,35 +1463,35 @@ class ArgumentOrder(AdminScriptTestCase):
        args = ['base_command', 'testlabel', '--settings=alternate_settings', '--option_a=x']
        out, err = self.run_manage(args)
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")

    def test_setting_then_short_option(self):
        "Short options passed after settings are correctly handled"
        args = ['base_command', 'testlabel', '--settings=alternate_settings', '--option_a=x']
        out, err = self.run_manage(args)
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")

    def test_option_then_setting(self):
        "Options passed before settings are correctly handled"
        args = ['base_command', 'testlabel', '--option_a=x', '--settings=alternate_settings']
        out, err = self.run_manage(args)
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")

    def test_short_option_then_setting(self):
        "Short options passed before settings are correctly handled"
        args = ['base_command', 'testlabel', '-a', 'x', '--settings=alternate_settings']
        out, err = self.run_manage(args)
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")

    def test_option_then_setting_then_option(self):
        "Options are correctly handled when they are passed before and after a setting"
        args = ['base_command', 'testlabel', '--option_a=x', '--settings=alternate_settings', '--option_b=y']
        out, err = self.run_manage(args)
        self.assertNoOutput(err)
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
        self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")


class StartProject(LiveServerTestCase, AdminScriptTestCase):