Skip to content

Commit 58e2a52

Browse files
authored
Merge pull request google#293 from iam/cpplint_quiet
cpplint: add --quiet flag to suppress all output when there's no errors
2 parents 8667623 + e8ffd7c commit 58e2a52

File tree

2 files changed

+114
-3
lines changed

2 files changed

+114
-3
lines changed

cpplint/cpplint.py

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
5858
[--counting=total|toplevel|detailed] [--root=subdir]
5959
[--linelength=digits] [--headers=x,y,...]
60+
[--quiet]
6061
<file> [file] ...
6162
6263
The style guidelines this tries to follow are those in
@@ -83,6 +84,9 @@
8384
verbose=#
8485
Specify a number 0-5 to restrict errors to certain verbosity levels.
8586
87+
quiet
88+
Don't print anything if no errors are found.
89+
8690
filter=-x,+y,...
8791
Specify a comma-separated list of category-filters to apply: only
8892
error messages whose category names pass the filters will be printed.
@@ -861,6 +865,7 @@ def __init__(self):
861865
self._filters_backup = self.filters[:]
862866
self.counting = 'total' # In what way are we counting errors?
863867
self.errors_by_category = {} # string to int dict storing error counts
868+
self.quiet = False # Suppress non-error messagess?
864869

865870
# output format:
866871
# "emacs" - format that emacs can parse (default)
@@ -871,6 +876,12 @@ def SetOutputFormat(self, output_format):
871876
"""Sets the output format for errors."""
872877
self.output_format = output_format
873878

879+
def SetQuiet(self, quiet):
880+
"""Sets the module's quiet settings, and returns the previous setting."""
881+
last_quiet = self.quiet
882+
self.quiet = quiet
883+
return last_quiet
884+
874885
def SetVerboseLevel(self, level):
875886
"""Sets the module's verbosity, and returns the previous setting."""
876887
last_verbose_level = self.verbose_level
@@ -952,6 +963,14 @@ def _SetOutputFormat(output_format):
952963
"""Sets the module's output format."""
953964
_cpplint_state.SetOutputFormat(output_format)
954965

966+
def _Quiet():
967+
"""Return's the module's quiet setting."""
968+
return _cpplint_state.quiet
969+
970+
def _SetQuiet(quiet):
971+
"""Set the module's quiet status, and return previous setting."""
972+
return _cpplint_state.SetQuiet(quiet)
973+
955974

956975
def _VerboseLevel():
957976
"""Returns the module's verbosity setting."""
@@ -5955,6 +5974,9 @@ def ProcessConfigOverrides(filename):
59555974
if base_name:
59565975
pattern = re.compile(val)
59575976
if pattern.match(base_name):
5977+
if _cpplint_state.quiet:
5978+
# Suppress "Ignoring file" warning when using --quiet.
5979+
return False
59585980
sys.stderr.write('Ignoring "%s": file excluded by "%s". '
59595981
'File path component "%s" matches '
59605982
'pattern "%s"\n' %
@@ -6006,6 +6028,7 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
60066028

60076029
_SetVerboseLevel(vlevel)
60086030
_BackupFilters()
6031+
old_errors = _cpplint_state.error_count
60096032

60106033
if not ProcessConfigOverrides(filename):
60116034
_RestoreFilters()
@@ -6074,7 +6097,10 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
60746097
Error(filename, linenum, 'whitespace/newline', 1,
60756098
'Unexpected \\r (^M) found; better to use only \\n')
60766099

6077-
sys.stdout.write('Done processing %s\n' % filename)
6100+
# Suppress printing anything if --quiet was passed unless the error
6101+
# count has increased after processing this file.
6102+
if not _cpplint_state.quiet or old_errors != _cpplint_state.error_count:
6103+
sys.stdout.write('Done processing %s\n' % filename)
60786104
_RestoreFilters()
60796105

60806106

@@ -6118,13 +6144,15 @@ def ParseArguments(args):
61186144
'root=',
61196145
'linelength=',
61206146
'extensions=',
6121-
'headers='])
6147+
'headers=',
6148+
'quiet'])
61226149
except getopt.GetoptError:
61236150
PrintUsage('Invalid arguments.')
61246151

61256152
verbosity = _VerboseLevel()
61266153
output_format = _OutputFormat()
61276154
filters = ''
6155+
quiet = _Quiet()
61286156
counting_style = ''
61296157

61306158
for (opt, val) in opts:
@@ -6134,6 +6162,8 @@ def ParseArguments(args):
61346162
if val not in ('emacs', 'vs7', 'eclipse'):
61356163
PrintUsage('The only allowed output formats are emacs, vs7 and eclipse.')
61366164
output_format = val
6165+
elif opt == '--quiet':
6166+
quiet = True
61376167
elif opt == '--verbose':
61386168
verbosity = int(val)
61396169
elif opt == '--filter':
@@ -6166,6 +6196,7 @@ def ParseArguments(args):
61666196
PrintUsage('No files were specified.')
61676197

