mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
902665bce6
If you want to turn off colors for commands, you have to manually adjust the git config settings (in various locations). If you're writing scripts though, you often don't want to modify those locations. Add a commandline option to explicitly control things. The default behavior is unchanged -- we still scan the config files. Change-Id: I54a3fd8e1918bac180aadd7c7d3004f069b02522
207 lines
4.5 KiB
Python
207 lines
4.5 KiB
Python
#
|
|
# Copyright (C) 2008 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import os
|
|
import sys
|
|
|
|
import pager
|
|
|
|
COLORS = {None :-1,
|
|
'normal' :-1,
|
|
'black' : 0,
|
|
'red' : 1,
|
|
'green' : 2,
|
|
'yellow' : 3,
|
|
'blue' : 4,
|
|
'magenta': 5,
|
|
'cyan' : 6,
|
|
'white' : 7}
|
|
|
|
ATTRS = {None :-1,
|
|
'bold' : 1,
|
|
'dim' : 2,
|
|
'ul' : 4,
|
|
'blink' : 5,
|
|
'reverse': 7}
|
|
|
|
RESET = "\033[m" # pylint: disable=W1401
|
|
# backslash is not anomalous
|
|
|
|
def is_color(s):
|
|
return s in COLORS
|
|
|
|
def is_attr(s):
|
|
return s in ATTRS
|
|
|
|
def _Color(fg = None, bg = None, attr = None):
|
|
fg = COLORS[fg]
|
|
bg = COLORS[bg]
|
|
attr = ATTRS[attr]
|
|
|
|
if attr >= 0 or fg >= 0 or bg >= 0:
|
|
need_sep = False
|
|
code = "\033[" #pylint: disable=W1401
|
|
|
|
if attr >= 0:
|
|
code += chr(ord('0') + attr)
|
|
need_sep = True
|
|
|
|
if fg >= 0:
|
|
if need_sep:
|
|
code += ';'
|
|
need_sep = True
|
|
|
|
if fg < 8:
|
|
code += '3%c' % (ord('0') + fg)
|
|
else:
|
|
code += '38;5;%d' % fg
|
|
|
|
if bg >= 0:
|
|
if need_sep:
|
|
code += ';'
|
|
need_sep = True
|
|
|
|
if bg < 8:
|
|
code += '4%c' % (ord('0') + bg)
|
|
else:
|
|
code += '48;5;%d' % bg
|
|
code += 'm'
|
|
else:
|
|
code = ''
|
|
return code
|
|
|
|
|
|
DEFAULT = None
|
|
|
|
def SetDefaultColoring(state):
|
|
"""Set coloring behavior to |state|.
|
|
|
|
This is useful for overriding config options via the command line.
|
|
"""
|
|
if state is None:
|
|
# Leave it alone -- return quick!
|
|
return
|
|
|
|
global DEFAULT
|
|
state = state.lower()
|
|
if state in ('auto',):
|
|
DEFAULT = state
|
|
elif state in ('always', 'yes', 'true', True):
|
|
DEFAULT = 'always'
|
|
elif state in ('never', 'no', 'false', False):
|
|
DEFAULT = 'never'
|
|
|
|
|
|
class Coloring(object):
|
|
def __init__(self, config, section_type):
|
|
self._section = 'color.%s' % section_type
|
|
self._config = config
|
|
self._out = sys.stdout
|
|
|
|
on = DEFAULT
|
|
if on is None:
|
|
on = self._config.GetString(self._section)
|
|
if on is None:
|
|
on = self._config.GetString('color.ui')
|
|
|
|
if on == 'auto':
|
|
if pager.active or os.isatty(1):
|
|
self._on = True
|
|
else:
|
|
self._on = False
|
|
elif on in ('true', 'always'):
|
|
self._on = True
|
|
else:
|
|
self._on = False
|
|
|
|
def redirect(self, out):
|
|
self._out = out
|
|
|
|
@property
|
|
def is_on(self):
|
|
return self._on
|
|
|
|
def write(self, fmt, *args):
|
|
self._out.write(fmt % args)
|
|
|
|
def flush(self):
|
|
self._out.flush()
|
|
|
|
def nl(self):
|
|
self._out.write('\n')
|
|
|
|
def printer(self, opt=None, fg=None, bg=None, attr=None):
|
|
s = self
|
|
c = self.colorer(opt, fg, bg, attr)
|
|
def f(fmt, *args):
|
|
s._out.write(c(fmt, *args))
|
|
return f
|
|
|
|
def nofmt_printer(self, opt=None, fg=None, bg=None, attr=None):
|
|
s = self
|
|
c = self.nofmt_colorer(opt, fg, bg, attr)
|
|
def f(fmt):
|
|
s._out.write(c(fmt))
|
|
return f
|
|
|
|
def colorer(self, opt=None, fg=None, bg=None, attr=None):
|
|
if self._on:
|
|
c = self._parse(opt, fg, bg, attr)
|
|
def f(fmt, *args):
|
|
output = fmt % args
|
|
return ''.join([c, output, RESET])
|
|
return f
|
|
else:
|
|
def f(fmt, *args):
|
|
return fmt % args
|
|
return f
|
|
|
|
def nofmt_colorer(self, opt=None, fg=None, bg=None, attr=None):
|
|
if self._on:
|
|
c = self._parse(opt, fg, bg, attr)
|
|
def f(fmt):
|
|
return ''.join([c, fmt, RESET])
|
|
return f
|
|
else:
|
|
def f(fmt):
|
|
return fmt
|
|
return f
|
|
|
|
def _parse(self, opt, fg, bg, attr):
|
|
if not opt:
|
|
return _Color(fg, bg, attr)
|
|
|
|
v = self._config.GetString('%s.%s' % (self._section, opt))
|
|
if v is None:
|
|
return _Color(fg, bg, attr)
|
|
|
|
v = v.strip().lower()
|
|
if v == "reset":
|
|
return RESET
|
|
elif v == '':
|
|
return _Color(fg, bg, attr)
|
|
|
|
have_fg = False
|
|
for a in v.split(' '):
|
|
if is_color(a):
|
|
if have_fg:
|
|
bg = a
|
|
else:
|
|
fg = a
|
|
elif is_attr(a):
|
|
attr = a
|
|
|
|
return _Color(fg, bg, attr)
|