Commit 0ff1fab8 authored by maruel@chromium.org's avatar maruel@chromium.org

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
parent 657aaf25
...@@ -607,7 +607,7 @@ Basic commands: ...@@ -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): ...@@ -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, ...@@ -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, ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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 = [
......
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