61686198
_SetOutputFormat(output_format)
6199+
_SetQuiet(quiet)
61696200
_SetVerboseLevel(verbosity)
61706201
_SetFilters(filters)
61716202
_SetCountingStyle(counting_style)
@@ -6186,7 +6217,9 @@ def main():
61866217
_cpplint_state.ResetErrorCounts()
61876218
for filename in filenames:
61886219
ProcessFile(filename, _cpplint_state.verbose_level)
6189-
_cpplint_state.PrintErrorCounts()
6220+
# If --quiet is passed, suppress printing error count unless there are errors.
6221+
if not _cpplint_state.quiet or _cpplint_state.error_count > 0:
6222+
_cpplint_state.PrintErrorCounts()
61906223

61916224
sys.exit(_cpplint_state.error_count > 0)
61926225

cpplint/cpplint_unittest.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import os
3838
import random
3939
import re
40+
import subprocess
4041
import sys
4142
import unittest
4243

@@ -5686,6 +5687,83 @@ def testInlineAssembly(self):
56865687
self.assertEquals(len(self.nesting_state.stack), 0)
56875688

56885689

5690+
class QuietTest(unittest.TestCase):
5691+
5692+
def setUp(self):
5693+
self.this_dir_path = os.path.dirname(os.path.abspath(__file__))
5694+
self.python_executable = sys.executable or 'python'
5695+
self.cpplint_test_h = os.path.join(self.this_dir_path,
5696+
'cpplint_test_header.h')
5697+
5698+
def _runCppLint(self, *args):
5699+
cpplint_abspath = os.path.join(self.this_dir_path, 'cpplint.py')
5700+
5701+
cmd_line = [self.python_executable, cpplint_abspath] + \
5702+
list(args) + \
5703+
[ self.cpplint_test_h ]
5704+
5705+
return_code = 0
5706+
try:
5707+
output = subprocess.check_output(cmd_line,
5708+
stderr=subprocess.STDOUT)
5709+
except subprocess.CalledProcessError as err:
5710+
return_code = err.returncode
5711+
output = err.output
5712+
5713+
return (return_code, output)
5714+
5715+
def testNonQuietWithErrors(self):
5716+
# This will fail: the test header is missing a copyright and header guard.
5717+
(return_code, output) = self._runCppLint()
5718+
self.assertEquals(1, return_code)
5719+
# Always-on behavior: Print error messages as they come up.
5720+
self.assertIn("[legal/copyright]", output)
5721+
self.assertIn("[build/header_guard]", output)
5722+
# If --quiet was unspecified: Print 'Done processing' and 'Total errors..'
5723+
self.assertIn("Done processing", output)
5724+
self.assertIn("Total errors found:", output)
5725+
5726+
def testQuietWithErrors(self):
5727+
# When there are errors, behavior is identical to not passing --quiet.
5728+
(return_code, output) = self._runCppLint('--quiet')
5729+
self.assertEquals(1, return_code)
5730+
self.assertIn("[legal/copyright]", output)
5731+
self.assertIn("[build/header_guard]", output)
5732+
# Even though --quiet was used, print these since there were errors.
5733+
self.assertIn("Done processing", output)
5734+
self.assertIn("Total errors found:", output)
5735+
5736+
def testNonQuietWithoutErrors(self):
5737+
# This will succeed. We filtered out all the known errors for that file.
5738+
(return_code, output) = self._runCppLint('--filter=' +
5739+
'-legal/copyright,' +
5740+
'-build/header_guard')
5741+
self.assertEquals(0, return_code, output)
5742+
# No cpplint errors are printed since there were no errors.
5743+
self.assertNotIn("[legal/copyright]", output)
5744+
self.assertNotIn("[build/header_guard]", output)
5745+
# Print 'Done processing' and 'Total errors found' since
5746+
# --quiet was not specified.
5747+
self.assertIn("Done processing", output)
5748+
self.assertIn("Total errors found:", output)
5749+
5750+
def testQuietWithoutErrors(self):
5751+
# This will succeed. We filtered out all the known errors for that file.
5752+
(return_code, output) = self._runCppLint('--quiet',
5753+
'--filter=' +
5754+
'-legal/copyright,' +
5755+
'-build/header_guard')
5756+
self.assertEquals(0, return_code, output)
5757+
# No cpplint errors are printed since there were no errors.
5758+
self.assertNotIn("[legal/copyright]", output)
5759+
self.assertNotIn("[build/header_guard]", output)
5760+
# --quiet was specified and there were no errors:
5761+
# skip the printing of 'Done processing' and 'Total errors..'
5762+
self.assertNotIn("Done processing", output)
5763+
self.assertNotIn("Total errors found:", output)
5764+
# Output with no errors must be completely blank!
5765+
self.assertEquals("", output)
5766+
56895767
# pylint: disable-msg=C6409
56905768
def setUp():
56915769
"""Runs before all tests are executed.

0 commit comments

Comments
 (0)