Merge pull request #2122 from theotherjimmy/colorized-output

Colorized the short Warnings/Errors generated by the toolchains
pull/2162/head
Bogdan Marinescu 2016-07-13 14:21:15 +03:00 committed by GitHub
commit d0d023ab58
7 changed files with 133 additions and 1 deletions

View File

@ -28,6 +28,7 @@ sys.path.insert(0, ROOT)
from tools.toolchains import TOOLCHAINS
from tools.toolchains import mbedToolchain
from tools.targets import TARGET_NAMES, TARGET_MAP
from tools.options import get_default_options_parser
from tools.build_api import build_library, build_mbed_libs, build_lib
@ -36,6 +37,7 @@ from tools.build_api import static_analysis_scan, static_analysis_scan_lib, stat
from tools.build_api import print_build_results
from tools.settings import CPPCHECK_CMD, CPPCHECK_MSG_FORMAT
from utils import argparse_filestring_type
from tools.settings import CPPCHECK_CMD, CPPCHECK_MSG_FORMAT, CLI_COLOR_MAP
if __name__ == '__main__':
start = time()
@ -164,6 +166,17 @@ if __name__ == '__main__':
# Get toolchains list
toolchains = options.tool if options.tool else TOOLCHAINS
if options.color:
# This import happens late to prevent initializing colorization when we don't need it
import colorize
if options.verbose:
notify = mbedToolchain.print_notify_verbose
else:
notify = mbedToolchain.print_notify
notify = colorize.print_in_color_notifier(CLI_COLOR_MAP, notify)
else:
notify = None
# Get libraries list
libraries = []
@ -224,6 +237,7 @@ if __name__ == '__main__':
lib_build_res = build_library(options.source_dir, options.build_dir, mcu, toolchain,
options=options.options,
extra_verbose=options.extra_verbose_notify,
notify=notify,
verbose=options.verbose,
silent=options.silent,
jobs=options.jobs,
@ -235,6 +249,7 @@ if __name__ == '__main__':
lib_build_res = build_mbed_libs(mcu, toolchain,
options=options.options,
extra_verbose=options.extra_verbose_notify,
notify=notify,
verbose=options.verbose,
silent=options.silent,
jobs=options.jobs,
@ -245,6 +260,7 @@ if __name__ == '__main__':
build_lib(lib_id, mcu, toolchain,
options=options.options,
extra_verbose=options.extra_verbose_notify,
notify=notify,
verbose=options.verbose,
silent=options.silent,
clean=options.clean,

71
tools/colorize.py Normal file
View File

@ -0,0 +1,71 @@
"""
mbed SDK
Copyright (c) 2016 ARM Limited
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.
"""
""" This python file is responsible for generating colorized notifiers.
"""
import sys
import re
from colorama import init, Fore, Back, Style
init()
colors = {
'none' : "",
'default' : Style.RESET_ALL,
'black' : Fore.BLACK,
'red' : Fore.RED,
'green' : Fore.GREEN,
'yellow' : Fore.YELLOW,
'blue' : Fore.BLUE,
'magenta' : Fore.MAGENTA,
'cyan' : Fore.CYAN,
'white' : Fore.WHITE,
'on_black' : Back.BLACK,
'on_red' : Back.RED,
'on_green' : Back.GREEN,
'on_yellow' : Back.YELLOW,
'on_blue' : Back.BLUE,
'on_magenta' : Back.MAGENTA,
'on_cyan' : Back.CYAN,
'on_white' : Back.WHITE,
}
# Convert a color string from a string into an ascii escape code that will print
# that color on the terminal.
color_matcher = re.compile(r"(\w+)(\W+on\W+\w+)?")
def colorstring_to_escapecode(color_string):
match = re.match(color_matcher, color_string)
if match:
return colors[match.group(1)] + (colors[match.group(2).strip().replace(" ","_")] if match.group(2) else "")
else:
return corols['default']
# Wrap a toolchain notifier in a colorizer. This colorizer will wrap notifications
# in a color if the severity matches a color in the *color_map*.
def print_in_color_notifier (color_map, print_fn):
def wrap(event, silent=False):
fd = sys.stdout
self = event['toolchain']
if fd.isatty() and 'severity' in event and event['severity'] in color_map:
fd.write(colorstring_to_escapecode(color_map[event['severity']]))
print_fn(self, event, silent)
fd.write(colorstring_to_escapecode('default'))
else:
print_fn(self, event, silent)
return wrap

View File

@ -46,6 +46,8 @@ from tools.build_api import mcu_toolchain_matrix
from utils import argparse_filestring_type
from utils import argparse_many
from argparse import ArgumentTypeError
from tools.toolchains import mbedToolchain
from tools.settings import CLI_COLOR_MAP
if __name__ == '__main__':
# Parse Options
@ -212,6 +214,17 @@ if __name__ == '__main__':
args_error(parser, "[ERROR] You should specify a TOOLCHAIN")
toolchain = options.tool[0]
if options.color:
# This import happens late to prevent initializing colorization when we don't need it
import colorize
if options.verbose:
notify = mbedToolchain.print_notify_verbose
else:
notify = mbedToolchain.print_notify
notify = colorize.print_in_color_notifier(CLI_COLOR_MAP, notify)
else:
notify = None
# Test
for test_no in p:
test = Test(test_no)
@ -250,6 +263,7 @@ if __name__ == '__main__':
linker_script=options.linker_script,
clean=options.clean,
verbose=options.verbose,
notify=notify,
silent=options.silent,
macros=options.macros,
jobs=options.jobs,

View File

@ -37,6 +37,10 @@ def get_default_options_parser(add_clean=True, add_options=True):
metavar="TOOLCHAIN",
type=argparse_many(argparse_force_uppercase_type(toolchainlist, "toolchain")))
parser.add_argument("--color",
help="print Warnings, and Errors in color",
action="store_true", default=False)
if add_clean:
parser.add_argument("-c", "--clean", action="store_true", default=False,
help="clean the build directory")

View File

@ -51,6 +51,10 @@ BUILD_OPTIONS = []
# mbed.org username
MBED_ORG_USER = ""
CLI_COLOR_MAP = {
"warning": "yellow",
"error" : "red"
}
##############################################################################
# User Settings (file)

View File

@ -34,6 +34,8 @@ from tools.targets import TARGET_MAP
from tools.utils import mkdir, ToolException, NotSupportedException
from tools.test_exporters import ReportExporter, ResultExporterType
from utils import argparse_filestring_type, argparse_lowercase_type, argparse_many
from tools.toolchains import mbedToolchain
from tools.settings import CLI_COLOR_MAP
if __name__ == '__main__':
try:
@ -121,6 +123,17 @@ if __name__ == '__main__':
else:
tests = all_tests
if options.color:
# This import happens late to prevent initializing colorization when we don't need it
import colorize
if options.verbose:
notify = mbedToolchain.print_notify_verbose
else:
notify = mbedToolchain.print_notify
notify = colorize.print_in_color_notifier(CLI_COLOR_MAP, notify)
else:
notify = None
if options.list:
# Print available tests in order and exit
print_tests(tests, options.format)
@ -155,6 +168,7 @@ if __name__ == '__main__':
name="mbed-build",
macros=options.macros,
verbose=options.verbose,
notify=notify,
archive=False)
library_build_success = True
@ -179,6 +193,7 @@ if __name__ == '__main__':
properties=build_properties,
macros=options.macros,
verbose=options.verbose,
notify=notify,
jobs=options.jobs,
continue_on_build_fail=options.continue_on_build_fail)

