| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Enables directory-specific presubmit checks to run at upload and/or commit. | 6 """Enables directory-specific presubmit checks to run at upload and/or commit. |
| 7 """ | 7 """ |
| 8 | 8 |
| 9 __version__ = '1.6.1' | 9 __version__ = '1.6.1' |
| 10 | 10 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 def write(self, s): | 97 def write(self, s): |
| 98 self.written_output.append(s) | 98 self.written_output.append(s) |
| 99 if self.output_stream: | 99 if self.output_stream: |
| 100 self.output_stream.write(s) | 100 self.output_stream.write(s) |
| 101 | 101 |
| 102 def getvalue(self): | 102 def getvalue(self): |
| 103 return ''.join(self.written_output) | 103 return ''.join(self.written_output) |
| 104 | 104 |
| 105 | 105 |
| 106 class OutputApi(object): | 106 class OutputApi(object): |
| 107 """This class (more like a module) gets passed to presubmit scripts so that | 107 """An instance of OutputApi gets passed to presubmit scripts so that they |
| 108 they can specify various types of results. | 108 can output various types of results. |
| 109 """ | 109 """ |
| 110 def __init__(self, is_committing): |
| 111 self.is_committing = is_committing |
| 112 |
| 110 class PresubmitResult(object): | 113 class PresubmitResult(object): |
| 111 """Base class for result objects.""" | 114 """Base class for result objects.""" |
| 112 fatal = False | 115 fatal = False |
| 113 should_prompt = False | 116 should_prompt = False |
| 114 | 117 |
| 115 def __init__(self, message, items=None, long_text=''): | 118 def __init__(self, message, items=None, long_text=''): |
| 116 """ | 119 """ |
| 117 message: A short one-line message to indicate errors. | 120 message: A short one-line message to indicate errors. |
| 118 items: A list of short strings to indicate where errors occurred. | 121 items: A list of short strings to indicate where errors occurred. |
| 119 long_text: multi-line text output, e.g. from another tool | 122 long_text: multi-line text output, e.g. from another tool |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 fatal = True | 159 fatal = True |
| 157 | 160 |
| 158 class PresubmitPromptWarning(PresubmitResult): | 161 class PresubmitPromptWarning(PresubmitResult): |
| 159 """An warning that prompts the user if they want to continue.""" | 162 """An warning that prompts the user if they want to continue.""" |
| 160 should_prompt = True | 163 should_prompt = True |
| 161 | 164 |
| 162 class PresubmitNotifyResult(PresubmitResult): | 165 class PresubmitNotifyResult(PresubmitResult): |
| 163 """Just print something to the screen -- but it's not even a warning.""" | 166 """Just print something to the screen -- but it's not even a warning.""" |
| 164 pass | 167 pass |
| 165 | 168 |
| 169 def PresubmitPromptOrNotify(self, *args, **kwargs): |
| 170 """Warn the user when uploading, but only notify if committing.""" |
| 171 if self.is_committing: |
| 172 return self.PresubmitNotifyResult(*args, **kwargs) |
| 173 return self.PresubmitPromptWarning(*args, **kwargs) |
| 174 |
| 166 class MailTextResult(PresubmitResult): | 175 class MailTextResult(PresubmitResult): |
| 167 """A warning that should be included in the review request email.""" | 176 """A warning that should be included in the review request email.""" |
| 168 def __init__(self, *args, **kwargs): | 177 def __init__(self, *args, **kwargs): |
| 169 super(OutputApi.MailTextResult, self).__init__() | 178 super(OutputApi.MailTextResult, self).__init__() |
| 170 raise NotImplementedError() | 179 raise NotImplementedError() |
| 171 | 180 |
| 172 | 181 |
| 173 class InputApi(object): | 182 class InputApi(object): |
| 174 """An instance of this object is passed to presubmit scripts so they can | 183 """An instance of this object is passed to presubmit scripts so they can |
| 175 know stuff about the change they're looking at. | 184 know stuff about the change they're looking at. |
| (...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1013 except Exception, e: | 1022 except Exception, e: |
| 1014 raise PresubmitFailure('"%s" had an exception.\n%s' % (presubmit_path, e)) | 1023 raise PresubmitFailure('"%s" had an exception.\n%s' % (presubmit_path, e)) |
| 1015 | 1024 |
| 1016 # These function names must change if we make substantial changes to | 1025 # These function names must change if we make substantial changes to |
| 1017 # the presubmit API that are not backwards compatible. | 1026 # the presubmit API that are not backwards compatible. |
| 1018 if self.committing: | 1027 if self.committing: |
| 1019 function_name = 'CheckChangeOnCommit' | 1028 function_name = 'CheckChangeOnCommit' |
| 1020 else: | 1029 else: |
| 1021 function_name = 'CheckChangeOnUpload' | 1030 function_name = 'CheckChangeOnUpload' |
| 1022 if function_name in context: | 1031 if function_name in context: |
| 1023 context['__args'] = (input_api, OutputApi()) | 1032 context['__args'] = (input_api, OutputApi(self.committing)) |
| 1024 logging.debug('Running %s in %s' % (function_name, presubmit_path)) | 1033 logging.debug('Running %s in %s' % (function_name, presubmit_path)) |
| 1025 result = eval(function_name + '(*__args)', context) | 1034 result = eval(function_name + '(*__args)', context) |
| 1026 logging.debug('Running %s done.' % function_name) | 1035 logging.debug('Running %s done.' % function_name) |
| 1027 if not (isinstance(result, types.TupleType) or | 1036 if not (isinstance(result, types.TupleType) or |
| 1028 isinstance(result, types.ListType)): | 1037 isinstance(result, types.ListType)): |
| 1029 raise PresubmitFailure( | 1038 raise PresubmitFailure( |
| 1030 'Presubmit functions must return a tuple or list') | 1039 'Presubmit functions must return a tuple or list') |
| 1031 for item in result: | 1040 for item in result: |
| 1032 if not isinstance(item, OutputApi.PresubmitResult): | 1041 if not isinstance(item, OutputApi.PresubmitResult): |
| 1033 raise PresubmitFailure( | 1042 raise PresubmitFailure( |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1290 except PresubmitFailure, e: | 1299 except PresubmitFailure, e: |
| 1291 print >> sys.stderr, e | 1300 print >> sys.stderr, e |
| 1292 print >> sys.stderr, 'Maybe your depot_tools is out of date?' | 1301 print >> sys.stderr, 'Maybe your depot_tools is out of date?' |
| 1293 print >> sys.stderr, 'If all fails, contact maruel@' | 1302 print >> sys.stderr, 'If all fails, contact maruel@' |
| 1294 return 2 | 1303 return 2 |
| 1295 | 1304 |
| 1296 | 1305 |
| 1297 if __name__ == '__main__': | 1306 if __name__ == '__main__': |
| 1298 fix_encoding.fix_encoding() | 1307 fix_encoding.fix_encoding() |
| 1299 sys.exit(Main(None)) | 1308 sys.exit(Main(None)) |
| OLD | NEW |