New option --color to control the coloring, and split the coloring from the output synchronization code

This commit is contained in:
Thomas Nagy 2014-01-05 01:39:32 +01:00
parent fa5f149775
commit 4107a0e29d
No known key found for this signature in database
GPG Key ID: 67A565EDFDF90E64
3 changed files with 65 additions and 59 deletions

View File

@ -7,51 +7,18 @@ logging, colors, terminal width and pretty-print
"""
import os, re, traceback, sys
from waflib import ansiterm
_nocolor = os.environ.get('NOCOLOR', 'no') not in ('no', '0', 'false')
try:
if not _nocolor:
import waflib.ansiterm
except ImportError:
pass
if not os.environ.get('NOSYNC', False):
# synchronized output is nearly mandatory to prevent garbled output
if sys.stdout.isatty() and id(sys.stdout) == id(sys.__stdout__):
sys.stdout = ansiterm.AnsiTerm(sys.stdout)
os.environ['TERM'] = 'vt100' # <- not sure about this
if sys.stderr.isatty() and id(sys.stderr) == id(sys.__stderr__):
sys.stderr = ansiterm.AnsiTerm(sys.stderr)
os.environ['TERM'] = 'vt100' # <- not sure about this
try:
import threading
except ImportError:
if not 'JOBS' in os.environ:
# no threading :-(
os.environ['JOBS'] = '1'
else:
wlock = threading.Lock()
class sync_stream(object):
def __init__(self, stream):
self.stream = stream
self.encoding = self.stream.encoding
def write(self, txt):
try:
wlock.acquire()
self.stream.write(txt)
self.stream.flush()
finally:
wlock.release()
def fileno(self):
return self.stream.fileno()
def flush(self):
self.stream.flush()
def isatty(self):
return self.stream.isatty()
if not os.environ.get('NOSYNC', False):
if id(sys.stdout) == id(sys.__stdout__):
sys.stdout = sync_stream(sys.stdout)
sys.stderr = sync_stream(sys.stderr)
import logging # import other modules only after
import logging # the logging module keeps holds reference on sys.stderr
LOG_FORMAT = "%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s"
HOUR_FORMAT = "%H:%M:%S"
@ -73,15 +40,17 @@ colors_lst = {
'cursor_off' :'\x1b[?25l',
}
got_tty = not os.environ.get('TERM', 'dumb') in ['dumb', 'emacs']
if got_tty:
try:
got_tty = sys.stderr.isatty() and sys.stdout.isatty()
except AttributeError:
got_tty = False
if (not got_tty and os.environ.get('TERM', 'dumb') != 'msys') or _nocolor:
colors_lst['USE'] = False
def enable_colors(level):
if level == 0:
colors_lst['USE'] = False
elif level == 1:
# and here we guess
term = os.environ.get('TERM', '')
if term in ['dumb', 'emacs']:
colors_lst['USE'] = False
pass
else:
colors_lst['USE'] = True
def get_term_cols():
return 80

View File

@ -14,6 +14,13 @@ as well as custom ones, used by the ``options`` wscript function.
import os, tempfile, optparse, sys, re
from waflib import Logs, Utils, Context
try:
import threading
except ImportError:
if not 'JOBS' in os.environ:
# no threading :-(
os.environ['JOBS'] = '1'
cmds = 'distclean configure build install clean uninstall check dist distcheck'.split()
"""
Constant representing the default waf commands displayed in::
@ -51,6 +58,7 @@ class opt_parser(optparse.OptionParser):
self.ctx = ctx
jobs = ctx.jobs()
p('-c', '--color', dest='colors', default='auto', action='store', help='whether to use colors (always/auto/never) [default: auto]')
p('-j', '--jobs', dest='jobs', default=jobs, type='int', help='amount of parallel jobs (%r)' % jobs)
p('-k', '--keep', dest='keep', default=0, action='count', help='keep running happily even if errors are found')
p('-v', '--verbose', dest='verbose', default=0, action='count', help='verbosity level -v -vv or -vvv [default: 0]')
@ -242,6 +250,15 @@ class OptionsContext(Context.Context):
if options.verbose >= 1:
self.load('errcheck')
try:
colors = {'always' : 2, 'auto' : 1, 'never' : 0}[options.colors]
except KeyError:
self.parser.error('Bad option "%s" for --color option' % options.colors)
else:
if os.environ.get('NOCOLOR', ''):
colors = 0
Logs.enable_colors(colors)
def execute(self):
"""
See :py:func:`waflib.Context.Context.execute`

View File

@ -11,12 +11,35 @@ console commands.
"""
import sys, os, re, threading
import re
from waflib.Utils import threading
wlock = threading.Lock()
try:
from ctypes import Structure, windll, c_short, c_ulong, c_int, byref, c_wchar
except ImportError:
pass
class AnsiTerm(object):
def __init__(self, stream):
self.stream = stream
self.encoding = self.stream.encoding
def write(self, txt):
try:
wlock.acquire()
self.stream.write(txt)
self.stream.flush()
finally:
wlock.release()
def fileno(self):
return self.stream.fileno()
def flush(self):
self.stream.flush()
def isatty(self):
return self.stream.isatty()
else:
class COORD(Structure):
@ -37,7 +60,6 @@ else:
_type = str
to_int = lambda number, default: number and int(number) or default
wlock = threading.Lock()
STD_OUTPUT_HANDLE = -11
STD_ERROR_HANDLE = -12
@ -230,6 +252,8 @@ else:
else:
self.writeconsole(txt)
else:
# no support for colors in the console, just output the text:
# eclipse or msys may be able to interpret the escape sequences
self.stream.write(text)
finally:
wlock.release()
@ -265,8 +289,4 @@ else:
def isatty(self):
return self._isatty
if sys.stdout.isatty() or sys.stderr.isatty():
sys.stderr = AnsiTerm(sys.stderr)
sys.stdout = AnsiTerm(sys.stdout)
os.environ['TERM'] = 'vt100'