View File

@ -274,6 +274,14 @@ class mbedToolchain:
self.legacy_ignore_dirs = LEGACY_IGNORE_DIRS - set([target.name, LEGACY_TOOLCHAIN_NAMES[self.name]])
# Output notify function
# This function is passed all events, and expected to handle notification of the
# user, emit the events to a log, etc.
# The API for all notify methods passed into the notify parameter is as follows:
# def notify(Event, Silent)
# Where *Event* is a dict representing the toolchain event that was generated
# e.g.: a compile succeeded, or a warning was emitted by the compiler
# or an application was linked
# *Silent* is a boolean
if notify:
self.notify_fun = notify
elif extra_verbose:
@ -338,7 +346,6 @@ class mbedToolchain:
event['severity'] = event['severity'].title()
event['file'] = basename(event['file'])
event['mcu_name'] = "None"
event['toolchain'] = "None"
event['target_name'] = event['target_name'].upper() if event['target_name'] else "Unknown"
event['toolchain_name'] = event['toolchain_name'].upper() if event['toolchain_name'] else "Unknown"
msg = '[%(severity)s] %(target_name)s::%(toolchain_name)s::%(file)s@%(line)s: %(message)s' % event
@ -351,6 +358,7 @@ class mbedToolchain:
def notify(self, event):
""" Little closure for notify functions
"""
event['toolchain'] = self
return self.notify_fun(event, self.silent)
def goanna_parse_line(self, line):