Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2251)

Unified Diff: cpplint.py

Issue 406373002: depot_tools: modify cpplint.py to allow CPPLINT.cfg overrides (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cpplint.py
diff --git a/cpplint.py b/cpplint.py
index 92384dc37181f6e982d0e6f74afe93d393c5de19..640ae08bfbac87a781a3a0e3e1a57600b601acc1 100755
--- a/cpplint.py
+++ b/cpplint.py
@@ -682,6 +682,8 @@ class _CppLintState(object):
self.error_count = 0 # global count of reported errors
# filters to apply when emitting error messages
self.filters = _DEFAULT_FILTERS[:]
+ # backup of filter list. Used to restore the state after each file.
sosa 2014/07/23 17:35:00 indentation also this seems super private to the c
Alex Vakulenko (Google) 2014/07/23 19:04:50 Done.
+ self.filters_backup = self.filters[:]
self.counting = 'total' # In what way are we counting errors?
self.errors_by_category = {} # string to int dict storing error counts
@@ -720,6 +722,10 @@ class _CppLintState(object):
"""
# Default filters always have less priority than the flag ones.
self.filters = _DEFAULT_FILTERS[:]
+ self.AddFilters(filters)
+
+ def AddFilters(self, filters):
+ """ Adds more filters to the existing list of error-message filters. """
for filt in filters.split(','):
clean_filt = filt.strip()
if clean_filt:
@@ -729,6 +735,14 @@ class _CppLintState(object):
raise ValueError('Every filter in --filters must start with + or -'
' (%s does not)' % filt)
+ def BackupFilters(self):
+ """ Saves the current filter list to backup storage."""
+ self.filters_backup = self.filters[:]
+
+ def RestoreFilters(self):
+ """ Restores filters previously backed up."""
+ self.filters = self.filters_backup[:]
+
def ResetErrorCounts(self):
"""Sets the module's error statistic back to zero."""
self.error_count = 0
@@ -796,6 +810,22 @@ def _SetFilters(filters):
"""
_cpplint_state.SetFilters(filters)
+def _AddFilters(filters):
+ """Adds more filter overrides. Unlike _SetFilters, this function does not
sosa 2014/07/23 17:35:00 Unlike should be on a newline. We usually keep the
Alex Vakulenko (Google) 2014/07/23 19:04:50 Done.
+ reset the current list of filters available.
+ Args:
+ filters: A string of comma-separated filters (eg "whitespace/indent").
+ Each filter should start with + or -; else we die.
+ """
+ _cpplint_state.AddFilters(filters)
+
+def _BackupFilters():
+ """ Saves the current filter list to backup storage."""
+ _cpplint_state.BackupFilters()
+
+def _RestoreFilters():
+ """ Restores filters previously backed up."""
+ _cpplint_state.RestoreFilters()
class _FunctionState(object):
"""Tracks current function name and the number of lines in its body."""
@@ -5424,6 +5454,84 @@ def ProcessFileData(filename, file_extension, lines, error,
CheckForNewlineAtEOF(filename, lines, error)
+def GetConfigOverrideFiles(filename):
+ """ Looks for CPPLINT.cfg files in the directory containing |filename| and
+ its parents and returns a list of configuration files found.
+
+ Args:
+ filename: The name of the file being processed by the linter.
+ """
+
+ cfg_override_files = []
+ abs_path = os.path.abspath(os.path.dirname(filename))
+
+ while True:
+ file = os.path.join(abs_path, "CPPLINT.cfg")
+ if os.path.isfile(file):
+ cfg_override_files.append(file)
+ parent = os.path.dirname(abs_path)
+ if parent == abs_path:
+ break
+ abs_path = parent
+
+ return reversed(cfg_override_files)
+
+def ProcessConfigFile(cfg_file, filename):
+ """ Loads the configuration file and processes the config overrides
sosa 2014/07/23 17:35:00 nit about docstring
Alex Vakulenko (Google) 2014/07/23 19:04:51 Done.
+ specified in it.
+
+ Config file contains a bunch of key=value pairs. Currently
sosa 2014/07/23 17:35:00 This should probably go in the module docstring /
Alex Vakulenko (Google) 2014/07/23 19:04:50 Done.
+ we are looking only for:
+ filter=+filter1,-filter2,...
+ exclude_files=regex
+
+ Args:
+ cfg_file: config file to process
+ filename: The name of the file being processed by the linter.
+
+ Returns:
+ false if the current |filename| should not be processed further.
+ """
+
+ try:
+ #lines = codecs.open(cfg_file, 'r', 'utf8', 'replace').read().split('\n')
sosa 2014/07/23 17:35:00 What's the line commented out for?
Alex Vakulenko (Google) 2014/07/23 19:04:50 Just forgot to remove. Done.
+ with open(cfg_file) as lines:
sosa 2014/07/23 17:35:00 Not completely correct naming. This is the file_ha
Alex Vakulenko (Google) 2014/07/23 19:04:50 Done.
+ for line in lines:
+ name, val = line.partition('=')[::2]
sosa 2014/07/23 17:35:00 mmm, this works but not really the correct usage o
Alex Vakulenko (Google) 2014/07/23 19:04:50 I copied this from somewhere. Fixed
+ name = name.strip()
sosa 2014/07/23 17:35:00 val = val.strip() here
Alex Vakulenko (Google) 2014/07/23 19:04:50 Done.
+ if name == 'filter':
+ _AddFilters(val.strip())
+ elif name == 'exclude_files':
sosa 2014/07/23 17:35:00 Should support comments but also error out for nam
Alex Vakulenko (Google) 2014/07/23 19:04:50 Done.
+ pattern = re.compile(val.strip())
+ if pattern.match(filename):
+ sys.stderr.write('Ignoring %s; file excluded by (%s)\n' %
+ (filename, cfg_file))
+ return False
+
+ except IOError:
+ sys.stderr.write(
+ "Skipping config file '%s': Can't open for reading\n" % cfg_file)
+ _RestoreFilters()
+ return True
+
+ return True
+
sosa 2014/07/23 17:35:00 2 lines should separate top-level methods
Alex Vakulenko (Google) 2014/07/23 19:04:50 Done.
+def ProcessConfigOverrides(cfg_override_files, filename):
+ """ Loads the configuration files and processes the config overrides
sosa 2014/07/23 17:35:00 same nit about docstrings.
Alex Vakulenko (Google) 2014/07/23 19:04:50 Done.
+ specified in those files..
+
+ Args:
+ cfg_override_files: list of cfg files to process
+ filename: The name of the file being processed by the linter.
+
+ Returns:
+ false if the current |filename| should not be processed further.
+ """
+ for cfg_file in cfg_override_files:
+ if not ProcessConfigFile(cfg_file, filename):
+ return False
+
+ return True
def ProcessFile(filename, vlevel, extra_check_functions=[]):
"""Does google-lint on a single file.
@@ -5440,6 +5548,12 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
"""
_SetVerboseLevel(vlevel)
+ _BackupFilters()
+
+ cfg_override_files = GetConfigOverrideFiles(filename)
+ if not ProcessConfigOverrides(cfg_override_files, filename):
+ _RestoreFilters()
+ return
lf_lines = []
crlf_lines = []
@@ -5471,6 +5585,7 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
except IOError:
sys.stderr.write(
"Skipping input '%s': Can't open for reading\n" % filename)
+ _RestoreFilters()
return
# Note, if no dot is found, this will give the entire filename as the ext.
@@ -5504,6 +5619,7 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
'Unexpected \\r (^M) found; better to use only \\n')
sys.stderr.write('Done processing %s\n' % filename)
+ _RestoreFilters()
def PrintUsage(message):
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698