Skip to content

Commit d0d023a

Browse files
authored
Merge pull request #2122 from theotherjimmy/colorized-output
Colorized the short Warnings/Errors generated by the toolchains
2 parents e9d225b + e2c8837 commit d0d023a

File tree

7 files changed

+133
-1
lines changed

7 files changed

+133
-1
lines changed

tools/build.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929

3030
from tools.toolchains import TOOLCHAINS
31+
from tools.toolchains import mbedToolchain
3132
from tools.targets import TARGET_NAMES, TARGET_MAP
3233
from tools.options import get_default_options_parser
3334
from tools.build_api import build_library, build_mbed_libs, build_lib
@@ -36,6 +37,7 @@
3637
from tools.build_api import print_build_results
3738
from tools.settings import CPPCHECK_CMD, CPPCHECK_MSG_FORMAT
3839
from utils import argparse_filestring_type
40+
from tools.settings import CPPCHECK_CMD, CPPCHECK_MSG_FORMAT, CLI_COLOR_MAP
3941

4042
if __name__ == '__main__':
4143
start = time()
@@ -164,6 +166,17 @@
164166
# Get toolchains list
165167
toolchains = options.tool if options.tool else TOOLCHAINS
166168

169+
if options.color:
170+
# This import happens late to prevent initializing colorization when we don't need it
171+
import colorize
172+
if options.verbose:
173+
notify = mbedToolchain.print_notify_verbose
174+
else:
175+
notify = mbedToolchain.print_notify
176+
notify = colorize.print_in_color_notifier(CLI_COLOR_MAP, notify)
177+
else:
178+
notify = None
179+
167180
# Get libraries list
168181
libraries = []
169182

@@ -224,6 +237,7 @@
224237
lib_build_res = build_library(options.source_dir, options.build_dir, mcu, toolchain,
225238
options=options.options,
226239
extra_verbose=options.extra_verbose_notify,
240+
notify=notify,
227241
verbose=options.verbose,
228242
silent=options.silent,
229243
jobs=options.jobs,
@@ -235,6 +249,7 @@
235249
lib_build_res = build_mbed_libs(mcu, toolchain,
236250
options=options.options,
237251
extra_verbose=options.extra_verbose_notify,
252+
notify=notify,
238253
verbose=options.verbose,
239254
silent=options.silent,
240255
jobs=options.jobs,
@@ -245,6 +260,7 @@
245260
build_lib(lib_id, mcu, toolchain,
246261
options=options.options,
247262
extra_verbose=options.extra_verbose_notify,
263+
notify=notify,
248264
verbose=options.verbose,
249265
silent=options.silent,
250266
clean=options.clean,

tools/colorize.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
"""
2+
mbed SDK
3+
Copyright (c) 2016 ARM Limited
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
"""
17+
18+
""" This python file is responsible for generating colorized notifiers.
19+
"""
20+
21+
import sys
22+
import re
23+
from colorama import init, Fore, Back, Style
24+
init()
25+
26+
colors = {
27+
'none' : "",
28+
'default' : Style.RESET_ALL,
29+
30+
'black' : Fore.BLACK,
31+
'red' : Fore.RED,
32+
'green' : Fore.GREEN,
33+
'yellow' : Fore.YELLOW,
34+
'blue' : Fore.BLUE,
35+
'magenta' : Fore.MAGENTA,
36+
'cyan' : Fore.CYAN,
37+
'white' : Fore.WHITE,
38+
39+
'on_black' : Back.BLACK,
40+
'on_red' : Back.RED,
41+
'on_green' : Back.GREEN,
42+
'on_yellow' : Back.YELLOW,
43+
'on_blue' : Back.BLUE,
44+
'on_magenta' : Back.MAGENTA,
45+
'on_cyan' : Back.CYAN,
46+
'on_white' : Back.WHITE,
47+
}
48+
49+
# Convert a color string from a string into an ascii escape code that will print
50+
# that color on the terminal.
51+
color_matcher = re.compile(r"(\w+)(\W+on\W+\w+)?")
52+
def colorstring_to_escapecode(color_string):
53+
match = re.match(color_matcher, color_string)
54+
if match:
55+
return colors[match.group(1)] + (colors[match.group(2).strip().replace(" ","_")] if match.group(2) else "")
56+
else:
57+
return corols['default']
58+
59+
# Wrap a toolchain notifier in a colorizer. This colorizer will wrap notifications
60+
# in a color if the severity matches a color in the *color_map*.
61+
def print_in_color_notifier (color_map, print_fn):
62+
def wrap(event, silent=False):
63+
fd = sys.stdout
64+
self = event['toolchain']
65+
if fd.isatty() and 'severity' in event and event['severity'] in color_map:
66+
fd.write(colorstring_to_escapecode(color_map[event['severity']]))
67+
print_fn(self, event, silent)
68+
fd.write(colorstring_to_escapecode('default'))
69+
else:
70+
print_fn(self, event, silent)
71+
return wrap

tools/make.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
from utils import argparse_filestring_type
4747
from utils import argparse_many
4848
from argparse import ArgumentTypeError
49+
from tools.toolchains import mbedToolchain
50+
from tools.settings import CLI_COLOR_MAP
4951

5052
if __name__ == '__main__':
5153
# Parse Options
@@ -212,6 +214,17 @@
212214
args_error(parser, "[ERROR] You should specify a TOOLCHAIN")
213215
toolchain = options.tool[0]
214216

217+
if options.color:
218+
# This import happens late to prevent initializing colorization when we don't need it
219+
import colorize
220+
if options.verbose:
221+
notify = mbedToolchain.print_notify_verbose
222+
else:
223+
notify = mbedToolchain.print_notify
224+
notify = colorize.print_in_color_notifier(CLI_COLOR_MAP, notify)
225+
else:
226+
notify = None
227+
215228
# Test
216229
for test_no in p:
217230
test = Test(test_no)
@@ -250,6 +263,7 @@
250263
linker_script=options.linker_script,
251264
clean=options.clean,
252265
verbose=options.verbose,
266+
notify=notify,
253267
silent=options.silent,
254268
macros=options.macros,
255269
jobs=options.jobs,

tools/options.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ def get_default_options_parser(add_clean=True, add_options=True):
3737
metavar="TOOLCHAIN",
3838
type=argparse_many(argparse_force_uppercase_type(toolchainlist, "toolchain")))
3939

40+
parser.add_argument("--color",
41+
help="print Warnings, and Errors in color",
42+
action="store_true", default=False)
43+
4044
if add_clean:
4145
parser.add_argument("-c", "--clean", action="store_true", default=False,
4246
help="clean the build directory")

tools/settings.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@
5151
# mbed.org username
5252
MBED_ORG_USER = ""
5353

54+
CLI_COLOR_MAP = {
55+
"warning": "yellow",
56+
"error" : "red"
57+
}
5458

5559
##############################################################################
5660
# User Settings (file)

tools/test.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
from tools.utils import mkdir, ToolException, NotSupportedException
3535
from tools.test_exporters import ReportExporter, ResultExporterType
3636
from utils import argparse_filestring_type, argparse_lowercase_type, argparse_many
37+
from tools.toolchains import mbedToolchain
38+
from tools.settings import CLI_COLOR_MAP
3739

3840
if __name__ == '__main__':
3941
try:
@@ -121,6 +123,17 @@
121123
else:
122124
tests = all_tests
123125

126+
if options.color:
127+
# This import happens late to prevent initializing colorization when we don't need it
128+
import colorize
129+
if options.verbose:
130+
notify = mbedToolchain.print_notify_verbose
131+
else:
132+
notify = mbedToolchain.print_notify
133+
notify = colorize.print_in_color_notifier(CLI_COLOR_MAP, notify)
134+
else:
135+
notify = None
136+
124137
if options.list:
125138
# Print available tests in order and exit
126139
print_tests(tests, options.format)
@@ -155,6 +168,7 @@
155168
name="mbed-build",
156169
macros=options.macros,
157170
verbose=options.verbose,
171+
notify=notify,
158172
archive=False)
159173

160174
library_build_success = True
@@ -179,6 +193,7 @@
179193
properties=build_properties,
180194
macros=options.macros,
181195
verbose=options.verbose,
196+
notify=notify,
182197
jobs=options.jobs,
183198
continue_on_build_fail=options.continue_on_build_fail)
184199

