summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xPRESUBMIT.py73
-rwxr-xr-xPRESUBMIT_unittest.py75
2 files changed, 148 insertions, 0 deletions
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
new file mode 100755
index 0000000..1340216
--- /dev/null
+++ b/PRESUBMIT.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+# Copyright (c) 2009 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Top-level presubmit script for Chromium.
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for
+details on the presubmit API built into gcl.
+"""
+
+
+import os
+
+
+# Files with these extensions will be considered source files
+SOURCE_FILE_EXTENSIONS = ['.c', '.cc', '.cpp', '.h', '.m', '.mm', '.py']
+
+
+def ReadFile(path):
+ """Given a path, returns the full contents of the file.
+
+ Reads files in binary format.
+ """
+ fo = open(path, 'rb')
+ try:
+ contents = fo.read()
+ finally:
+ fo.close()
+ return contents
+
+
+# Seam for unit testing
+_ReadFile = ReadFile
+
+
+def CheckChangeOnUpload(input_api, output_api):
+ return (CheckNoCrOrTabs(input_api, output_api) +
+ input_api.canned_checks.CheckDoNotSubmit(input_api, output_api))
+
+
+def CheckChangeOnCommit(input_api, output_api):
+ # No extra checks on commit for now
+ return CheckChangeOnUpload(input_api, output_api)
+
+
+def CheckNoCrOrTabs(input_api, output_api):
+ """Reports an error if source files use CR (or CRLF) or TAB.
+ """
+ cr_files = []
+ tab_files = []
+ results = []
+
+ for f in input_api.AffectedTextFiles(include_deletes=False):
+ path = f.LocalPath()
+ root, ext = os.path.splitext(path)
+ if ext in SOURCE_FILE_EXTENSIONS:
+ # Need to read the file ourselves since AffectedFile.NewContents()
+ # will normalize line endings.
+ contents = _ReadFile(path)
+ if '\r' in contents:
+ cr_files.append(path)
+ if '\t' in contents:
+ tab_files.append(path)
+ if cr_files:
+ results.append(output_api.PresubmitError(
+ 'Found CR (or CRLF) line ending in these files, please use only LF:',
+ items=cr_files))
+ if tab_files:
+ results.append(output_api.PresubmitError(
+ 'Found tabs in the following files, please use spaces',
+ items=tab_files))
+ return results
diff --git a/PRESUBMIT_unittest.py b/PRESUBMIT_unittest.py
new file mode 100755
index 0000000..5a2c514
--- /dev/null
+++ b/PRESUBMIT_unittest.py
@@ -0,0 +1,75 @@
+#!/usr/bin/python
+# Copyright (c) 2009 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Unit tests for top-level Chromium presubmit script.
+"""
+
+
+import PRESUBMIT
+import unittest
+
+
+class MockInputApi(object):
+ def __init__(self):
+ self.affected_files = []
+
+ def AffectedTextFiles(self, include_deletes=True):
+ return self.affected_files
+
+
+class MockAffectedFile(object):
+ def __init__(self, path):
+ self.path = path
+
+ def LocalPath(self):
+ return self.path
+
+
+class MockOutputApi(object):
+ class PresubmitError(object):
+ def __init__(self, msg, items):
+ self.msg = msg
+ self.items = items
+
+
+class PresubmitUnittest(unittest.TestCase):
+ def setUp(self):
+ self.file_contents = ''
+ def MockReadFile(path):
+ self.failIf(path.endswith('notsource'))
+ return self.file_contents
+ PRESUBMIT._ReadFile = MockReadFile
+
+ def tearDown(self):
+ PRESUBMIT._ReadFile = PRESUBMIT.ReadFile
+
+ def testCheckNoCrLfOrTabs(self):
+ api = MockInputApi()
+ api.affected_files = [
+ MockAffectedFile('foo/blat/yoo.notsource'),
+ MockAffectedFile('foo/blat/source.h'),
+ MockAffectedFile('foo/blat/source.mm'),
+ MockAffectedFile('foo/blat/source.py'),
+ ]
+ self.file_contents = 'file with\nerror\nhere\r\nyes there'
+ self.failUnless(len(PRESUBMIT.CheckNoCrOrTabs(api, MockOutputApi)) == 1)
+ self.failUnless(
+ len(PRESUBMIT.CheckNoCrOrTabs(api, MockOutputApi)[0].items) == 3)
+
+ self.file_contents = 'file\twith\ttabs'
+ self.failUnless(len(PRESUBMIT.CheckNoCrOrTabs(api, MockOutputApi)) == 1)
+
+ self.file_contents = 'file\rusing\rCRs'
+ self.failUnless(len(PRESUBMIT.CheckNoCrOrTabs(api, MockOutputApi)) == 1)
+
+ self.file_contents = 'both\ttabs and\r\nCRLF'
+ self.failUnless(len(PRESUBMIT.CheckNoCrOrTabs(api, MockOutputApi)) == 2)
+
+ self.file_contents = 'file with\nzero \\t errors \\r\\n'
+ self.failIf(PRESUBMIT.CheckNoCrOrTabs(api, MockOutputApi))
+
+
+if __name__ == '__main__':
+ unittest.main()