diff --git a/python/mozlint/mozlint/formatters/stylish.py b/python/mozlint/mozlint/formatters/stylish.py index fdfbe79dac49..44bcc6c69991 100644 --- a/python/mozlint/mozlint/formatters/stylish.py +++ b/python/mozlint/mozlint/formatters/stylish.py @@ -13,23 +13,25 @@ from ..util.string import pluralize class StylishFormatter(object): """Formatter based on the eslint default.""" - _indent_ = ' ' + _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], + "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') +{diff}""".lstrip( + "\n" + ) fmt_summary = "{t.bold}{c}\u2716 {problem} ({error}, {warning}{failure}){t.normal}" def __init__(self, disable_colors=False): @@ -40,7 +42,7 @@ class StylishFormatter(object): for num in self._colors[color]: if num < self.num_colors: return self.term.color(num) - return '' + return "" def _reset_max(self): self.max_lineno = 0 @@ -60,15 +62,15 @@ class StylishFormatter(object): 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') + 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' + new_diff += self._indent_ + line + "\n" return new_diff def __call__(self, result): @@ -85,48 +87,61 @@ class StylishFormatter(object): for err in errors: assert isinstance(err, Issue) self._update_max(err) - if err.level == 'error': + 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))): + 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) + 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) + "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(self.fmt.format(**args).rstrip().rstrip("\n")) - message.append('') # newline + 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, - )) + 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 '', - )) + 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) + return "\n".join(message) diff --git a/python/mozlint/mozlint/result.py b/python/mozlint/mozlint/result.py index 7a29f1e9c364..69812482406a 100644 --- a/python/mozlint/mozlint/result.py +++ b/python/mozlint/mozlint/result.py @@ -67,28 +67,40 @@ class Issue(object): """ __slots__ = ( - 'linter', - 'path', - 'message', - 'lineno', - 'column', - 'hint', - 'source', - 'level', - 'rule', - 'lineoffset', - 'diff' + "linter", + "path", + "message", + "lineno", + "column", + "hint", + "source", + "level", + "rule", + "lineoffset", + "diff", ) - def __init__(self, linter, path, message, lineno, column=None, hint=None, - source=None, level=None, rule=None, lineoffset=None, diff=None): + def __init__( + self, + linter, + path, + message, + lineno, + column=None, + hint=None, + source=None, + level=None, + rule=None, + lineoffset=None, + diff=None, + ): self.path = path self.message = message self.lineno = int(lineno) if lineno else 0 self.column = int(column) if column else column self.hint = hint self.source = source - self.level = level or 'error' + self.level = level or "error" self.linter = linter self.rule = rule self.lineoffset = lineoffset @@ -127,10 +139,10 @@ def from_config(config, **kwargs): for attr in Issue.__slots__: attrs[attr] = kwargs.get(attr, config.get(attr)) - if not attrs['linter']: - attrs['linter'] = config.get('name') + if not attrs["linter"]: + attrs["linter"] = config.get("name") - if not attrs['message']: - attrs['message'] = config.get('description') + if not attrs["message"]: + attrs["message"] = config.get("description") return Issue(**attrs) diff --git a/python/mozlint/test/test_formatters.py b/python/mozlint/test/test_formatters.py index 8145c52cbe6b..0f96739d44a2 100644 --- a/python/mozlint/test/test_formatters.py +++ b/python/mozlint/test/test_formatters.py @@ -15,15 +15,15 @@ from mozlint.result import Issue, ResultSummary from mozlint import formatters NORMALISED_PATHS = { - 'abc': os.path.normpath('a/b/c.txt'), - 'def': os.path.normpath('d/e/f.txt'), - 'cwd': mozpath.normpath(os.getcwd()), + "abc": os.path.normpath("a/b/c.txt"), + "def": os.path.normpath("d/e/f.txt"), + "cwd": mozpath.normpath(os.getcwd()), } EXPECTED = { - 'compact': { - 'kwargs': {}, - 'format': """ + "compact": { + "kwargs": {}, + "format": """ a/b/c.txt: line 1, Error - oh no foo (foo) a/b/c.txt: line 4, col 10, Error - oh no baz (baz) a/b/c.txt: line 5, Error - oh no foo-diff (foo-diff) @@ -32,11 +32,9 @@ d/e/f.txt: line 4, col 2, Warning - oh no bar (bar-not-allowed) 4 problems """.strip(), }, - 'stylish': { - 'kwargs': { - 'disable_colors': True, - }, - 'format': """ + "stylish": { + "kwargs": {"disable_colors": True}, + "format": """ a/b/c.txt 1 error oh no foo (foo) 4:10 error oh no baz (baz) @@ -51,68 +49,67 @@ d/e/f.txt \u2716 4 problems (3 errors, 1 warning) """.strip(), }, - 'treeherder': { - 'kwargs': {}, - 'format': """ + "treeherder": { + "kwargs": {}, + "format": """ TEST-UNEXPECTED-ERROR | a/b/c.txt:1 | oh no foo (foo) TEST-UNEXPECTED-ERROR | a/b/c.txt:4:10 | oh no baz (baz) TEST-UNEXPECTED-ERROR | a/b/c.txt:5 | oh no foo-diff (foo-diff) TEST-UNEXPECTED-WARNING | d/e/f.txt:4:2 | oh no bar (bar-not-allowed) """.strip(), }, - 'unix': { - 'kwargs': {}, - 'format': """ + "unix": { + "kwargs": {}, + "format": """ {abc}:1: foo error: oh no foo {abc}:4:10: baz error: oh no baz {abc}:5: foo-diff error: oh no foo-diff {def}:4:2: bar-not-allowed warning: oh no bar -""".format(**NORMALISED_PATHS).strip(), +""".format( + **NORMALISED_PATHS + ).strip(), }, - 'summary': { - 'kwargs': {}, - 'format': """ + "summary": { + "kwargs": {}, + "format": """ {cwd}/a: 3 errors {cwd}/d: 0 errors, 1 warning -""".format(**NORMALISED_PATHS).strip(), +""".format( + **NORMALISED_PATHS + ).strip(), }, } @pytest.fixture -def result(scope='module'): +def result(scope="module"): containers = ( + Issue(linter="foo", path="a/b/c.txt", message="oh no foo", lineno=1), Issue( - linter='foo', - path='a/b/c.txt', - message="oh no foo", - lineno=1, - ), - Issue( - linter='bar', - path='d/e/f.txt', + linter="bar", + path="d/e/f.txt", message="oh no bar", hint="try baz instead", - level='warning', + level="warning", lineno="4", column="2", rule="bar-not-allowed", ), Issue( - linter='baz', - path='a/b/c.txt', + linter="baz", + path="a/b/c.txt", message="oh no baz", lineno=4, column=10, source="if baz:", ), Issue( - linter='foo-diff', - path='a/b/c.txt', + linter="foo-diff", + path="a/b/c.txt", message="oh no foo-diff", lineno=5, source="if baz:", - diff='diff 1\n- hello\n+ hello2', + diff="diff 1\n- hello\n+ hello2", ), ) result = ResultSummary() @@ -124,13 +121,13 @@ def result(scope='module'): @pytest.mark.parametrize("name", EXPECTED.keys()) def test_formatters(result, name): opts = EXPECTED[name] - fmt = formatters.get(name, **opts['kwargs']) + fmt = formatters.get(name, **opts["kwargs"]) # encoding to str bypasses a UnicodeEncodeError in pytest - assert fmt(result).encode('utf-8') == opts['format'].encode('utf-8') + assert fmt(result).encode("utf-8") == opts["format"].encode("utf-8") def test_json_formatter(result): - fmt = formatters.get('json') + fmt = formatters.get("json") formatted = json.loads(fmt(result)) assert set(formatted.keys()) == set(result.issues.keys()) @@ -141,5 +138,5 @@ def test_json_formatter(result): assert all(s in err for s in slots) -if __name__ == '__main__': +if __name__ == "__main__": mozunit.main()