#!/usr/bin/env python # # Copyright (C) 2009 Google Inc. All rights reserved. # Copyright (C) 2010 Chris Jerdonek (chris.jerdonek@gmail.com) # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Does WebKit-lint on C/C++ or text files. The goal of this script is to identify places in the code that *may* be in non-compliance with WebKit style. It does not attempt to fix up these problems -- the point is to educate. It does also not attempt to find all problems, or to ensure that everything it does find is legitimately a problem. In particular, we can get very confused by /* and // inside strings! We do a small hack, which is to ignore //'s with "'s after them on the same line, but it is far from perfect (in either direction). """ import codecs import logging import os import os.path import sys from webkitpy.style_references import detect_checkout import webkitpy.style.checker as checker from webkitpy.style.patchreader import PatchReader from webkitpy.style.checker import StyleProcessor from webkitpy.style.filereader import TextFileReader from webkitpy.style.main import change_directory _log = logging.getLogger("check-webkit-style") # FIXME: Move this code to style.main. def main(): # Change stderr to write with replacement characters so we don't die # if we try to print something containing non-ASCII characters. stderr = codecs.StreamReaderWriter(sys.stderr, codecs.getreader('utf8'), codecs.getwriter('utf8'), 'replace') # Setting an "encoding" attribute on the stream is necessary to # prevent the logging module from raising an error. See # the checker.configure_logging() function for more information. stderr.encoding = "UTF-8" # FIXME: Change webkitpy.style so that we do not need to overwrite # the global sys.stderr. This involves updating the code to # accept a stream parameter where necessary, and not calling # sys.stderr explicitly anywhere. sys.stderr = stderr args = sys.argv[1:] # Checking for the verbose flag before calling check_webkit_style_parser() # lets us enable verbose logging earlier. is_verbose = "-v" in args or "--verbose" in args checker.configure_logging(stream=stderr, is_verbose=is_verbose) _log.debug("Verbose logging enabled.") parser = checker.check_webkit_style_parser() (paths, options) = parser.parse(args) checkout = detect_checkout() if checkout is None: if not paths: _log.error("WebKit checkout not found: You must run this script " "from within a WebKit checkout if you are not passing " "specific paths to check.") sys.exit(1) checkout_root = None _log.debug("WebKit checkout not found for current directory.") else: checkout_root = checkout.root_path() _log.debug("WebKit checkout found with root: %s" % checkout_root) configuration = checker.check_webkit_style_configuration(options) paths = change_directory(checkout_root=checkout_root, paths=paths) style_processor = StyleProcessor(configuration) file_reader = TextFileReader(style_processor) if paths and not options.diff_files: file_reader.process_paths(paths) else: changed_files = paths if options.diff_files else None patch = checkout.create_patch(options.git_commit, changed_files=changed_files) patch_checker = PatchReader(file_reader) patch_checker.check(patch) error_count = style_processor.error_count file_count = file_reader.file_count delete_only_file_count = file_reader.delete_only_file_count _log.info("Total errors found: %d in %d files" % (error_count, file_count)) # We fail when style errors are found or there are no checked files. sys.exit(error_count > 0 or (file_count == 0 and delete_only_file_count == 0)) if __name__ == "__main__": main()