class StylishFormatter(object): """Formatter based on the eslint default.""" _indent_ = " " # Colors later on in the list are fallbacks in case the terminal # doesn't support colors earlier in the list. # See http://www.calmar.ws/vim/256-xterm-24bit-rgb-color-chart.html _colors = { "grey": [247, 8, 7], "red": [1], "green": [2], "yellow": [3], "brightred": [9, 1], "brightyellow": [11, 3], } fmt = """ {c1}{lineno}{column} {c2}{level}{normal} {message} {c1}{rule}({linter}){normal} {diff}""".lstrip("\n") fmt_summary = "{t.bold}{c}\u2716 {problem} ({error}, {warning}{failure}){t.normal}" def __init__(self, disable_colors=False): self.term = Terminal(disable_styling=disable_colors) self.num_colors = self.term.number_of_colors def color(self, color): for num in self._colors[color]: if num < self.num_colors: return self.term.color(num) return "" def _reset_max(self): self.max_lineno = 0 self.max_column = 0 self.max_level = 0 self.max_message = 0 def _update_max(self, err): """Calculates the longest length of each token for spacing.""" self.max_lineno = max(self.max_lineno, len(str(err.lineno))) if err.column: self.max_column = max(self.max_column, len(str(err.column))) self.max_level = max(self.max_level, len(str(err.level))) self.max_message = max(self.max_message, len(err.message)) def _get_colored_diff(self, diff): if not diff: return "" new_diff = "" for line in diff.split("\n"): if line.startswith("+"): new_diff += self.color("green") elif line.startswith("-"): new_diff += self.color("red") else: new_diff += self.term.normal new_diff += self._indent_ + line + "\n" return new_diff def __call__(self, result): message = [] failed = result.failed num_errors = 0 num_warnings = 0 for path, errors in sorted(result.issues.iteritems()): self._reset_max() message.append(self.term.underline(path)) # Do a first pass to calculate required padding for err in errors: assert isinstance(err, Issue) self._update_max(err) if err.level == "error": num_errors += 1 else: num_warnings += 1 for err in sorted(errors, key=lambda e: (int(e.lineno), int(e.column or 0))): if err.column: col = ":" + str(err.column).ljust(self.max_column) else: col = "".ljust(self.max_column + 1) args = { "normal": self.term.normal, "c1": self.color("grey"), "c2": self.color("red") if err.level == "error" else self.color("yellow"), "lineno": str(err.lineno).rjust(self.max_lineno), "column": col, "level": err.level.ljust(self.max_level), "rule": "{} ".format(err.rule) if err.rule else "", "linter": err.linter.lower(), "message": err.message.ljust(self.max_message), "diff": self._get_colored_diff(err.diff).ljust(self.max_message), } message.append(self.fmt.format(**args).rstrip().rstrip("\n")) message.append("") # newline # If there were failures, make it clear which linters failed for fail in failed: message.append( "{c}A failure occurred in the {name} linter.".format( c=self.color("brightred"), name=fail)) # Print a summary message.append( self.fmt_summary.format( t=self.term, c=self.color("brightred") if num_errors or failed else self.color("brightyellow"), problem=pluralize("problem", num_errors + num_warnings + len(failed)), error=pluralize("error", num_errors), warning=pluralize( "warning", num_warnings or result.total_suppressed_warnings), failure=", {}".format(pluralize("failure", len(failed))) if failed else "", )) return "\n".join(message)
class StylishFormatter(object): """Formatter based on the eslint default.""" # Colors later on in the list are fallbacks in case the terminal # doesn't support colors earlier in the list. # See http://www.calmar.ws/vim/256-xterm-24bit-rgb-color-chart.html _colors = { 'grey': [247, 8, 7], 'red': [1], 'yellow': [3], 'brightred': [9, 1], 'brightyellow': [11, 3], } fmt = " {c1}{lineno}{column} {c2}{level}{normal} {message} {c1}{rule}({linter}){normal}" fmt_summary = "{t.bold}{c}\u2716 {problem} ({error}, {warning}{failure}){t.normal}" def __init__(self, disable_colors=False): self.term = Terminal(disable_styling=disable_colors) self.num_colors = self.term.number_of_colors def color(self, color): for num in self._colors[color]: if num < self.num_colors: return self.term.color(num) return '' def _reset_max(self): self.max_lineno = 0 self.max_column = 0 self.max_level = 0 self.max_message = 0 def _update_max(self, err): """Calculates the longest length of each token for spacing.""" self.max_lineno = max(self.max_lineno, len(str(err.lineno))) if err.column: self.max_column = max(self.max_column, len(str(err.column))) self.max_level = max(self.max_level, len(str(err.level))) self.max_message = max(self.max_message, len(err.message)) def _pluralize(self, s, num): if num != 1: s += 's' return str(num) + ' ' + s def __call__(self, result, failed=None, **kwargs): message = [] failed = failed or [] num_errors = 0 num_warnings = 0 for path, errors in sorted(result.iteritems()): self._reset_max() message.append(self.term.underline(path)) # Do a first pass to calculate required padding for err in errors: assert isinstance(err, ResultContainer) self._update_max(err) if err.level == 'error': num_errors += 1 else: num_warnings += 1 for err in errors: message.append( self.fmt.format( normal=self.term.normal, c1=self.color('grey'), c2=self.color('red') if err.level == 'error' else self.color('yellow'), lineno=str(err.lineno).rjust(self.max_lineno), column=(":" + str(err.column).ljust(self.max_column)) if err.column else "", level=err.level.ljust(self.max_level), message=err.message.ljust(self.max_message), rule='{} '.format(err.rule) if err.rule else '', linter=err.linter.lower(), )) message.append('') # newline # If there were failures, make it clear which linters failed for fail in failed: message.append( "{c}A failure occurred in the {name} linter.".format( c=self.color('brightred'), name=fail, )) # Print a summary message.append( self.fmt_summary.format( t=self.term, c=self.color('brightred') if num_errors or failed else self.color('brightyellow'), problem=self._pluralize( 'problem', num_errors + num_warnings + len(failed)), error=self._pluralize('error', num_errors), warning=self._pluralize('warning', num_warnings), failure=', {}'.format(self._pluralize('failure', len(failed))) if failed else '', )) return '\n'.join(message)