Add repository root presubmit support.

Review URL: http://codereview.chromium.org/115616

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@16738 0039d316-1c4b-4281-b951-d872f2087c98
experimental/szager/collated-output
maruel@chromium.org 16 years ago
parent 657aaf250d
commit 0ff1fab804

@ -607,7 +607,7 @@ Basic commands:
[--send_mail] [--no_try] [--no_presubmit] [--send_mail] [--no_try] [--no_presubmit]
Uploads the changelist to the server for review. Uploads the changelist to the server for review.
gcl commit change_name [--force] gcl commit change_name [--no_presubmit] [--force]
Commits the changelist to the repository. Commits the changelist to the repository.
gcl lint change_name gcl lint change_name
@ -1023,11 +1023,13 @@ def DoPresubmitChecks(change_info, committing):
"""Imports presubmit, then calls presubmit.DoPresubmitChecks.""" """Imports presubmit, then calls presubmit.DoPresubmitChecks."""
# Need to import here to avoid circular dependency. # Need to import here to avoid circular dependency.
import presubmit_support import presubmit_support
root_presubmit = GetCachedFile('PRESUBMIT.py', use_root=True)
result = presubmit_support.DoPresubmitChecks(change_info, result = presubmit_support.DoPresubmitChecks(change_info,
committing, committing,
verbose=False, verbose=False,
output_stream=sys.stdout, output_stream=sys.stdout,
input_stream=sys.stdin) input_stream=sys.stdin,
default_presubmit=root_presubmit)
if not result: if not result:
print "\nPresubmit errors, can't continue (use --no_presubmit to bypass)" print "\nPresubmit errors, can't continue (use --no_presubmit to bypass)"
return result return result

