Add more presubmit support. Add PRESUBMIT.py to depot_tools.

Changed InputApi.PresubmitLocalPath() to contain the absolute path without the script name.
Review URL: http://codereview.chromium.org/113354

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@16157 0039d316-1c4b-4281-b951-d872f2087c98
experimental/szager/collated-output
maruel@chromium.org 16 years ago
parent 1998c6d137
commit 3d23524cb0

@ -0,0 +1,38 @@
#!/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 depot tools.
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for
details on the presubmit API built into gcl.
"""
def CheckChangeOnUpload(input_api, output_api):
return RunUnitTests(input_api, output_api)
def CheckChangeOnCommit(input_api, output_api):
return (RunUnitTests(input_api, output_api) +
input_api.canned_checks.CheckDoNotSubmit(input_api, output_api))
def RunUnitTests(input_api, output_api):
import unittest
tests_suite = []
test_loader = unittest.TestLoader()
def LoadTests(module_name):
module = __import__(module_name)
for part in module_name.split('.')[1:]:
module = getattr(module, part)
tests_suite.extend(test_loader.loadTestsFromModule(module)._tests)
# List all the test modules to test here:
LoadTests('tests.gcl_unittest')
LoadTests('tests.gclient_test')
LoadTests('tests.presubmit_unittest')
LoadTests('tests.trychange_unittest')
unittest.TextTestRunner(verbosity=0).run(unittest.TestSuite(tests_suite))
# TODO(maruel): Find a way to block the check-in.
return []

@ -181,7 +181,7 @@ class InputApi(object):
self.platform = sys.platform self.platform = sys.platform
# The local path of the currently-being-processed presubmit script. # The local path of the currently-being-processed presubmit script.
self.current_presubmit_path = presubmit_path self._current_presubmit_path = os.path.dirname(presubmit_path)
# We carry the canned checks so presubmit scripts can easily use them. # We carry the canned checks so presubmit scripts can easily use them.
self.canned_checks = presubmit_canned_checks self.canned_checks = presubmit_canned_checks
@ -194,7 +194,7 @@ class InputApi(object):
relative to the PRESUBMIT.py script, so the whole tree can be branched and relative to the PRESUBMIT.py script, so the whole tree can be branched and
the presubmit script still works, without editing its content. the presubmit script still works, without editing its content.
""" """
return self.current_presubmit_path return self._current_presubmit_path
@staticmethod @staticmethod
def DepotToLocalPath(depot_path): def DepotToLocalPath(depot_path):
@ -258,8 +258,7 @@ class InputApi(object):
script, or subdirectories thereof. script, or subdirectories thereof.
""" """
output_files = [] output_files = []
dir_with_slash = normpath( dir_with_slash = normpath("%s/" % self.PresubmitLocalPath())
"%s/" % os.path.dirname(self.current_presubmit_path))
if len(dir_with_slash) == 1: if len(dir_with_slash) == 1:
dir_with_slash = '' dir_with_slash = ''
for af in self.change.AffectedFiles(include_dirs, include_deletes): for af in self.change.AffectedFiles(include_dirs, include_deletes):
@ -630,6 +629,7 @@ def DoPresubmitChecks(change_info,
results = [] results = []
executer = PresubmitExecuter(change_info, committing) executer = PresubmitExecuter(change_info, committing)
for filename in presubmit_files: for filename in presubmit_files:
filename = os.path.abspath(filename)
if verbose: if verbose:
print "Running %s" % filename print "Running %s" % filename
# Accept CRLF presubmit script. # Accept CRLF presubmit script.

@ -0,0 +1,8 @@
#!/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 depot_tools."""
pass

@ -7,6 +7,7 @@
import os import os
import StringIO import StringIO
import sys
import unittest import unittest
# Local imports # Local imports
@ -79,6 +80,8 @@ class PresubmitTestsBase(unittest.TestCase):
def MockGetRepositoryRoot(): def MockGetRepositoryRoot():
return '' return ''
gcl.GetRepositoryRoot = MockGetRepositoryRoot gcl.GetRepositoryRoot = MockGetRepositoryRoot
self._sys_stdout = sys.stdout
sys.stdout = StringIO.StringIO()
def tearDown(self): def tearDown(self):
os.path.isfile = self.original_IsFile os.path.isfile = self.original_IsFile
@ -86,6 +89,7 @@ class PresubmitTestsBase(unittest.TestCase):
gcl.GetSVNFileProperty = self.original_GetSVNFileProperty gcl.GetSVNFileProperty = self.original_GetSVNFileProperty
gcl.ReadFile = self.original_ReadFile gcl.ReadFile = self.original_ReadFile
gcl.GetRepositoryRoot = self.original_GetRepositoryRoot gcl.GetRepositoryRoot = self.original_GetRepositoryRoot
sys.stdout = self._sys_stdout
@staticmethod @staticmethod
def MakeBasicChange(name, description): def MakeBasicChange(name, description):
@ -299,7 +303,7 @@ class PresubmitUnittest(PresubmitTestsBase):
output = StringIO.StringIO() output = StringIO.StringIO()
input = StringIO.StringIO('y\n') input = StringIO.StringIO('y\n')
self.failIf(presubmit.DoPresubmitChecks(ci, False, False, output, input)) self.failIf(presubmit.DoPresubmitChecks(ci, False, True, output, input))
self.failUnless(output.getvalue().count('!!')) self.failUnless(output.getvalue().count('!!'))
def testDoPresubmitChecksPromptsAfterWarnings(self): def testDoPresubmitChecksPromptsAfterWarnings(self):
@ -316,7 +320,7 @@ class PresubmitUnittest(PresubmitTestsBase):
output = StringIO.StringIO() output = StringIO.StringIO()
input = StringIO.StringIO('n\n') # say no to the warning input = StringIO.StringIO('n\n') # say no to the warning
self.failIf(presubmit.DoPresubmitChecks(ci, False, False, output, input)) self.failIf(presubmit.DoPresubmitChecks(ci, False, True, output, input))
self.failUnless(output.getvalue().count('??')) self.failUnless(output.getvalue().count('??'))
output = StringIO.StringIO() output = StringIO.StringIO()
@ -324,7 +328,7 @@ class PresubmitUnittest(PresubmitTestsBase):
self.failUnless(presubmit.DoPresubmitChecks(ci, self.failUnless(presubmit.DoPresubmitChecks(ci,
False, False,
False, True,
output, output,
input)) input))
self.failUnless(output.getvalue().count('??')) self.failUnless(output.getvalue().count('??'))
@ -344,7 +348,7 @@ class PresubmitUnittest(PresubmitTestsBase):
output = StringIO.StringIO() output = StringIO.StringIO()
input = StringIO.StringIO() # should be unused input = StringIO.StringIO() # should be unused
self.failIf(presubmit.DoPresubmitChecks(ci, False, False, output, input)) self.failIf(presubmit.DoPresubmitChecks(ci, False, True, output, input))
self.failUnless(output.getvalue().count('??')) self.failUnless(output.getvalue().count('??'))
self.failUnless(output.getvalue().count('XX!!XX')) self.failUnless(output.getvalue().count('XX!!XX'))
self.failIf(output.getvalue().count('(y/N)')) self.failIf(output.getvalue().count('(y/N)'))
@ -380,11 +384,11 @@ class InputApiUnittest(PresubmitTestsBase):
'DepotToLocalPath', 'FilterTextFiles', 'LocalPaths', 'LocalToDepotPath', 'DepotToLocalPath', 'FilterTextFiles', 'LocalPaths', 'LocalToDepotPath',
'PresubmitLocalPath', 'RightHandSideLines', 'ServerPaths', 'PresubmitLocalPath', 'RightHandSideLines', 'ServerPaths',
'basename', 'cPickle', 'cStringIO', 'canned_checks', 'change', 'basename', 'cPickle', 'cStringIO', 'canned_checks', 'change',
'current_presubmit_path', 'marshal', 'os_path', 'pickle', 'platform', 'marshal', 'os_path', 'pickle', 'platform',
're', 'subprocess', 'tempfile', 'urllib2', 're', 'subprocess', 'tempfile', 'urllib2',
] ]
# If this test fails, you should add the relevant test. # If this test fails, you should add the relevant test.
self.compareMembers(presubmit.InputApi(None, None), members) self.compareMembers(presubmit.InputApi(None, './.'), members)
def testDepotToLocalPath(self): def testDepotToLocalPath(self):
path = presubmit.InputApi.DepotToLocalPath('svn:/foo/smurf') path = presubmit.InputApi.DepotToLocalPath('svn:/foo/smurf')
@ -400,7 +404,7 @@ class InputApiUnittest(PresubmitTestsBase):
def testInputApiConstruction(self): def testInputApiConstruction(self):
# Fudge the change object, it's not used during construction anyway # Fudge the change object, it's not used during construction anyway
api = presubmit.InputApi(change=42, presubmit_path='foo/path') api = presubmit.InputApi(change=42, presubmit_path='foo/path/PRESUBMIT.py')
self.failUnless(api.PresubmitLocalPath() == 'foo/path') self.failUnless(api.PresubmitLocalPath() == 'foo/path')
self.failUnless(api.change == 42) self.failUnless(api.change == 42)
@ -450,13 +454,13 @@ class InputApiUnittest(PresubmitTestsBase):
api = presubmit.InputApi(change, 'foo/PRESUBMIT.py') api = presubmit.InputApi(change, 'foo/PRESUBMIT.py')
affected_files = api.AffectedFiles() affected_files = api.AffectedFiles()
self.failUnless(len(affected_files) == 3) self.assertEquals(len(affected_files), 3)
self.failUnless(affected_files[0].LocalPath() == self.assertEquals(affected_files[0].LocalPath(),
presubmit.normpath('foo/blat.cc')) presubmit.normpath('foo/blat.cc'))
self.failUnless(affected_files[1].LocalPath() == self.assertEquals(affected_files[1].LocalPath(),
presubmit.normpath('foo/blat/binary.dll')) presubmit.normpath('foo/blat/binary.dll'))
self.failUnless(affected_files[2].LocalPath() == self.assertEquals(affected_files[2].LocalPath(),
presubmit.normpath('foo/mat/beingdeleted.txt')) presubmit.normpath('foo/mat/beingdeleted.txt'))
rhs_lines = [] rhs_lines = []
for line in api.RightHandSideLines(): for line in api.RightHandSideLines():
@ -596,64 +600,64 @@ class CannedChecksUnittest(PresubmitTestsBase):
def testCannedCheckChangeHasBugField(self): def testCannedCheckChangeHasBugField(self):
change = self.MakeBasicChange('foo', change = self.MakeBasicChange('foo',
'Foo\nBUG=1234') 'Foo\nBUG=1234')
api = presubmit.InputApi(change, 'PRESUBMIT.py') api = presubmit.InputApi(change, './PRESUBMIT.py')
self.failIf(presubmit_canned_checks.CheckChangeHasBugField( self.failIf(presubmit_canned_checks.CheckChangeHasBugField(
api, presubmit.OutputApi)) api, presubmit.OutputApi))
change = self.MakeBasicChange('foo', change = self.MakeBasicChange('foo',
'Foo\nNEVERTESTED=did some stuff') 'Foo\nNEVERTESTED=did some stuff')
api = presubmit.InputApi(change, 'PRESUBMIT.py') api = presubmit.InputApi(change, './PRESUBMIT.py')
self.failUnless(presubmit_canned_checks.CheckChangeHasBugField( self.failUnless(presubmit_canned_checks.CheckChangeHasBugField(
api, presubmit.OutputApi)) api, presubmit.OutputApi))
def testCannedCheckChangeHasTestField(self): def testCannedCheckChangeHasTestField(self):
change = self.MakeBasicChange('foo', change = self.MakeBasicChange('foo',
'Foo\nTEST=did some stuff') 'Foo\nTEST=did some stuff')
api = presubmit.InputApi(change, 'PRESUBMIT.py') api = presubmit.InputApi(change, './PRESUBMIT.py')
self.failIf(presubmit_canned_checks.CheckChangeHasTestField( self.failIf(presubmit_canned_checks.CheckChangeHasTestField(
api, presubmit.OutputApi)) api, presubmit.OutputApi))
change = self.MakeBasicChange('foo', change = self.MakeBasicChange('foo',
'Foo\nNOTEST=did some stuff') 'Foo\nNOTEST=did some stuff')
api = presubmit.InputApi(change, 'PRESUBMIT.py') api = presubmit.InputApi(change, './PRESUBMIT.py')
self.failUnless(presubmit_canned_checks.CheckChangeHasTestField( self.failUnless(presubmit_canned_checks.CheckChangeHasTestField(
api, presubmit.OutputApi)) api, presubmit.OutputApi))
def testCannedCheckChangeHasTestedField(self): def testCannedCheckChangeHasTestedField(self):
change = self.MakeBasicChange('foo', change = self.MakeBasicChange('foo',
'Foo\nTESTED=did some stuff') 'Foo\nTESTED=did some stuff')
api = presubmit.InputApi(change, 'PRESUBMIT.py') api = presubmit.InputApi(change, './PRESUBMIT.py')
self.failIf(presubmit_canned_checks.CheckChangeHasTestedField( self.failIf(presubmit_canned_checks.CheckChangeHasTestedField(
api, presubmit.OutputApi)) api, presubmit.OutputApi))
change = self.MakeBasicChange('foo', change = self.MakeBasicChange('foo',
'Foo\nNEVERTESTED=did some stuff') 'Foo\nNEVERTESTED=did some stuff')
api = presubmit.InputApi(change, 'PRESUBMIT.py') api = presubmit.InputApi(change, './PRESUBMIT.py')
self.failUnless(presubmit_canned_checks.CheckChangeHasTestedField( self.failUnless(presubmit_canned_checks.CheckChangeHasTestedField(
api, presubmit.OutputApi)) api, presubmit.OutputApi))
def testCannedCheckChangeHasQAField(self): def testCannedCheckChangeHasQAField(self):
change = self.MakeBasicChange('foo', change = self.MakeBasicChange('foo',
'Foo\nQA=test floop feature very well') 'Foo\nQA=test floop feature very well')
api = presubmit.InputApi(change, 'PRESUBMIT.py') api = presubmit.InputApi(change, './PRESUBMIT.py')
self.failIf(presubmit_canned_checks.CheckChangeHasQaField( self.failIf(presubmit_canned_checks.CheckChangeHasQaField(
api, presubmit.OutputApi)) api, presubmit.OutputApi))
change = self.MakeBasicChange('foo', change = self.MakeBasicChange('foo',
'Foo\nNOTFORQA=test floop feature very well') 'Foo\nNOTFORQA=test floop feature very well')
api = presubmit.InputApi(change, 'PRESUBMIT.py') api = presubmit.InputApi(change, './PRESUBMIT.py')
self.failUnless(presubmit_canned_checks.CheckChangeHasQaField( self.failUnless(presubmit_canned_checks.CheckChangeHasQaField(
api, presubmit.OutputApi)) api, presubmit.OutputApi))
def testCannedCheckDoNotSubmitInDescription(self): def testCannedCheckDoNotSubmitInDescription(self):
change = self.MakeBasicChange('foo', 'hello') change = self.MakeBasicChange('foo', 'hello')
api = presubmit.InputApi(change, 'PRESUBMIT.py') api = presubmit.InputApi(change, './PRESUBMIT.py')
self.failIf(presubmit_canned_checks.CheckDoNotSubmitInDescription( self.failIf(presubmit_canned_checks.CheckDoNotSubmitInDescription(
api, presubmit.OutputApi)) api, presubmit.OutputApi))
change = self.MakeBasicChange('foo', change = self.MakeBasicChange('foo',
'DO NOT ' + 'SUBMIT') 'DO NOT ' + 'SUBMIT')
api = presubmit.InputApi(change, 'PRESUBMIT.py') api = presubmit.InputApi(change, './PRESUBMIT.py')
self.failUnless(presubmit_canned_checks.CheckDoNotSubmitInDescription( self.failUnless(presubmit_canned_checks.CheckDoNotSubmitInDescription(
api, presubmit.OutputApi)) api, presubmit.OutputApi))

Loading…
Cancel
Save