diff --git a/tools/lint b/tools/lint index 9d0774e483..5f12a4e180 100755 --- a/tools/lint +++ b/tools/lint @@ -88,7 +88,7 @@ def run(): def custom_py(): # type: () -> int """Runs custom checks for python files (config: tools/linter_lib/custom_check.py)""" - failed = python_rules.check(by_lang) + failed = python_rules.check(by_lang, verbose=args.verbose) return 1 if failed else 0 @linter_config.lint @@ -97,7 +97,7 @@ def run(): """Runs custom checks for non-python files (config: tools/linter_lib/custom_check.py)""" failed = False for rule in non_py_rules: - failed = failed or rule.check(by_lang) + failed = failed or rule.check(by_lang, verbose=args.verbose) return 1 if failed else 0 @linter_config.lint diff --git a/tools/zulint/command.py b/tools/zulint/command.py index 8d5d170f1c..07c2d1ec51 100644 --- a/tools/zulint/command.py +++ b/tools/zulint/command.py @@ -43,6 +43,9 @@ def add_default_linter_arguments(parser): type=split_arg_into_list, help='Only run linter for languages in the group(s), e.g.: ' '--groups=backend,frontend') + parser.add_argument('--verbose', '-v', + action='store_true', + help='Print verbose output where available') def split_arg_into_list(arg): # type: (str) -> List[str] diff --git a/tools/zulint/custom_rules.py b/tools/zulint/custom_rules.py index b6f57f62cc..cacd94b252 100644 --- a/tools/zulint/custom_rules.py +++ b/tools/zulint/custom_rules.py @@ -6,7 +6,7 @@ from __future__ import absolute_import import re import traceback -from zulint.printer import print_err, colors +from zulint.printer import print_err, colors, GREEN, BOLDRED, ENDC, MAGENTA if False: from typing import Any, Dict, List, Optional, Tuple, Iterable @@ -28,6 +28,7 @@ class RuleList: self.shebang_rules = shebang_rules # Exclude the files in this folder from rules self.exclude_files_in = "\\" + self.verbose = False def get_line_info_from_file(self, fn): # type: (str) -> List[LineTup] @@ -125,6 +126,13 @@ class RuleList: print_err(identifier, color, '{} at {} line {}:'.format( rule['description'], fn, line_number)) print_err(identifier, color, line) + if self.verbose: + if rule.get('good_lines'): + print_err(identifier, color, GREEN + " Good code: {}{}".format( + (MAGENTA + " | " + GREEN).join(rule['good_lines']), ENDC)) + if rule.get('bad_lines'): + print_err(identifier, color, BOLDRED + " Bad code: {}{}".format( + (MAGENTA + " | " + BOLDRED).join(rule['bad_lines']), ENDC)) def check_file_for_long_lines(self, fn, @@ -202,8 +210,8 @@ class RuleList: return failed - def check(self, by_lang): - # type: (Dict[str, List[str]]) -> bool + def check(self, by_lang, verbose=False): + # type: (Dict[str, List[str]], bool) -> bool # By default, a rule applies to all files within the extension for # which it is specified (e.g. all .py files) # There are three operators we can use to manually include or exclude files from linting for a rule: @@ -215,6 +223,7 @@ class RuleList: # 'include_only': 'set([, ...])' - includes only those files where is a # substring of the filepath. failed = False + self.verbose = verbose for lang in self.langs: color = next(colors) for fn in by_lang[lang]: