@@ -228,17 +228,94 @@ def FindFilesIn(self, path):
228228 return result
229229
230230
231- class CppLintProcessor (SourceFileProcessor ):
231+ class CacheableSourceFileProcessor (SourceFileProcessor ):
232+ """Utility class that allows caching ProcessFiles() method calls.
233+
234+ In order to use it, create a ProcessFilesWithoutCaching method that returns
235+ the files requiring intervention after processing the source files.
236+ """
237+
238+ def __init__ (self , cache_file_path , file_type ):
239+ self .cache_file_path = cache_file_path
240+ self .file_type = file_type
241+
242+ def GetProcessorWorker (self ):
243+ """Expected to return the worker function to run the formatter."""
244+ raise NotImplementedError
245+
246+ def GetProcessorScript (self ):
247+ """Expected to return a tuple
248+ (path to the format processor script, list of arguments)."""
249+ raise NotImplementedError
250+
251+ def GetProcessorCommand (self ):
252+ format_processor , options = self .GetProcessorScript ()
253+ if not format_processor :
254+ print ('Could not find the formatter for % files' % self .file_type )
255+ sys .exit (1 )
256+
257+ command = [sys .executable , format_processor ]
258+ command .extend (options )
259+
260+ return command
261+
262+ def ProcessFiles (self , files ):
263+ cache = FileContentsCache (self .cache_file_path )
264+ cache .Load ()
265+ files = cache .FilterUnchangedFiles (files )
266+
267+ if len (files ) == 0 :
268+ print 'No changes in %s files detected. Skipping check' % self .file_type
269+ return True
270+
271+ files_requiring_changes = self .DetectFilesToChange (files )
272+ print (
273+ 'Total %s files found that require formatting: %d' %
274+ (self .file_type , len (files_requiring_changes )))
275+ for file in files_requiring_changes :
276+ cache .RemoveFile (file )
277+
278+ cache .Save ()
279+ return files_requiring_changes == []
280+
281+ def DetectFilesToChange (self , files ):
282+ command = self .GetProcessorCommand ()
283+ worker = self .GetProcessorWorker ()
284+
285+ commands = [command + [file ] for file in files ]
286+ count = multiprocessing .cpu_count ()
287+ pool = multiprocessing .Pool (count )
288+ try :
289+ results = pool .map_async (worker , commands ).get (timeout = 240 )
290+ except KeyboardInterrupt :
291+ print "\n Caught KeyboardInterrupt, terminating workers."
292+ pool .terminate ()
293+ pool .join ()
294+ sys .exit (1 )
295+
296+ unformatted_files = []
297+ for index , errors in enumerate (results ):
298+ if errors > 0 :
299+ unformatted_files .append (files [index ])
300+
301+ return unformatted_files
302+
303+
304+ class CppLintProcessor (CacheableSourceFileProcessor ):
232305 """
233306 Lint files to check that they follow the google code style.
234307 """
235308
309+ def __init__ (self ):
310+ super (CppLintProcessor , self ).__init__ (
311+ cache_file_path = '.cpplint-cache' , file_type = 'C/C++' )
312+
236313 def IsRelevant (self , name ):
237314 return name .endswith ('.cc' ) or name .endswith ('.h' )
238315
239316 def IgnoreDir (self , name ):
240317 return (super (CppLintProcessor , self ).IgnoreDir (name )
241- or (name == 'third_party' ))
318+ or (name == 'third_party' ))
242319
243320 IGNORE_LINT = ['export-template.h' , 'flag-definitions.h' ]
244321
@@ -251,55 +328,30 @@ def GetPathsToSearch(self):
251328 test_dirs = ['cctest' , 'common' , 'fuzzer' , 'inspector' , 'unittests' ]
252329 return dirs + [join ('test' , dir ) for dir in test_dirs ]
253330
254- def GetCpplintScript (self , prio_path ):
255- for path in [prio_path ] + os .environ ["PATH" ].split (os .pathsep ):
331+ def GetProcessorWorker (self ):
332+ return CppLintWorker
333+
334+ def GetProcessorScript (self ):
335+ filters = ',' .join ([n for n in LINT_RULES ])
336+ arguments = ['--filter' , filters ]
337+ for path in [TOOLS_PATH ] + os .environ ["PATH" ].split (os .pathsep ):
256338 path = path .strip ('"' )
257- cpplint = os .path .join (path , " cpplint.py" )
339+ cpplint = os .path .join (path , ' cpplint.py' )
258340 if os .path .isfile (cpplint ):
259- return cpplint
260-
261- return None
262-
263- def ProcessFiles (self , files ):
264- good_files_cache = FileContentsCache ('.cpplint-cache' )
265- good_files_cache .Load ()
266- files = good_files_cache .FilterUnchangedFiles (files )
267- if len (files ) == 0 :
268- print 'No changes in C/C++ files detected. Skipping cpplint check.'
269- return True
270-
271- filters = "," .join ([n for n in LINT_RULES ])
272- cpplint = self .GetCpplintScript (TOOLS_PATH )
273- if cpplint is None :
274- print ('Could not find cpplint.py. Make sure '
275- 'depot_tools is installed and in the path.' )
276- sys .exit (1 )
277-
278- command = [sys .executable , cpplint , '--filter' , filters ]
279-
280- commands = [command + [file ] for file in files ]
281- count = multiprocessing .cpu_count ()
282- pool = multiprocessing .Pool (count )
283- try :
284- results = pool .map_async (CppLintWorker , commands ).get (999999 )
285- except KeyboardInterrupt :
286- print "\n Caught KeyboardInterrupt, terminating workers."
287- sys .exit (1 )
341+ return cpplint , arguments
288342
289- for i in range (len (files )):
290- if results [i ] > 0 :
291- good_files_cache .RemoveFile (files [i ])
343+ return None , arguments
292344
293- total_errors = sum (results )
294- print "Total C/C++ files found that require formatting: %d" % total_errors
295- good_files_cache .Save ()
296- return total_errors == 0
297345
298- class TorqueFormatProcessor (SourceFileProcessor ):
346+ class TorqueFormatProcessor (CacheableSourceFileProcessor ):
299347 """
300348 Check .tq files to verify they follow the Torque style guide.
301349 """
302350
351+ def __init__ (self ):
352+ super (TorqueFormatProcessor , self ).__init__ (
353+ cache_file_path = '.torquelint-cache' , file_type = 'Torque' )
354+
303355 def IsRelevant (self , name ):
304356 return name .endswith ('.tq' )
305357
@@ -308,47 +360,17 @@ def GetPathsToSearch(self):
308360 test_dirs = ['torque' ]
309361 return dirs + [join ('test' , dir ) for dir in test_dirs ]
310362
311- def GetTorquelintScript (self ):
363+ def GetProcessorWorker (self ):
364+ return TorqueLintWorker
365+
366+ def GetProcessorScript (self ):
312367 torque_tools = os .path .join (TOOLS_PATH , "torque" )
313368 torque_path = os .path .join (torque_tools , "format-torque.py" )
314-
369+ arguments = [ '-l' ]
315370 if os .path .isfile (torque_path ):
316- return torque_path
371+ return torque_path , arguments
317372
318- return None
319-
320- def ProcessFiles (self , files ):
321- good_files_cache = FileContentsCache ('.torquelint-cache' )
322- good_files_cache .Load ()
323- files = good_files_cache .FilterUnchangedFiles (files )
324- if len (files ) == 0 :
325- print 'No changes in Torque files detected. Skipping Torque lint check.'
326- return True
327-
328- torquelint = self .GetTorquelintScript ()
329- if torquelint is None :
330- print ('Could not find format-torque.' )
331- sys .exit (1 )
332-
333- command = [sys .executable , torquelint , '-l' ]
334-
335- commands = [command + [file ] for file in files ]
336- count = multiprocessing .cpu_count ()
337- pool = multiprocessing .Pool (count )
338- try :
339- results = pool .map_async (TorqueLintWorker , commands ).get ()
340- except KeyboardInterrupt :
341- print "\n Caught KeyboardInterrupt, terminating workers."
342- sys .exit (1 )
343-
344- for i in range (len (files )):
345- if results [i ] > 0 :
346- good_files_cache .RemoveFile (files [i ])
347-
348- total_errors = sum (results )
349- print "Total Torque files requiring formatting: %d" % total_errors
350- good_files_cache .Save ()
351- return total_errors == 0
373+ return None , arguments
352374
353375COPYRIGHT_HEADER_PATTERN = re .compile (
354376 r'Copyright [\d-]*20[0-1][0-9] the V8 project authors. All rights reserved.' )
@@ -630,6 +652,7 @@ def PyTests(workspace):
630652 print 'Running ' + script
631653 result &= subprocess .call (
632654 [sys .executable , script ], stdout = subprocess .PIPE ) == 0
655+
633656 return result
634657
635658
0 commit comments