-
Henning Glawe authoredHenning Glawe authored
annotator.py 3.81 KiB
import logging
import re
from nomadcore.match_highlighter import MatchHighlighter, ANSI
LOGGER = logging.getLogger(__name__)
RE_EMPTY = re.compile(r"^\s*$")
class Annotator(object):
def __init__(self, annotateFilename=None, coverageIgnore=None,
formatNameWidth=15, formatSourceWidth=20):
self.matchHighlighter = MatchHighlighter()
self.coverageIgnore = coverageIgnore
if annotateFilename is None:
self.annotateFile = None
else:
LOGGER.info("writing annotated input to " + annotateFilename)
self.annotateFile = open(annotateFilename, 'w')
self.annotateFile.write(
"# this file contains ANSI colors; use 'less -R' to view it\n")
self._formatNameWidth = formatNameWidth
self._formatSourceWidth = formatSourceWidth
self._update_annotate_format()
self.counter = {}
for counter in ['total', 'ignore', 'match', 'partial', 'unmatched']:
self.counter[counter] = 0
def _update_annotate_format(self):
self._annotate_format = '%%%ds:%%04d %%%ds %%9s|%%s' % (
self._formatSourceWidth, self._formatNameWidth)
def set_formatSourceWidth(self, formatSourceWidth):
self._formatSourceWidth = formatSourceWidth
self._update_annotate_format()
def set_formatNameWidth(self, formatNameWidth):
self._formatNameWidth = formatNameWidth
self._update_annotate_format()
def annotate(self, match, line, matcher, targetStartEnd):
if not self.annotateFile:
return 1
# classify match
full = match and match.start() == 0 and match.end() == len(line)
local_ignore = False
global_ignore = False
matcher_does_nothing = False
if match:
if matcher.coverageIgnore:
local_ignore = True
elif matcher.does_nothing:
matcher_does_nothing = True
else:
m2 = RE_EMPTY.match(line)
if m2:
global_ignore = True
match = m2
elif self.coverageIgnore is not None:
m2 = self.coverageIgnore.match(line)
if m2:
global_ignore = True
match = m2
# update counters
self.counter['total'] += 1
if local_ignore or global_ignore:
self.counter['ignore'] += 1
elif match:
if full:
self.counter['match'] += 1
else:
self.counter['partial'] += 1
else:
self.counter['unmatched'] += 1
# setup match label
matchlabel = ''
if local_ignore:
matchlabel = 'l_ign'
elif global_ignore:
matchlabel = 'g_ign'
elif match:
if matcher_does_nothing:
matchlabel='n_'
if not full:
matchlabel += 'p_'
matchlabel += 'end' if targetStartEnd else 'start'
else:
matchlabel = 'no'
# highlight line
if local_ignore or global_ignore:
highlighted = self.matchHighlighter.highlight(
match, line, linecolor=ANSI.FG_BLUE)
elif matcher_does_nothing:
highlighted = self.matchHighlighter.highlight(
match, line, linecolor=ANSI.FG_MAGENTA)
elif match:
highlighted = self.matchHighlighter.highlight(match, line)
else:
highlighted = line
# set matcher name
if matcher.name:
name=matcher.name[-self._formatNameWidth:]
else:
name='UNNAMED'
defFile=matcher.defFile[-self._formatSourceWidth:]
self.annotateFile.write(self._annotate_format % (
defFile, matcher.defLine, name,
matchlabel, highlighted,
))