0

Very basic starter presubmit script for Chromium, as requested by maruel.

At present this checks the following:
- No tabs in source files
- The words "DO-NOT-SUBMIT" (without the dashes) do not appear in the CL
  description or in files in the change
- No CRLF in source files (.cc, .h, .mm, .py)

Limitations:
- The general limitations of the current presubmit API implementation
  apply.  One of these is that gcl only walks up to the checkout root
  searching for presubmit files, so if you've mapped stuff into your
  client using DEPS, it will only walk up to where the root of that
  mapping.

Patch contributed by Jói.

Review: http://codereview.chromium.org/20474


git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10015 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
maruel@chromium.org
2009-02-19 16:33:12 +00:00
parent 1402c866ad
commit ca8d1984ce
2 changed files with 148 additions and 0 deletions

73
PRESUBMIT.py Executable file

@ -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

75
PRESUBMIT_unittest.py Executable file

@ -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()