Commit 3d23524c authored by maruel@chromium.org's avatar maruel@chromium.org

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
parent 1998c6d1
#!/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): ...@@ -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): ...@@ -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): ...@@ -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, ...@@ -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.
......
#!/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 @@ ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment