| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 | 295 |
| 296 Args: | 296 Args: |
| 297 Depot path as a string. | 297 Depot path as a string. |
| 298 | 298 |
| 299 Returns: | 299 Returns: |
| 300 The local path of the depot path under the user's current client, or None | 300 The local path of the depot path under the user's current client, or None |
| 301 if the file is not mapped. | 301 if the file is not mapped. |
| 302 | 302 |
| 303 Remember to check for the None case and show an appropriate error! | 303 Remember to check for the None case and show an appropriate error! |
| 304 """ | 304 """ |
| 305 local_path = scm.SVN.CaptureInfo(depot_path).get('Path') | 305 return scm.SVN.CaptureLocalInfo([depot_path], self.change.RepositoryRoot() |
| 306 if local_path: | 306 ).get('Path') |
| 307 return local_path | |
| 308 | 307 |
| 309 def LocalToDepotPath(self, local_path): | 308 def LocalToDepotPath(self, local_path): |
| 310 """Translate a local path to a depot path. | 309 """Translate a local path to a depot path. |
| 311 | 310 |
| 312 Args: | 311 Args: |
| 313 Local path (relative to current directory, or absolute) as a string. | 312 Local path (relative to current directory, or absolute) as a string. |
| 314 | 313 |
| 315 Returns: | 314 Returns: |
| 316 The depot path (SVN URL) of the file if mapped, otherwise None. | 315 The depot path (SVN URL) of the file if mapped, otherwise None. |
| 317 """ | 316 """ |
| 318 depot_path = scm.SVN.CaptureInfo(local_path).get('URL') | 317 return scm.SVN.CaptureLocalInfo([local_path], self.change.RepositoryRoot() |
| 319 if depot_path: | 318 ).get('URL') |
| 320 return depot_path | |
| 321 | 319 |
| 322 def AffectedFiles(self, include_dirs=False, include_deletes=True, | 320 def AffectedFiles(self, include_dirs=False, include_deletes=True, |
| 323 file_filter=None): | 321 file_filter=None): |
| 324 """Same as input_api.change.AffectedFiles() except only lists files | 322 """Same as input_api.change.AffectedFiles() except only lists files |
| 325 (and optionally directories) in the same directory as the current presubmit | 323 (and optionally directories) in the same directory as the current presubmit |
| 326 script, or subdirectories thereof. | 324 script, or subdirectories thereof. |
| 327 """ | 325 """ |
| 328 dir_with_slash = normpath("%s/" % self.PresubmitLocalPath()) | 326 dir_with_slash = normpath("%s/" % self.PresubmitLocalPath()) |
| 329 if len(dir_with_slash) == 1: | 327 if len(dir_with_slash) == 1: |
| 330 dir_with_slash = '' | 328 dir_with_slash = '' |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 @property | 420 @property |
| 423 def tbr(self): | 421 def tbr(self): |
| 424 """Returns if a change is TBR'ed.""" | 422 """Returns if a change is TBR'ed.""" |
| 425 return 'TBR' in self.change.tags | 423 return 'TBR' in self.change.tags |
| 426 | 424 |
| 427 | 425 |
| 428 class AffectedFile(object): | 426 class AffectedFile(object): |
| 429 """Representation of a file in a change.""" | 427 """Representation of a file in a change.""" |
| 430 # Method could be a function | 428 # Method could be a function |
| 431 # pylint: disable=R0201 | 429 # pylint: disable=R0201 |
| 432 def __init__(self, path, action, repository_root=''): | 430 def __init__(self, path, action, repository_root): |
| 433 self._path = path | 431 self._path = path |
| 434 self._action = action | 432 self._action = action |
| 435 self._local_root = repository_root | 433 self._local_root = repository_root |
| 436 self._is_directory = None | 434 self._is_directory = None |
| 437 self._properties = {} | 435 self._properties = {} |
| 438 self._cached_changed_contents = None | 436 self._cached_changed_contents = None |
| 439 self._cached_new_contents = None | 437 self._cached_new_contents = None |
| 440 logging.debug('%s(%s)' % (self.__class__.__name__, self._path)) | 438 logging.debug('%s(%s)' % (self.__class__.__name__, self._path)) |
| 441 | 439 |
| 442 def ServerPath(self): | 440 def ServerPath(self): |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 # Method 'NNN' is abstract in class 'NNN' but is not overridden | 554 # Method 'NNN' is abstract in class 'NNN' but is not overridden |
| 557 # pylint: disable=W0223 | 555 # pylint: disable=W0223 |
| 558 | 556 |
| 559 def __init__(self, *args, **kwargs): | 557 def __init__(self, *args, **kwargs): |
| 560 AffectedFile.__init__(self, *args, **kwargs) | 558 AffectedFile.__init__(self, *args, **kwargs) |
| 561 self._server_path = None | 559 self._server_path = None |
| 562 self._is_text_file = None | 560 self._is_text_file = None |
| 563 | 561 |
| 564 def ServerPath(self): | 562 def ServerPath(self): |
| 565 if self._server_path is None: | 563 if self._server_path is None: |
| 566 self._server_path = scm.SVN.CaptureInfo( | 564 self._server_path = scm.SVN.CaptureLocalInfo( |
| 567 self.AbsoluteLocalPath()).get('URL', '') | 565 [self.LocalPath()], self._local_root).get('URL', '') |
| 568 return self._server_path | 566 return self._server_path |
| 569 | 567 |
| 570 def IsDirectory(self): | 568 def IsDirectory(self): |
| 571 if self._is_directory is None: | 569 if self._is_directory is None: |
| 572 path = self.AbsoluteLocalPath() | 570 path = self.AbsoluteLocalPath() |
| 573 if os.path.exists(path): | 571 if os.path.exists(path): |
| 574 # Retrieve directly from the file system; it is much faster than | 572 # Retrieve directly from the file system; it is much faster than |
| 575 # querying subversion, especially on Windows. | 573 # querying subversion, especially on Windows. |
| 576 self._is_directory = os.path.isdir(path) | 574 self._is_directory = os.path.isdir(path) |
| 577 else: | 575 else: |
| 578 self._is_directory = scm.SVN.CaptureInfo( | 576 self._is_directory = scm.SVN.CaptureLocalInfo( |
| 579 path).get('Node Kind') in ('dir', 'directory') | 577 [self.LocalPath()], self._local_root |
| 578 ).get('Node Kind') in ('dir', 'directory') |
| 580 return self._is_directory | 579 return self._is_directory |
| 581 | 580 |
| 582 def Property(self, property_name): | 581 def Property(self, property_name): |
| 583 if not property_name in self._properties: | 582 if not property_name in self._properties: |
| 584 self._properties[property_name] = scm.SVN.GetFileProperty( | 583 self._properties[property_name] = scm.SVN.GetFileProperty( |
| 585 self.AbsoluteLocalPath(), property_name).rstrip() | 584 self.LocalPath(), property_name, self._local_root).rstrip() |
| 586 return self._properties[property_name] | 585 return self._properties[property_name] |
| 587 | 586 |
| 588 def IsTextFile(self): | 587 def IsTextFile(self): |
| 589 if self._is_text_file is None: | 588 if self._is_text_file is None: |
| 590 if self.Action() == 'D': | 589 if self.Action() == 'D': |
| 591 # A deleted file is not a text file. | 590 # A deleted file is not a text file. |
| 592 self._is_text_file = False | 591 self._is_text_file = False |
| 593 elif self.IsDirectory(): | 592 elif self.IsDirectory(): |
| 594 self._is_text_file = False | 593 self._is_text_file = False |
| 595 else: | 594 else: |
| 596 mime_type = scm.SVN.GetFileProperty(self.AbsoluteLocalPath(), | 595 mime_type = scm.SVN.GetFileProperty( |
| 597 'svn:mime-type') | 596 self.LocalPath(), 'svn:mime-type', self._local_root) |
| 598 self._is_text_file = (not mime_type or mime_type.startswith('text/')) | 597 self._is_text_file = (not mime_type or mime_type.startswith('text/')) |
| 599 return self._is_text_file | 598 return self._is_text_file |
| 600 | 599 |
| 601 def GenerateScmDiff(self): | 600 def GenerateScmDiff(self): |
| 602 return scm.SVN.GenerateDiff([self.AbsoluteLocalPath()]) | 601 return scm.SVN.GenerateDiff( |
| 602 [self.LocalPath()], self._local_root, False, None) |
| 603 | 603 |
| 604 | 604 |
| 605 class GitAffectedFile(AffectedFile): | 605 class GitAffectedFile(AffectedFile): |
| 606 """Representation of a file in a change out of a git checkout.""" | 606 """Representation of a file in a change out of a git checkout.""" |
| 607 # Method 'NNN' is abstract in class 'NNN' but is not overridden | 607 # Method 'NNN' is abstract in class 'NNN' but is not overridden |
| 608 # pylint: disable=W0223 | 608 # pylint: disable=W0223 |
| 609 | 609 |
| 610 def __init__(self, *args, **kwargs): | 610 def __init__(self, *args, **kwargs): |
| 611 AffectedFile.__init__(self, *args, **kwargs) | 611 AffectedFile.__init__(self, *args, **kwargs) |
| 612 self._server_path = None | 612 self._server_path = None |
| (...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1258 except PresubmitFailure, e: | 1258 except PresubmitFailure, e: |
| 1259 print >> sys.stderr, e | 1259 print >> sys.stderr, e |
| 1260 print >> sys.stderr, 'Maybe your depot_tools is out of date?' | 1260 print >> sys.stderr, 'Maybe your depot_tools is out of date?' |
| 1261 print >> sys.stderr, 'If all fails, contact maruel@' | 1261 print >> sys.stderr, 'If all fails, contact maruel@' |
| 1262 return 2 | 1262 return 2 |
| 1263 | 1263 |
| 1264 | 1264 |
| 1265 if __name__ == '__main__': | 1265 if __name__ == '__main__': |
| 1266 fix_encoding.fix_encoding() | 1266 fix_encoding.fix_encoding() |
| 1267 sys.exit(Main(None)) | 1267 sys.exit(Main(None)) |
| OLD | NEW |