Skip to content

Commit 5c16cd3

Browse files
committed
Implement color terminal notifications
You can turn them on with MBED_COLOR=True
1 parent fcf7dbf commit 5c16cd3

File tree

4 files changed

+80
-89
lines changed

4 files changed

+80
-89
lines changed

tools/colorize.py

Lines changed: 0 additions & 80 deletions
This file was deleted.

tools/make.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@
5555
from utils import argparse_many
5656
from utils import argparse_dir_not_parent
5757
from tools.toolchains import mbedToolchain, TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS
58-
from tools.settings import CLI_COLOR_MAP
5958

6059
if __name__ == '__main__':
6160
# Parse Options
@@ -233,7 +232,7 @@
233232
args_error(parser, "argument --build is required when argument --source is provided")
234233

235234

236-
notify = TerminalNotifier(options.verbose, options.silent)
235+
notify = TerminalNotifier(options.verbose, options.silent, options.color)
237236

238237
if not TOOLCHAIN_CLASSES[toolchain].check_executable():
239238
search_path = TOOLCHAIN_PATHS[toolchain] or "No path set"

tools/notifier/term.py

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,49 @@
1515

1616
from __future__ import print_function, division, absolute_import
1717

18+
import re
19+
import sys
1820
from os.path import basename
1921

2022
from . import Notifier
21-
from ..settings import PRINT_COMPILER_OUTPUT_AS_LINK
23+
from ..settings import (PRINT_COMPILER_OUTPUT_AS_LINK,
24+
CLI_COLOR_MAP, COLOR)
2225

2326
class TerminalNotifier(Notifier):
2427
"""
25-
Writes notifications to a terminal based on a silent and verbose flag.
28+
Writes notifications to a terminal based on silent, verbose and color flags.
2629
"""
2730

28-
def __init__(self, verbose=False, silent=False):
31+
def __init__(self, verbose=False, silent=False, color=False):
2932
self.verbose = verbose
3033
self.silent = silent
3134
self.output = ""
35+
self.color = color or COLOR
36+
if self.color:
37+
from colorama import init, Fore, Back, Style
38+
init()
39+
self.COLORS = {
40+
'none' : "",
41+
'default' : Style.RESET_ALL,
42+
43+
'black' : Fore.BLACK,
44+
'red' : Fore.RED,
45+
'green' : Fore.GREEN,
46+
'yellow' : Fore.YELLOW,
47+
'blue' : Fore.BLUE,
48+
'magenta' : Fore.MAGENTA,
49+
'cyan' : Fore.CYAN,
50+
'white' : Fore.WHITE,
51+
52+
'on_black' : Back.BLACK,
53+
'on_red' : Back.RED,
54+
'on_green' : Back.GREEN,
55+
'on_yellow' : Back.YELLOW,
56+
'on_blue' : Back.BLUE,
57+
'on_magenta' : Back.MAGENTA,
58+
'on_cyan' : Back.CYAN,
59+
'on_white' : Back.WHITE,
60+
}
3261

3362
def get_output(self):
3463
return self.output
@@ -40,7 +69,10 @@ def notify(self, event):
4069
msg = self.print_notify(event)
4170
if msg:
4271
if not self.silent:
43-
print(msg)
72+
if self.color:
73+
self.print_in_color(event, msg)
74+
else:
75+
print(msg)
4476
self.output += msg + "\n"
4577

4678
def print_notify(self, event):
@@ -87,3 +119,33 @@ def print_notify_verbose(self, event):
87119

88120
elif event['type'] == 'progress':
89121
return self.print_notify(event) # standard handle
122+
123+
COLOR_MATCHER = re.compile(r"(\w+)(\W+on\W+\w+)?")
124+
def colorstring_to_escapecode(self, color_string):
125+
""" Convert a color string from a string into an ascii escape code that
126+
will print that color on the terminal.
127+
128+
Positional arguments:
129+
color_string - the string to parse
130+
"""
131+
match = re.match(self.COLOR_MATCHER, color_string)
132+
if match:
133+
return self.COLORS[match.group(1)] + \
134+
(self.COLORS[match.group(2).strip().replace(" ", "_")]
135+
if match.group(2) else "")
136+
else:
137+
return self.COLORS['default']
138+
139+
def print_in_color(self, event, msg):
140+
""" Wrap a toolchain notifier in a colorizer. This colorizer will wrap
141+
notifications in a color if the severity matches a color in the
142+
CLI_COLOR_MAP.
143+
"""
144+
"""The notification function inself"""
145+
if sys.stdout.isatty() and event.get('severity', None) in CLI_COLOR_MAP:
146+
sys.stdout.write(self.colorstring_to_escapecode(
147+
CLI_COLOR_MAP[event['severity']]))
148+
print(msg)
149+
sys.stdout.write(self.colorstring_to_escapecode('default'))
150+
else:
151+
print(msg)

tools/settings.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
# Goanna static analyser. Please overload it in mbed_settings.py
4646
GOANNA_PATH = ""
4747

48+
4849
# cppcheck path (command) and output message format
4950
CPPCHECK_CMD = ["cppcheck", "--enable=all"]
5051
CPPCHECK_MSG_FORMAT = ["--template=[{severity}] {file}@{line}: {id}:{message}"]
@@ -57,9 +58,12 @@
5758
# Print compiler warnings and errors as link format
5859
PRINT_COMPILER_OUTPUT_AS_LINK = False
5960

61+
# Print warnings/errors in color
62+
COLOR = False
63+
6064
CLI_COLOR_MAP = {
61-
"warning": "yellow",
62-
"error" : "red"
65+
"Warning": "yellow",
66+
"Error" : "red"
6367
}
6468

6569
##############################################################################
@@ -77,7 +81,7 @@
7781
# User Settings (env vars)
7882
##############################################################################
7983
_ENV_PATHS = ['ARM_PATH', 'GCC_ARM_PATH', 'GCC_CR_PATH', 'IAR_PATH',
80-
'ARMC6_PATH', 'PRINT_COMPILER_OUTPUT_AS_LINK']
84+
'ARMC6_PATH']
8185

8286
for _n in _ENV_PATHS:
8387
if getenv('MBED_'+_n):
@@ -87,6 +91,12 @@
8791
print("WARNING: MBED_%s set as environment variable but doesn't"
8892
" exist" % _n)
8993

94+
_ENV_VARS = ['PRINT_COMPILER_OUTPUT_AS_LINK', 'COLOR']
95+
for _n in _ENV_VARS:
96+
value = getenv('MBED_%s' % _n)
97+
if value:
98+
globals()[_n] = value
99+
90100

91101
##############################################################################
92102
# Test System Settings

0 commit comments

Comments
 (0)