A cache of MD5 sums of source file contents is now maintained. Cpplint is only invoked for new, changed, and files containing errors from the past lint check run.
As a result, repetitive presubmit checks now run in a blink of an eye, so we can include it as an obligatory pre-submit check to avoid frequent CB breakages on lint errors. Review URL: http://codereview.chromium.org/440026 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3368 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
25c5637e34
commit
f2f00d0d09
@ -28,9 +28,11 @@
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
import md5
|
||||
import optparse
|
||||
import os
|
||||
from os.path import abspath, join, dirname, basename, exists
|
||||
import pickle
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
@ -93,6 +95,50 @@ whitespace/todo
|
||||
""".split()
|
||||
|
||||
|
||||
class FileContentsCache(object):
|
||||
|
||||
def __init__(self, sums_file_name):
|
||||
self.sums = {}
|
||||
self.sums_file_name = sums_file_name
|
||||
|
||||
def Load(self):
|
||||
try:
|
||||
sums_file = None
|
||||
try:
|
||||
sums_file = open(self.sums_file_name, 'r')
|
||||
self.sums = pickle.load(sums_file)
|
||||
except IOError:
|
||||
# File might not exist, this is OK.
|
||||
pass
|
||||
finally:
|
||||
if sums_file:
|
||||
sums_file.close()
|
||||
|
||||
def Save(self):
|
||||
try:
|
||||
sums_file = open(self.sums_file_name, 'w')
|
||||
pickle.dump(self.sums, sums_file)
|
||||
finally:
|
||||
sums_file.close()
|
||||
|
||||
def FilterUnchangedFiles(self, files):
|
||||
changed_or_new = []
|
||||
for file in files:
|
||||
try:
|
||||
handle = open(file, "r")
|
||||
file_sum = md5.new(handle.read()).digest()
|
||||
if not file in self.sums or self.sums[file] != file_sum:
|
||||
changed_or_new.append(file)
|
||||
self.sums[file] = file_sum
|
||||
finally:
|
||||
handle.close()
|
||||
return changed_or_new
|
||||
|
||||
def RemoveFile(self, file):
|
||||
if file in self.sums:
|
||||
self.sums.pop(file)
|
||||
|
||||
|
||||
class SourceFileProcessor(object):
|
||||
"""
|
||||
Utility class that can run through a directory structure, find all relevant
|
||||
@ -137,7 +183,7 @@ class CppLintProcessor(SourceFileProcessor):
|
||||
or (name == 'third_party'))
|
||||
|
||||
IGNORE_LINT = ['flag-definitions.h']
|
||||
|
||||
|
||||
def IgnoreFile(self, name):
|
||||
return (super(CppLintProcessor, self).IgnoreFile(name)
|
||||
or (name in CppLintProcessor.IGNORE_LINT))
|
||||
@ -146,13 +192,32 @@ class CppLintProcessor(SourceFileProcessor):
|
||||
return ['src', 'public', 'samples', join('test', 'cctest')]
|
||||
|
||||
def ProcessFiles(self, files, path):
|
||||
good_files_cache = FileContentsCache('.cpplint-cache')
|
||||
good_files_cache.Load()
|
||||
files = good_files_cache.FilterUnchangedFiles(files)
|
||||
if len(files) == 0:
|
||||
print 'No changes in files detected. Skipping cpplint check.'
|
||||
return True
|
||||
|
||||
filt = '-,' + ",".join(['+' + n for n in ENABLED_LINT_RULES])
|
||||
command = ['cpplint.py', '--filter', filt] + join(files)
|
||||
local_cpplint = join(path, "tools", "cpplint.py")
|
||||
if exists(local_cpplint):
|
||||
command = ['python', local_cpplint, '--filter', filt] + join(files)
|
||||
process = subprocess.Popen(command)
|
||||
return process.wait() == 0
|
||||
|
||||
process = subprocess.Popen(command, stderr=subprocess.PIPE)
|
||||
LINT_ERROR_PATTERN = re.compile(r'^(.+)[:(]\d+[:)]')
|
||||
while True:
|
||||
out_line = process.stderr.readline()
|
||||
if out_line == '' and process.poll() != None:
|
||||
break
|
||||
sys.stderr.write(out_line)
|
||||
m = LINT_ERROR_PATTERN.match(out_line)
|
||||
if m:
|
||||
good_files_cache.RemoveFile(m.group(1))
|
||||
|
||||
good_files_cache.Save()
|
||||
return process.returncode == 0
|
||||
|
||||
|
||||
COPYRIGHT_HEADER_PATTERN = re.compile(
|
||||
|
Loading…
Reference in New Issue
Block a user