- Add a presubmit check that lints C++ files (will submit CLs that
  add this to PRESUBMIT.py in the chromium tree later).
- Update cpplint.py to the latest version from the style guide.

Review URL: http://codereview.chromium.org/395022

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@32180 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/presubmit_canned_checks.py b/presubmit_canned_checks.py
index f9088d7..3a57490 100755
--- a/presubmit_canned_checks.py
+++ b/presubmit_canned_checks.py
@@ -5,7 +5,6 @@
 
 """Generic presubmit checks that can be reused by other presubmit checks."""
 
-
 ### Description checks
 
 def CheckChangeHasTestField(input_api, output_api):
@@ -76,6 +75,51 @@
   return []
 
 
+def CheckChangeLintsClean(input_api, output_api, source_file_filter=None):
+  """Checks that all ".cc" and ".h" files pass cpplint.py."""
+  _RE_IS_TEST = input_api.re.compile(r'.*tests?.(cc|h)$')
+  result = []
+
+  # Initialize cpplint.
+  import cpplint
+  cpplint._cpplint_state.ResetErrorCounts()
+
+  # Justifications for each filter:
+  #
+  # - build/include       : Too many; fix in the future.
+  # - build/include_order : Not happening; #ifdefed includes.
+  # - build/namespace     : I'm surprised by how often we violate this rule.
+  # - readability/casting : Mistakes a whole bunch of function pointer.
+  # - runtime/int         : Can be fixed long term; volume of errors too high
+  # - runtime/virtual     : Broken now, but can be fixed in the future?
+  # - whitespace/braces   : We have a lot of explicit scoping in chrome code.
+  cpplint._SetFilters("-build/include,-build/include_order,-build/namespace,"
+                      "-readability/casting,-runtime/int,-runtime/virtual,"
+                      "-whitespace/braces")
+
+  # We currently are more strict with normal code than unit tests; 4 and 5 are
+  # the verbosity level that would normally be passed to cpplint.py through
+  # --verbose=#. Hopefully, in the future, we can be more verbose.
+  files = [f.AbsoluteLocalPath() for f in
+           input_api.AffectedSourceFiles(source_file_filter)]
+  for file_name in files:
+    if _RE_IS_TEST.match(file_name):
+      level = 5
+    else:
+      level = 4
+
+    cpplint.ProcessFile(file_name, level)
+
+  if cpplint._cpplint_state.error_count > 0:
+    if input_api.is_committing:
+      res_type = output_api.PresubmitError
+    else:
+      res_type = output_api.PresubmitPromptWarning
+    result = [res_type("Changelist failed cpplint.py check.")]
+
+  return result
+
+
 def CheckChangeHasNoCR(input_api, output_api, source_file_filter=None):
   """Checks no '\r' (CR) character is in any source files."""
   cr_files = []