@ -603,7 +603,8 @@ def DoPresubmitChecks(change_info,
committing, committing,
verbose, verbose,
output_stream, output_stream,
input_stream): input_stream,
default_presubmit):
"""Runs all presubmit checks that apply to the files in the change. """Runs all presubmit checks that apply to the files in the change.
This finds all PRESUBMIT.py files in directories enclosing the files in the This finds all PRESUBMIT.py files in directories enclosing the files in the
@ -619,19 +620,24 @@ def DoPresubmitChecks(change_info,
verbose: Prints debug info. verbose: Prints debug info.
output_stream: A stream to write output from presubmit tests to. output_stream: A stream to write output from presubmit tests to.
input_stream: A stream to read input from the user. input_stream: A stream to read input from the user.
default_presubmit: A default presubmit script to execute in any case.
Return: Return:
True if execution can continue, False if not. True if execution can continue, False if not.
""" """
presubmit_files = ListRelevantPresubmitFiles(change_info.FileList()) presubmit_files = ListRelevantPresubmitFiles(change_info.FileList())
if not presubmit_files and verbose: if not presubmit_files and verbose:
print "Warning, no presubmit.py found." output_stream.write("Warning, no presubmit.py found.")
results = [] results = []
executer = PresubmitExecuter(change_info, committing) executer = PresubmitExecuter(change_info, committing)
if default_presubmit:
if verbose:
output_stream.write("Running default presubmit script")
results += executer.ExecPresubmitScript(default_presubmit, 'PRESUBMIT.py')
for filename in presubmit_files: for filename in presubmit_files:
filename = os.path.abspath(filename) filename = os.path.abspath(filename)
if verbose: if verbose:
print "Running %s" % filename output_stream.write("Running %s" % filename)
# Accept CRLF presubmit script. # Accept CRLF presubmit script.
presubmit_script = gcl.ReadFile(filename, 'rU') presubmit_script = gcl.ReadFile(filename, 'rU')
results += executer.ExecPresubmitScript(presubmit_script, filename) results += executer.ExecPresubmitScript(presubmit_script, filename)
@ -701,11 +707,12 @@ def Main(argv):
files = ParseFiles(args, options.recursive) files = ParseFiles(args, options.recursive)
if options.verbose: if options.verbose:
print "Found %d files." % len(files) print "Found %d files." % len(files)
return DoPresubmitChecks(gcl.ChangeInfo(name='temp', files=files), return not DoPresubmitChecks(gcl.ChangeInfo(name='temp', files=files),
options.commit, options.commit,
options.verbose, options.verbose,
sys.stdout, sys.stdout,
sys.stdin) sys.stdin,
default_presubmit=None)
if __name__ == '__main__': if __name__ == '__main__':

@ -79,7 +79,7 @@ class GclUnittest(GclTestsBase):
dummy = StringIO.StringIO() dummy = StringIO.StringIO()
gcl.sys.stdout = dummy gcl.sys.stdout = dummy
gcl.Help() gcl.Help()
self.assertEquals(len(dummy.getvalue()), 1815) self.assertEquals(len(dummy.getvalue()), 1832)
finally: finally:
gcl.sys.stdout = old_stdout gcl.sys.stdout = old_stdout

@ -62,16 +62,18 @@ class PresubmitTestsBase(unittest.TestCase):
self.fail('Should not attempt to read file that is directory.') self.fail('Should not attempt to read file that is directory.')
elif path.endswith('PRESUBMIT.py'): elif path.endswith('PRESUBMIT.py'):
# used in testDoPresubmitChecks # used in testDoPresubmitChecks
return ('def CheckChangeOnUpload(input_api, output_api):\n' return """
' if not input_api.change.NOSUCHKEY:\n' def CheckChangeOnUpload(input_api, output_api):
' return [output_api.PresubmitError("!!")]\n' if not input_api.change.NOSUCHKEY:
' elif not input_api.change.REALLYNOSUCHKEY:\n' return [output_api.PresubmitError("!!")]
' return [output_api.PresubmitPromptWarning("??")]\n' elif not input_api.change.REALLYNOSUCHKEY:
' elif not input_api.change.REALLYABSOLUTELYNOSUCHKEY:\n' return [output_api.PresubmitPromptWarning("??")]
' return [output_api.PresubmitPromptWarning("??"),\n' elif not input_api.change.REALLYABSOLUTELYNOSUCHKEY:
' output_api.PresubmitError("XX!!XX")]\n' return [output_api.PresubmitPromptWarning("??"),
' else:\n' output_api.PresubmitError("XX!!XX")]
' return ()') else:
return ()
"""
else: else:
return 'one:%s\r\ntwo:%s' % (path, path) return 'one:%s\r\ntwo:%s' % (path, path)
gcl.ReadFile = MockReadFile gcl.ReadFile = MockReadFile
@ -303,8 +305,9 @@ 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, True, output, input)) self.failIf(presubmit.DoPresubmitChecks(ci, False, True, output, input,
self.failUnless(output.getvalue().count('!!')) None))
self.assertEqual(output.getvalue().count('!!'), 2)
def testDoPresubmitChecksPromptsAfterWarnings(self): def testDoPresubmitChecksPromptsAfterWarnings(self):
description_lines = ('Hello there', description_lines = ('Hello there',
@ -320,8 +323,9 @@ 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, True, output, input)) self.failIf(presubmit.DoPresubmitChecks(ci, False, True, output, input,
self.failUnless(output.getvalue().count('??')) None))
self.assertEqual(output.getvalue().count('??'), 2)
output = StringIO.StringIO() output = StringIO.StringIO()
input = StringIO.StringIO('y\n') # say yes to the warning input = StringIO.StringIO('y\n') # say yes to the warning
@ -330,7 +334,8 @@ class PresubmitUnittest(PresubmitTestsBase):
False, False,
True, True,
output, output,
input)) input,
None))
self.failUnless(output.getvalue().count('??')) self.failUnless(output.getvalue().count('??'))
def testDoPresubmitChecksNoWarningPromptIfErrors(self): def testDoPresubmitChecksNoWarningPromptIfErrors(self):
@ -348,10 +353,40 @@ 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, True, output, input)) self.failIf(presubmit.DoPresubmitChecks(ci, False, True, output, input,
self.failUnless(output.getvalue().count('??')) None))
self.failUnless(output.getvalue().count('XX!!XX')) self.assertEqual(output.getvalue().count('??'), 2)
self.failIf(output.getvalue().count('(y/N)')) self.assertEqual(output.getvalue().count('XX!!XX'), 2)
self.assertEqual(output.getvalue().count('(y/N)'), 0)
def testDoDefaultPresubmitChecks(self):
description_lines = ('Hello there',
'this is a change',
'STORY=http://tracker/123')
files = [
['A', 'haspresubmit\\blat.cc'],
]
ci = gcl.ChangeInfo(name='mychange',
description='\n'.join(description_lines),
files=files)
output = StringIO.StringIO()
input = StringIO.StringIO('y\n')
# Always fail.
DEFAULT_SCRIPT = """
def CheckChangeOnUpload(input_api, output_api):
print 'This is a test'
return [output_api.PresubmitError("!!")]
"""
def MockReadFile(dummy):
return ''
gcl.ReadFile = MockReadFile
def MockIsFile(dummy):
return False
os.path.isfile = MockIsFile
self.failIf(presubmit.DoPresubmitChecks(ci, False, True, output, input,
DEFAULT_SCRIPT))
self.assertEquals(output.getvalue().count('!!'), 1)
def testDirectoryHandling(self): def testDirectoryHandling(self):
files = [ files = [

Loading…
Cancel
Save