Home | History | Annotate | Download | only in checkstyle
      1 # Copyright 2013 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """Script that is used by PRESUBMIT.py to run style checks on Java files."""
      6 
      7 import os
      8 import subprocess
      9 
     10 
     11 def RunCheckstyle(input_api, output_api, style_file):
     12   if not os.path.exists(style_file):
     13     file_error = ('  Java checkstyle configuration file is missing: '
     14                   + style_file)
     15     return [output_api.PresubmitError(file_error)]
     16 
     17   # Filter out non-Java files and files that were deleted.
     18   java_files = [x.LocalPath() for x in input_api.AffectedFiles(False, False)
     19                 if os.path.splitext(x.LocalPath())[1] == '.java']
     20   if not java_files:
     21     return []
     22 
     23   # Run checkstyle
     24   checkstyle_env = os.environ.copy()
     25   checkstyle_env['JAVA_CMD'] = 'java'
     26   try:
     27     check = subprocess.Popen(['checkstyle', '-c', style_file] + java_files,
     28                              stdout=subprocess.PIPE, env=checkstyle_env)
     29     stdout, _ = check.communicate()
     30     if check.returncode == 0:
     31       return []
     32   except OSError as e:
     33     import errno
     34     if e.errno == errno.ENOENT:
     35       install_error = ('  checkstyle is not installed. Please run '
     36                        'build/install-build-deps-android.sh')
     37       return [output_api.PresubmitPromptWarning(install_error)]
     38 
     39   # Remove non-error values from stdout
     40   errors = stdout.splitlines()
     41 
     42   if errors and errors[0] == 'Starting audit...':
     43     del errors[0]
     44   if errors and errors[-1] == 'Audit done.':
     45     del errors[-1]
     46 
     47   # Filter out warnings
     48   errors = [x for x in errors if 'warning: ' not in x]
     49   if not errors:
     50     return []
     51 
     52   local_path = input_api.PresubmitLocalPath()
     53   output = []
     54   for error in errors:
     55     # Change the full file path to relative path in the output lines
     56     full_path, end = error.split(':', 1)
     57     rel_path = os.path.relpath(full_path, local_path)
     58     output.append('  %s:%s' % (rel_path, end))
     59   return [output_api.PresubmitPromptWarning('\n'.join(output))]