OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2006-2009 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.1' | 9 __version__ = '1.2' |
10 | 10 |
11 # TODO(joi) Add caching where appropriate/needed. The API is designed to allow | 11 # TODO(joi) Add caching where appropriate/needed. The API is designed to allow |
12 # caching (between all different invocations of presubmit scripts for a given | 12 # caching (between all different invocations of presubmit scripts for a given |
13 # change). We should add it as our presubmit scripts start feeling slow. | 13 # change). We should add it as our presubmit scripts start feeling slow. |
14 | 14 |
15 import cPickle # Exposed through the API. | 15 import cPickle # Exposed through the API. |
16 import cStringIO # Exposed through the API. | 16 import cStringIO # Exposed through the API. |
17 import exceptions | 17 import exceptions |
18 import fnmatch | 18 import fnmatch |
19 import glob | 19 import glob |
20 import marshal # Exposed through the API. | 20 import marshal # Exposed through the API. |
21 import optparse | 21 import optparse |
22 import os # Somewhat exposed through the API. | 22 import os # Somewhat exposed through the API. |
23 import pickle # Exposed through the API. | 23 import pickle # Exposed through the API. |
24 import re # Exposed through the API. | 24 import re # Exposed through the API. |
25 import subprocess # Exposed through the API. | 25 import subprocess # Exposed through the API. |
26 import sys # Parts exposed through API. | 26 import sys # Parts exposed through API. |
27 import tempfile # Exposed through the API. | 27 import tempfile # Exposed through the API. |
28 import types | 28 import types |
| 29 import unittest # Exposed through the API. |
29 import urllib2 # Exposed through the API. | 30 import urllib2 # Exposed through the API. |
30 import warnings | 31 import warnings |
31 | 32 |
32 # Local imports. | 33 # Local imports. |
33 # TODO(joi) Would be cleaner to factor out utils in gcl to separate module, but | 34 # TODO(joi) Would be cleaner to factor out utils in gcl to separate module, but |
34 # for now it would only be a couple of functions so hardly worth it. | 35 # for now it would only be a couple of functions so hardly worth it. |
35 import gcl | 36 import gcl |
36 import gclient | 37 import gclient |
37 import presubmit_canned_checks | 38 import presubmit_canned_checks |
38 | 39 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 # so that presubmit scripts don't have to import them. | 166 # so that presubmit scripts don't have to import them. |
166 self.basename = os.path.basename | 167 self.basename = os.path.basename |
167 self.cPickle = cPickle | 168 self.cPickle = cPickle |
168 self.cStringIO = cStringIO | 169 self.cStringIO = cStringIO |
169 self.os_path = os.path | 170 self.os_path = os.path |
170 self.pickle = pickle | 171 self.pickle = pickle |
171 self.marshal = marshal | 172 self.marshal = marshal |
172 self.re = re | 173 self.re = re |
173 self.subprocess = subprocess | 174 self.subprocess = subprocess |
174 self.tempfile = tempfile | 175 self.tempfile = tempfile |
| 176 self.unittest = unittest |
175 self.urllib2 = urllib2 | 177 self.urllib2 = urllib2 |
176 | 178 |
177 # InputApi.platform is the platform you're currently running on. | 179 # InputApi.platform is the platform you're currently running on. |
178 self.platform = sys.platform | 180 self.platform = sys.platform |
179 | 181 |
180 # The local path of the currently-being-processed presubmit script. | 182 # The local path of the currently-being-processed presubmit script. |
181 self._current_presubmit_path = os.path.dirname(presubmit_path) | 183 self._current_presubmit_path = os.path.dirname(presubmit_path) |
182 | 184 |
183 # We carry the canned checks so presubmit scripts can easily use them. | 185 # We carry the canned checks so presubmit scripts can easily use them. |
184 self.canned_checks = presubmit_canned_checks | 186 self.canned_checks = presubmit_canned_checks |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 contained by the directory of the currently executing presubmit script. | 268 contained by the directory of the currently executing presubmit script. |
267 | 269 |
268 This is useful for doing line-by-line regex checks, like checking for | 270 This is useful for doing line-by-line regex checks, like checking for |
269 trailing whitespace. | 271 trailing whitespace. |
270 | 272 |
271 Yields: | 273 Yields: |
272 a 3 tuple: | 274 a 3 tuple: |
273 the AffectedFile instance of the current file; | 275 the AffectedFile instance of the current file; |
274 integer line number (1-based); and | 276 integer line number (1-based); and |
275 the contents of the line as a string. | 277 the contents of the line as a string. |
| 278 |
| 279 Note: The cariage return (LF or CR) is stripped off. |
276 """ | 280 """ |
277 return InputApi._RightHandSideLinesImpl( | 281 return InputApi._RightHandSideLinesImpl( |
278 filter(lambda x: x.IsTextFile(), | 282 filter(lambda x: x.IsTextFile(), |
279 self.AffectedFiles(include_deletes=False))) | 283 self.AffectedFiles(include_deletes=False))) |
280 | 284 |
281 @staticmethod | 285 @staticmethod |
282 def _RightHandSideLinesImpl(affected_files): | 286 def _RightHandSideLinesImpl(affected_files): |
283 """Implements RightHandSideLines for InputApi and GclChange.""" | 287 """Implements RightHandSideLines for InputApi and GclChange.""" |
284 for af in affected_files: | 288 for af in affected_files: |
285 lines = af.NewContents() | 289 lines = af.NewContents() |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 Deleted files are not text file.""" | 346 Deleted files are not text file.""" |
343 raise NotImplementedError() # Implement when needed | 347 raise NotImplementedError() # Implement when needed |
344 | 348 |
345 def NewContents(self): | 349 def NewContents(self): |
346 """Returns an iterator over the lines in the new version of file. | 350 """Returns an iterator over the lines in the new version of file. |
347 | 351 |
348 The new version is the file in the user's workspace, i.e. the "right hand | 352 The new version is the file in the user's workspace, i.e. the "right hand |
349 side". | 353 side". |
350 | 354 |
351 Contents will be empty if the file is a directory or does not exist. | 355 Contents will be empty if the file is a directory or does not exist. |
| 356 Note: The cariage returns (LF or CR) are stripped off. |
352 """ | 357 """ |
353 if self.IsDirectory(): | 358 if self.IsDirectory(): |
354 return [] | 359 return [] |
355 else: | 360 else: |
356 return gcl.ReadFile(self.AbsoluteLocalPath()).splitlines() | 361 return gcl.ReadFile(self.AbsoluteLocalPath()).splitlines() |
357 | 362 |
358 def OldContents(self): | 363 def OldContents(self): |
359 """Returns an iterator over the lines in the old version of file. | 364 """Returns an iterator over the lines in the old version of file. |
360 | 365 |
361 The old version is the file in depot, i.e. the "left hand side". | 366 The old version is the file in depot, i.e. the "left hand side". |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 return not DoPresubmitChecks(gcl.ChangeInfo(name='temp', files=files), | 743 return not DoPresubmitChecks(gcl.ChangeInfo(name='temp', files=files), |
739 options.commit, | 744 options.commit, |
740 options.verbose, | 745 options.verbose, |
741 sys.stdout, | 746 sys.stdout, |
742 sys.stdin, | 747 sys.stdin, |
743 default_presubmit=None) | 748 default_presubmit=None) |
744 | 749 |
745 | 750 |
746 if __name__ == '__main__': | 751 if __name__ == '__main__': |
747 sys.exit(Main(sys.argv)) | 752 sys.exit(Main(sys.argv)) |
OLD | NEW |