More PRESUBMIT checks.
Checks for:
- No iostream includes in headers
- No use of FRIEND_TEST for gtest
- Verifies that all C/C++ code passes cpplint.py check.
- Verifies that BUG= is present in commit message
- Verifies that TEST= is present in commit message
For more details, see Chrome's PRESUBMIT.py at
http://src.chromium.org/viewvc/chrome/trunk/src/PRESUBMIT.py?revision=113979&view=markup
and the canned checks at
http://src.chromium.org/viewvc/chrome/trunk/tools/depot_tools/presubmit_canned_checks.py?view=markup
BUG=
TEST=
Review URL: https://webrtc-codereview.appspot.com/317011
git-svn-id: http://webrtc.googlecode.com/svn/trunk@1737 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 33bdab3..56c8d5b 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -23,8 +23,91 @@
}
return license_header
+def _CheckNoIOStreamInHeaders(input_api, output_api):
+ """Checks to make sure no .h files include <iostream>."""
+ files = []
+ pattern = input_api.re.compile(r'^#include\s*<iostream>',
+ input_api.re.MULTILINE)
+ for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
+ if not f.LocalPath().endswith('.h'):
+ continue
+ contents = input_api.ReadFile(f)
+ if pattern.search(contents):
+ files.append(f)
+
+ if len(files):
+ return [ output_api.PresubmitError(
+ 'Do not #include <iostream> in header files, since it inserts static ' +
+ 'initialization into every file including the header. Instead, ' +
+ '#include <ostream>. See http://crbug.com/94794',
+ files) ]
+ return []
+
+def _CheckNoFRIEND_TEST(input_api, output_api):
+ """Make sure that gtest's FRIEND_TEST() macro is not used, the
+ FRIEND_TEST_ALL_PREFIXES() macro from testsupport/gtest_prod_util.h should be
+ used instead since that allows for FLAKY_, FAILS_ and DISABLED_ prefixes."""
+ problems = []
+
+ file_filter = lambda f: f.LocalPath().endswith(('.cc', '.h'))
+ for f in input_api.AffectedFiles(file_filter=file_filter):
+ for line_num, line in f.ChangedContents():
+ if 'FRIEND_TEST(' in line:
+ problems.append(' %s:%d' % (f.LocalPath(), line_num))
+
+ if not problems:
+ return []
+ return [output_api.PresubmitPromptWarning('WebRTC\'s code should not use '
+ 'gtest\'s FRIEND_TEST() macro. Include testsupport/gtest_prod_util.h and '
+ 'use FRIEND_TEST_ALL_PREFIXES() instead.\n' + '\n'.join(problems))]
+
+def _CheckNewFilesLintClean(input_api, output_api, source_file_filter=None):
+ """Checks that all NEW '.cc' and '.h' files pass cpplint.py.
+ This check is based on _CheckChangeLintsClean in
+ depot_tools/presubmit_canned_checks.py but has less filters and only checks
+ added files."""
+ result = []
+
+ # Initialize cpplint.
+ import cpplint
+ # Access to a protected member _XX of a client class
+ # pylint: disable=W0212
+ cpplint._cpplint_state.ResetErrorCounts()
+
+ # Justifications for each filter:
+ #
+ # - build/header_guard : WebRTC coding style says they should be prefixed
+ # with WEBRTC_, which is not possible to configure in
+ # cpplint.py.
+ cpplint._SetFilters('-build/header_guard')
+
+ # Use the strictest verbosity level for cpplint.py (level 1) which is the
+ # default when running cpplint.py from command line.
+ # To make it possible to work with not-yet-converted code, we're only applying
+ # it to new (or moved/renamed) files.
+ verbosity_level = 1
+ files = []
+ for f in input_api.AffectedSourceFiles(source_file_filter):
+ # Note that moved/renamed files also count as added for svn.
+ if (f.Action() == 'A'):
+ files.append(f.AbsoluteLocalPath())
+ for file_name in files:
+ cpplint.ProcessFile(file_name, verbosity_level)
+
+ if cpplint._cpplint_state.error_count > 0:
+ if input_api.is_committing:
+ # TODO(kjellander): Change back to PresubmitError below when we're
+ # confident with the lint settings.
+ res_type = output_api.PresubmitPromptWarning
+ else:
+ res_type = output_api.PresubmitPromptWarning
+ result = [res_type('Changelist failed cpplint.py check.')]
+
+ return result
+
def _CommonChecks(input_api, output_api):
"""Checks common to both upload and commit."""
+ # TODO(kjellander): Use presubmit_canned_checks.PanProjectChecks too.
results = []
results.extend(input_api.canned_checks.CheckLongLines(
input_api, output_api))
@@ -34,8 +117,11 @@
input_api, output_api))
results.extend(input_api.canned_checks.CheckChangeTodoHasOwner(
input_api, output_api))
+ results.extend(_CheckNewFilesLintClean(input_api, output_api))
results.extend(input_api.canned_checks.CheckLicense(
input_api, output_api, _LicenseHeader(input_api)))
+ results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
+ results.extend(_CheckNoFRIEND_TEST(input_api, output_api))
return results
def CheckChangeOnUpload(input_api, output_api):
@@ -51,4 +137,8 @@
input_api, output_api))
results.extend(input_api.canned_checks.CheckChangeHasDescription(
input_api, output_api))
+ results.extend(input_api.canned_checks.CheckChangeHasBugField(
+ input_api, output_api))
+ results.extend(input_api.canned_checks.CheckChangeHasTestField(
+ input_api, output_api))
return results