xds-k8s: Colorize all the things (#26845)
parent
4271d1a482
commit
4742f99457
7 changed files with 122 additions and 9 deletions
@ -0,0 +1,99 @@ |
|||||||
|
# Copyright 2021 gRPC authors. |
||||||
|
# |
||||||
|
# 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. |
||||||
|
"""The module contains helpers to enable color output in terminals. |
||||||
|
|
||||||
|
Use this to log resources dumped as a structured document (f.e. YAML), |
||||||
|
and enable colorful syntax highlighting. |
||||||
|
|
||||||
|
TODO(sergiitk): This can be used to output protobuf responses formatted as JSON. |
||||||
|
""" |
||||||
|
import logging |
||||||
|
from typing import Optional |
||||||
|
|
||||||
|
from absl import flags |
||||||
|
import pygments |
||||||
|
import pygments.formatter |
||||||
|
import pygments.formatters.other |
||||||
|
import pygments.formatters.terminal |
||||||
|
import pygments.formatters.terminal256 |
||||||
|
import pygments.lexer |
||||||
|
import pygments.lexers.data |
||||||
|
import pygments.styles |
||||||
|
|
||||||
|
# The style for terminals supporting 8/16 colors. |
||||||
|
STYLE_ANSI_16 = 'ansi16' |
||||||
|
# Join with pygments styles for terminals supporting 88/256 colors. |
||||||
|
ALL_COLOR_STYLES = [STYLE_ANSI_16] + list(pygments.styles.get_all_styles()) |
||||||
|
|
||||||
|
# Flags. |
||||||
|
COLOR = flags.DEFINE_bool("color", default=True, help='Colorize the output') |
||||||
|
COLOR_STYLE = flags.DEFINE_enum( |
||||||
|
"color_style", |
||||||
|
default='material', |
||||||
|
enum_values=ALL_COLOR_STYLES, |
||||||
|
help=('Color styles for terminals supporting 256 colors. ' |
||||||
|
f'Use {STYLE_ANSI_16} style for terminals supporting 8/16 colors')) |
||||||
|
|
||||||
|
logger = logging.getLogger(__name__) |
||||||
|
|
||||||
|
# Type aliases. |
||||||
|
Lexer = pygments.lexer.Lexer |
||||||
|
YamlLexer = pygments.lexers.data.YamlLexer |
||||||
|
Formatter = pygments.formatter.Formatter |
||||||
|
NullFormatter = pygments.formatters.other.NullFormatter |
||||||
|
TerminalFormatter = pygments.formatters.terminal.TerminalFormatter |
||||||
|
Terminal256Formatter = pygments.formatters.terminal256.Terminal256Formatter |
||||||
|
|
||||||
|
|
||||||
|
class Highlighter: |
||||||
|
formatter: Formatter |
||||||
|
lexer: Lexer |
||||||
|
color: bool |
||||||
|
color_style: Optional[str] = None |
||||||
|
|
||||||
|
def __init__(self, |
||||||
|
*, |
||||||
|
lexer: Lexer, |
||||||
|
color: Optional[bool] = None, |
||||||
|
color_style: Optional[str] = None): |
||||||
|
self.lexer = lexer |
||||||
|
self.color = color if color is not None else COLOR.value |
||||||
|
|
||||||
|
if self.color: |
||||||
|
color_style = color_style if color_style else COLOR_STYLE.value |
||||||
|
if color_style not in ALL_COLOR_STYLES: |
||||||
|
raise ValueError(f'Unrecognized color style {color_style}, ' |
||||||
|
f'valid styles: {ALL_COLOR_STYLES}') |
||||||
|
if color_style == STYLE_ANSI_16: |
||||||
|
# 8/16 colors support only. |
||||||
|
self.formatter = TerminalFormatter() |
||||||
|
else: |
||||||
|
# 88/256 colors. |
||||||
|
self.formatter = Terminal256Formatter(style=color_style) |
||||||
|
else: |
||||||
|
self.formatter = NullFormatter() |
||||||
|
|
||||||
|
def highlight(self, code: str) -> str: |
||||||
|
return pygments.highlight(code, self.lexer, self.formatter) |
||||||
|
|
||||||
|
|
||||||
|
class HighlighterYaml(Highlighter): |
||||||
|
|
||||||
|
def __init__(self, |
||||||
|
*, |
||||||
|
color: Optional[bool] = None, |
||||||
|
color_style: Optional[str] = None): |
||||||
|
super().__init__(lexer=YamlLexer(encoding='utf-8'), |
||||||
|
color=color, |
||||||
|
color_style=color_style) |
Loading…
Reference in new issue