diff --git a/test/parallel_testsuite.py b/test/parallel_testsuite.py index 778e1e8361495..c35029b04ac0b 100644 --- a/test/parallel_testsuite.py +++ b/test/parallel_testsuite.py @@ -16,7 +16,7 @@ import common from common import errlog -from tools.diagnostics import with_color, CYAN, GREEN, RED +from tools.colored_logger import with_color, CYAN, GREEN, RED from tools.utils import WINDOWS diff --git a/tools/cmdline.py b/tools/cmdline.py index 0f27b3c4bae8c..f263110faf3d7 100644 --- a/tools/cmdline.py +++ b/tools/cmdline.py @@ -510,9 +510,9 @@ def consume_arg_file(): elif check_flag('--threadprofiler'): settings_changes.append('PTHREADS_PROFILING=1') elif arg in ('-fcolor-diagnostics', '-fdiagnostics-color', '-fdiagnostics-color=always'): - diagnostics.color_enabled = True - elif arg in ('-fno-color-diagnostics', '-fdiagnostics-color=never'): - diagnostics.color_enabled = False + colored_logger.enable(force=True) + elif arg in ('-fno-color-diagnostics', '-fno-diagnostics-color', '-fdiagnostics-color=never'): + colored_logger.disable() elif arg == '-fno-exceptions': settings.DISABLE_EXCEPTION_CATCHING = 1 settings.DISABLE_EXCEPTION_THROWING = 1 @@ -568,9 +568,6 @@ def consume_arg_file(): settings.USE_PTHREADS = 0 elif arg == '-pthreads': exit_with_error('unrecognized command-line option `-pthreads`; did you mean `-pthread`?') - elif arg in ('-fno-diagnostics-color', '-fdiagnostics-color=never'): - colored_logger.disable() - diagnostics.color_enabled = False elif arg == '-fno-rtti': settings.USE_RTTI = 0 elif arg == '-frtti': diff --git a/tools/colored_logger.py b/tools/colored_logger.py index b5e90ca2206e5..f32505e36be28 100644 --- a/tools/colored_logger.py +++ b/tools/colored_logger.py @@ -4,11 +4,56 @@ # found in the LICENSE file. """Enables colored logger just by importing this module + +Also, provides utiliy functions to use ANSI colors in the terminal. """ import ctypes import sys import logging +from functools import wraps + + +# ANSI colors +RED = 1 +GREEN = 2 +YELLOW = 3 +BLUE = 4 +MAGENTA = 5 +CYAN = 6 +WHITE = 7 + +color_enabled = False + + +def output_color(color): + if color_enabled: + return '\033[3%sm' % color + return '' + + +def bold(): + if color_enabled: + return '\033[1m' + return '' + + +def reset_color(): + if color_enabled: + return '\033[0m' + return '' + + +def with_bold_color(color, string): + return output_color(color) + bold() + string + reset_color() + + +def with_color(color, string): + return output_color(color) + string + reset_color() + + +def with_bold(string): + return bold() + string + reset_color() def ansi_color_available(): @@ -34,30 +79,35 @@ def ansi_color_available(): def add_coloring_to_emit_ansi(fn): # add methods we need to the class + @wraps(fn) def new(*args): levelno = args[1].levelno + color = None if levelno >= 40: - color = '\x1b[31m' # red + color = RED elif levelno >= 30: - color = '\x1b[33m' # yellow + color = YELLOW elif levelno >= 20: - color = '\x1b[32m' # green + color = GREEN elif levelno >= 10: - color = '\x1b[35m' # pink - else: - color = '\x1b[0m' # normal - args[1].msg = color + args[1].msg + '\x1b[0m' # normal + color = MAGENTA + if color: + args[1].msg = with_color(color, args[1].msg) return fn(*args) new.orig_func = fn return new -def enable(): - if ansi_color_available(): +def enable(force=False): + global color_enabled + if force or ansi_color_available(): logging.StreamHandler.emit = add_coloring_to_emit_ansi(logging.StreamHandler.emit) + color_enabled = True def disable(): + global color_enabled if hasattr(logging.StreamHandler.emit, 'orig_func'): logging.StreamHandler.emit = logging.StreamHandler.emit.orig_func + color_enabled = False diff --git a/tools/diagnostics.py b/tools/diagnostics.py index f3989f84baa8c..cd0701a762940 100644 --- a/tools/diagnostics.py +++ b/tools/diagnostics.py @@ -13,7 +13,6 @@ from . import colored_logger -color_enabled = colored_logger.ansi_color_available() logger = logging.getLogger('diagnostics') tool_name = os.path.splitext(os.path.basename(sys.argv[0]))[0] @@ -21,19 +20,10 @@ WARN = 1 ERROR = 2 -# available (ANSI) colors -RED = 1 -GREEN = 2 -YELLOW = 3 -BLUE = 4 -MAGENTA = 5 -CYAN = 6 -WHITE = 7 - # color for use for each diagnostic level level_colors = { - WARN: MAGENTA, - ERROR: RED, + WARN: colored_logger.MAGENTA, + ERROR: colored_logger.RED, } level_prefixes = { @@ -42,55 +32,19 @@ } -def output_color(color): - if color_enabled: - return '\033[3%sm' % color - return '' - - -def bold(): - if color_enabled: - return '\033[1m' - return '' - - -def reset_color(): - if color_enabled: - return '\033[0m' - return '' - - -def with_color(color, text): - return output_color(color) + text + reset_color() - - def diag(level, msg, *args): # Format output message as: # : : msg - # With the `:` part being colored accordingly. - sys.stderr.write(tool_name + ': ') - - if color_enabled: - output = output_color(level_colors[level]) + bold() - if output: - sys.stderr.write(output) - - sys.stderr.write(level_prefixes[level]) - - if color_enabled: - output = reset_color() + bold() - if output: - sys.stderr.write(output) - + # With the `:` part being colored accordingly, and the message itself in bold. + prefix = level_prefixes[level] + color = level_colors[level] if args: msg = msg % args - sys.stderr.write(str(msg)) - sys.stderr.write('\n') - if color_enabled: - output = reset_color() - if output: - sys.stderr.write(output) + # Add colors + prefix = colored_logger.with_bold_color(color, prefix) + msg = colored_logger.with_bold(msg) + sys.stderr.write(f'{tool_name}: {prefix}{msg}\n') def error(msg, *args):