colorise issue messages

Summary:public
Add colors to errors and warnings reported by infer

Reviewed By: cristianoc

Differential Revision: D3023927

fb-gh-sync-id: 555bb8f
shipit-source-id: 555bb8f
master
Jules Villard 9 years ago committed by Facebook Github Bot 8
parent b03304e0d8
commit 527d26dd91

@ -24,6 +24,75 @@ PLAIN_FORMATTER = 0
TERMINAL_FORMATTER = 1
def terminal_only(s):
if not sys.stdout.isatty():
return ''
return s
BLUE = terminal_only('\033[34m')
BLUE_BG = terminal_only('\033[44m')
MAGENTA = terminal_only('\033[35m')
MAGENTA_BG = terminal_only('\033[45m')
BRIGHT = terminal_only('\033[1m')
DIM = terminal_only('\033[2m')
RED = terminal_only('\033[31m')
RESET = terminal_only('\033[0m')
WHITE = terminal_only('\033[37m')
WHITE_BG = terminal_only('\033[47m')
YELLOW = terminal_only('\033[35m')
ERROR = RED
HEADER = BRIGHT
SUCCESS = MAGENTA_BG + WHITE + BRIGHT
WARNING = ''
class Invalid_mode(Exception):
pass
INFER_LOGO = """\
_.........
_.....................
_...........................
_.................................
_.....................................
_...............I _....................
_.................I _......................
_..................I _.......................
_..................I _.......................
_...................I _........................
_...................I _........................
_....................I No issues _...............
_....................I found _...............
_....................I _.........................
_...................I _........................
_...................I _........................
_..................I _.......................
_.................I _......................
_................I _.....................
_.....................................
_...................................
_.............................
_........................
_...............\
"""
def logo(mode):
if mode == PLAIN_FORMATTER:
return ''
if mode != TERMINAL_FORMATTER:
raise Invalid_mode()
disc_color = MAGENTA_BG
entailment_color = WHITE_BG + MAGENTA
logo = INFER_LOGO.replace('_', disc_color + ' ') \
.replace('I', entailment_color + ' ') \
.replace('.', ' ') \
.replace('\n', RESET + '\n')
return logo + RESET
def syntax_highlighting(source_name, mode, s):
if pygments is None or mode == PLAIN_FORMATTER:
return s
@ -35,3 +104,11 @@ def syntax_highlighting(source_name, mode, s):
return s
formatter = pygments.formatters.TerminalFormatter()
return pygments.highlight(s, lexer, formatter)
def color(s, color, mode):
if mode == TERMINAL_FORMATTER:
return color + s + RESET
if mode == PLAIN_FORMATTER:
return s
raise Invalid_mode()

@ -21,7 +21,7 @@ import sys
import tempfile
import xml.etree.ElementTree as ET
from . import config, colorize, source, utils
from . import colorize, config, source, utils
# Increase the limit of the CSV parser to sys.maxlimit
@ -182,10 +182,10 @@ def _text_of_report_list(reports, formatter=colorize.TERMINAL_FORMATTER):
line = report[JSON_INDEX_LINE]
source_context = ''
if formatter is not None:
if formatter == colorize.TERMINAL_FORMATTER:
source_context = source.build_source_context(
filename,
colorize.TERMINAL_FORMATTER,
formatter,
line,
)
indenter = source.Indenter() \
@ -193,7 +193,12 @@ def _text_of_report_list(reports, formatter=colorize.TERMINAL_FORMATTER):
.add(source_context)
source_context = '\n' + unicode(indenter)
text = '%s%s' % (text_of_report(report), source_context)
msg = text_of_report(report)
if report[JSON_INDEX_KIND] == ISSUE_KIND_ERROR:
msg = colorize.color(msg, colorize.ERROR, formatter)
elif report[JSON_INDEX_KIND] == ISSUE_KIND_WARNING:
msg = colorize.color(msg, colorize.WARNING, formatter)
text = '%s%s' % (msg, source_context)
text_errors_list.append(text)
t = report[JSON_INDEX_TYPE]
@ -208,7 +213,10 @@ def _text_of_report_list(reports, formatter=colorize.TERMINAL_FORMATTER):
n_issues = len(text_errors_list)
if n_issues == 0:
return 'No issues found'
if formatter == colorize.TERMINAL_FORMATTER:
return colorize.logo(formatter)
else:
return 'No issues found'
max_type_length = max(map(len, error_types_count.keys())) + 2
sorted_error_types = error_types_count.items()
@ -220,10 +228,17 @@ def _text_of_report_list(reports, formatter=colorize.TERMINAL_FORMATTER):
text_errors = '\n\n'.join(text_errors_list)
msg = 'Found %s\n\n%s\n\nSummary of the reports:\n\n%s' % (
utils.get_plural('issue', n_issues),
text_errors,
'\n'.join(types_text_list),
issues_found = 'Found {n_issues}'.format(
n_issues=utils.get_plural('issue', n_issues),
)
msg = '{issues_found}\n\n{issues}\n\n{header}\n\n{summary}'.format(
issues_found=colorize.color(issues_found,
colorize.HEADER,
formatter),
issues=text_errors,
header=colorize.color('Summary of the reports',
colorize.HEADER, formatter),
summary='\n'.join(types_text_list),
)
return msg
@ -241,7 +256,9 @@ def print_and_save_errors(json_report, bugs_out):
utils.stdout('\n' + _text_of_report_list(errors))
with codecs.open(bugs_out, 'w',
encoding=config.LOCALE, errors='replace') as file_out:
file_out.write(_text_of_report_list(errors, formatter=None))
plain_out = _text_of_report_list(errors,
formatter=colorize.PLAIN_FORMATTER)
file_out.write(plain_out)
def merge_reports_from_paths(report_paths):

@ -12,7 +12,7 @@ from __future__ import unicode_literals
import codecs
from . import config, colorize, utils
from . import colorize, config, utils
BASE_INDENT = 2
# how many lines of context around each report
@ -63,17 +63,30 @@ def build_source_context(source_name, mode, report_line):
# could go beyond last line, checked in the loop
end_line = report_line + SOURCE_CONTEXT
n_length = len(str(end_line))
# get source excerpt
line_number = 1
s = ''
excerpt = ''
with codecs.open(source_name, 'r',
encoding=config.LOCALE, errors="replace") as source_file:
# avoid going past the end of the file
for line in source_file:
if start_line <= line_number <= end_line:
num = str(line_number).zfill(n_length)
caret = ' '
if line_number == report_line:
caret = '> '
s += '%s. %s%s' % (num, caret, line)
excerpt += line
line_number += 1
return colorize.syntax_highlighting(source_name, mode, s)
excerpt = colorize.syntax_highlighting(source_name, mode, excerpt)
# number lines and add caret at the right position
n_length = len(str(end_line))
s = ''
line_number = start_line
for line in excerpt.split('\n'):
num = colorize.color((str(line_number) + '.').zfill(n_length),
colorize.DIM, mode)
caret = ' '
if line_number == report_line:
caret = colorize.color('> ',
colorize.HEADER, mode)
s += '%s %s%s\n' % (num, caret, line)
line_number += 1
return s

Loading…
Cancel
Save