From d82326a39d70d7fe897dabd6bb85fa746905e1f4 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Mon, 19 Nov 2018 11:22:53 -0500 Subject: [PATCH] Add --color and --no-color options. By default, we auto-detect color mode (if it's a tty, color default on, else off). But you can force it either way. --- builder.py | 9 ++++++--- logs.py | 13 +++++++------ redo-ifchange.py | 2 +- redo-log.py | 4 ++-- redo.py | 5 ++++- vars.py | 1 + 6 files changed, 21 insertions(+), 13 deletions(-) diff --git a/builder.py b/builder.py index e4fcd09..aff26c7 100644 --- a/builder.py +++ b/builder.py @@ -22,7 +22,8 @@ def _try_stat(filename): log_reader_pid = None -def start_stdin_log_reader(status, details, pretty, debug_locks, debug_pids): +def start_stdin_log_reader(status, details, pretty, color, + debug_locks, debug_pids): if not vars.LOG: return global log_reader_pid r, w = os.pipe() # main pipe to redo-log @@ -47,7 +48,7 @@ def start_stdin_log_reader(status, details, pretty, debug_locks, debug_pids): os.dup2(w, 1) os.dup2(w, 2) os.close(w) - check_tty(sys.stderr) + check_tty(sys.stderr, vars.COLOR) else: # child try: @@ -64,8 +65,10 @@ def start_stdin_log_reader(status, details, pretty, debug_locks, debug_pids): ('--pretty' if pretty else '--no-pretty'), ('--debug-locks' if debug_locks else '--no-debug-locks'), ('--debug-pids' if debug_pids else '--no-debug-pids'), - '-' ] + if color != 1: + argv.append('--color' if color >= 2 else '--no-color') + argv.append('-') os.execvp(argv[0], argv) except Exception, e: sys.stderr.write('redo-log: exec: %s\n' % e) diff --git a/logs.py b/logs.py index 9073ba8..54a17ee 100644 --- a/logs.py +++ b/logs.py @@ -2,9 +2,10 @@ import os, re, sys, time import vars -def check_tty(file): +def check_tty(file, color): global RED, GREEN, YELLOW, BOLD, PLAIN - if file.isatty() and (os.environ.get('TERM') or 'dumb') != 'dumb': + color_ok = file.isatty() and (os.environ.get('TERM') or 'dumb') != 'dumb' + if (color and color_ok) or color >= 2: # ...use ANSI formatting codes. RED = "\x1b[31m" GREEN = "\x1b[32m" @@ -98,17 +99,17 @@ class PrettyLog(object): _log = None -def setup(file, pretty): +def setup(file, pretty, color): global _log if pretty or vars.PRETTY: - check_tty(file) + check_tty(file, color=color) _log = PrettyLog(file=file) else: _log = RawLog(file=file) -# FIXME: explicitly initialize in each program -setup(file=sys.stderr, pretty=False) +# FIXME: explicitly initialize in each program, for clarity +setup(file=sys.stderr, pretty=vars.PRETTY, color=vars.COLOR) def write(s): diff --git a/redo-ifchange.py b/redo-ifchange.py index 8982fe6..aae4212 100755 --- a/redo-ifchange.py +++ b/redo-ifchange.py @@ -21,7 +21,7 @@ rv = 202 try: if vars_init.is_toplevel: builder.start_stdin_log_reader(status=True, details=True, - pretty=True, debug_locks=False, debug_pids=False) + pretty=True, color=True, debug_locks=False, debug_pids=False) if vars.TARGET and not vars.UNLOCKED: me = os.path.join(vars.STARTDIR, os.path.join(vars.PWD, vars.TARGET)) diff --git a/redo-log.py b/redo-log.py index 7bfa85d..63f5503 100755 --- a/redo-log.py +++ b/redo-log.py @@ -10,9 +10,9 @@ r,recursive show build logs for dependencies too u,unchanged show lines for dependencies not needing to be rebuilt f,follow keep watching for more lines to be appended (like tail -f) no-details only show 'redo' recursion trace, not build output -no-colorize don't colorize 'redo' log messages no-status don't display build summary line in --follow no-pretty don't pretty-print logs, show raw @@REDO output instead +no-color disable ANSI color; --color to force enable (default: auto) debug-locks print messages about file locking (useful for debugging) debug-pids print process ids in log messages (useful for debugging) ack-fd= (internal use only) print REDO-OK to this fd upon starting @@ -211,7 +211,7 @@ try: sys.exit(1) if opt.status < 2 and not os.isatty(2): opt.status = False - logs.setup(file=sys.stdout, pretty=opt.pretty) + logs.setup(file=sys.stdout, pretty=opt.pretty, color=opt.color) if opt.debug_locks: vars.DEBUG_LOCKS = 1 if opt.debug_pids: diff --git a/redo.py b/redo.py index b4e4fc6..26fcb8c 100755 --- a/redo.py +++ b/redo.py @@ -16,6 +16,7 @@ no-details only show 'redo' recursion trace (to see more later, use redo-log) no-status don't display build summary line at the bottom of the screen no-log don't capture error output, just let it flow straight to stderr no-pretty don't pretty-print logs, show raw @@REDO output instead +no-color disable ANSI color; --color to force enable (default: auto) debug-locks print messages about file locking (useful for debugging) debug-pids print process ids as part of log messages (useful for debugging) version print the current version and exit @@ -51,6 +52,8 @@ if opt.no_log: os.environ['REDO_LOG'] = '0' if opt.no_pretty: os.environ['REDO_PRETTY'] = '0' + if opt.no_color: + os.environ['REDO_COLOR'] = '0' import vars_init vars_init.init(targets) @@ -61,7 +64,7 @@ from logs import warn, err try: if vars_init.is_toplevel: builder.start_stdin_log_reader(status=opt.status, details=opt.details, - pretty=opt.pretty, + pretty=opt.pretty, color=opt.color, debug_locks=opt.debug_locks, debug_pids=opt.debug_pids) for t in targets: if os.path.exists(t): diff --git a/vars.py b/vars.py index d2bda0b..3b95915 100644 --- a/vars.py +++ b/vars.py @@ -17,6 +17,7 @@ VERBOSE = os.environ.get('REDO_VERBOSE', '') and 1 or 0 XTRACE = os.environ.get('REDO_XTRACE', '') and 1 or 0 KEEP_GOING = os.environ.get('REDO_KEEP_GOING', '') and 1 or 0 LOG = atoi(os.environ.get('REDO_LOG', '1')) # defaults on +COLOR = atoi(os.environ.get('REDO_COLOR', '1')) # defaults on # subprocesses mustn't pretty-print if a parent is running redo-log PRETTY = (not LOG) and atoi(os.environ.get('REDO_PRETTY', '1')) SHUFFLE = os.environ.get('REDO_SHUFFLE', '') and 1 or 0