tools/toolchains/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,14 @@ def __init__(self, target, options=None, notify=None, macros=None, silent=False,
274274
self.legacy_ignore_dirs = LEGACY_IGNORE_DIRS - set([target.name, LEGACY_TOOLCHAIN_NAMES[self.name]])
275275

276276
# Output notify function
277+
# This function is passed all events, and expected to handle notification of the
278+
# user, emit the events to a log, etc.
279+
# The API for all notify methods passed into the notify parameter is as follows:
280+
# def notify(Event, Silent)
281+
# Where *Event* is a dict representing the toolchain event that was generated
282+
# e.g.: a compile succeeded, or a warning was emitted by the compiler
283+
# or an application was linked
284+
# *Silent* is a boolean
277285
if notify:
278286
self.notify_fun = notify
279287
elif extra_verbose:
@@ -338,7 +346,6 @@ def print_notify_verbose(self, event, silent=False):
338346
event['severity'] = event['severity'].title()
339347
event['file'] = basename(event['file'])
340348
event['mcu_name'] = "None"
341-
event['toolchain'] = "None"
342349
event['target_name'] = event['target_name'].upper() if event['target_name'] else "Unknown"
343350
event['toolchain_name'] = event['toolchain_name'].upper() if event['toolchain_name'] else "Unknown"
344351
msg = '[%(severity)s] %(target_name)s::%(toolchain_name)s::%(file)s@%(line)s: %(message)s' % event
@@ -351,6 +358,7 @@ def print_notify_verbose(self, event, silent=False):
351358
def notify(self, event):
352359
""" Little closure for notify functions
353360
"""
361+
event['toolchain'] = self
354362
return self.notify_fun(event, self.silent)
355363

356364
def goanna_parse_line(self, line):

0 commit comments

Comments
 (0)