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.1' |
10 | 10 |
(...skipping 23 matching lines...) Expand all Loading... |
34 import gcl | 34 import gcl |
35 import gclient | 35 import gclient |
36 import presubmit_canned_checks | 36 import presubmit_canned_checks |
37 | 37 |
38 | 38 |
39 # Matches key/value (or "tag") lines in changelist descriptions. | 39 # Matches key/value (or "tag") lines in changelist descriptions. |
40 _tag_line_re = re.compile( | 40 _tag_line_re = re.compile( |
41 '^\s*(?P<key>[A-Z][A-Z_0-9]*)\s*=\s*(?P<value>.*?)\s*$') | 41 '^\s*(?P<key>[A-Z][A-Z_0-9]*)\s*=\s*(?P<value>.*?)\s*$') |
42 | 42 |
43 | 43 |
44 # Friendly names may be used for certain keys. All values for key-value pairs | |
45 # in change descriptions (like BUG=123) can be retrieved from a change object | |
46 # directly as if they were attributes, e.g. change.R (or equivalently because | |
47 # we have a friendly name for it, change.Reviewers), change.BUG (or | |
48 # change.BugIDs) and so forth. | |
49 # | |
50 # Add to this mapping as needed/desired. | |
51 SPECIAL_KEYS = { | |
52 'Reviewers' : 'R', | |
53 'BugIDs' : 'BUG', | |
54 'Tested': 'TESTED', | |
55 'Test': 'TEST' | |
56 } | |
57 | |
58 | |
59 class NotImplementedException(Exception): | 44 class NotImplementedException(Exception): |
60 """We're leaving placeholders in a bunch of places to remind us of the | 45 """We're leaving placeholders in a bunch of places to remind us of the |
61 design of the API, but we have not implemented all of it yet. Implement as | 46 design of the API, but we have not implemented all of it yet. Implement as |
62 the need arises. | 47 the need arises. |
63 """ | 48 """ |
64 pass | 49 pass |
65 | 50 |
66 | 51 |
67 def normpath(path): | 52 def normpath(path): |
68 '''Version of os.path.normpath that also changes backward slashes to | 53 '''Version of os.path.normpath that also changes backward slashes to |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 | 437 |
453 self.affected_files = [ | 438 self.affected_files = [ |
454 SvnAffectedFile(info[1], info[0].strip(), repository_root) | 439 SvnAffectedFile(info[1], info[0].strip(), repository_root) |
455 for info in change_info.files | 440 for info in change_info.files |
456 ] | 441 ] |
457 | 442 |
458 def Change(self): | 443 def Change(self): |
459 """Returns the change name.""" | 444 """Returns the change name.""" |
460 return self.name | 445 return self.name |
461 | 446 |
462 def Changelist(self): | |
463 """Synonym for Change().""" | |
464 return self.Change() | |
465 | |
466 def DescriptionText(self): | 447 def DescriptionText(self): |
467 """Returns the user-entered changelist description, minus tags. | 448 """Returns the user-entered changelist description, minus tags. |
468 | 449 |
469 Any line in the user-provided description starting with e.g. "FOO=" | 450 Any line in the user-provided description starting with e.g. "FOO=" |
470 (whitespace permitted before and around) is considered a tag line. Such | 451 (whitespace permitted before and around) is considered a tag line. Such |
471 lines are stripped out of the description this function returns. | 452 lines are stripped out of the description this function returns. |
472 """ | 453 """ |
473 return self.description_without_tags | 454 return self.description_without_tags |
474 | 455 |
475 def FullDescriptionText(self): | 456 def FullDescriptionText(self): |
476 """Returns the complete changelist description including tags.""" | 457 """Returns the complete changelist description including tags.""" |
477 return self.full_description | 458 return self.full_description |
478 | 459 |
479 def RepositoryRoot(self): | 460 def RepositoryRoot(self): |
480 """Returns the repository root for this change, as an absolute path.""" | 461 """Returns the repository root for this change, as an absolute path.""" |
481 return self.repository_root | 462 return self.repository_root |
482 | 463 |
483 def __getattr__(self, attr): | 464 def __getattr__(self, attr): |
484 """Return keys directly as attributes on the object. | 465 """Return keys directly as attributes on the object. |
485 | 466 |
486 You may use a friendly name (from SPECIAL_KEYS) or the actual name of | 467 You may use a friendly name (from SPECIAL_KEYS) or the actual name of |
487 the key. | 468 the key. |
488 """ | 469 """ |
489 if attr in SPECIAL_KEYS: | 470 return self.tags.get(attr) |
490 key = SPECIAL_KEYS[attr] | |
491 if key in self.tags: | |
492 return self.tags[key] | |
493 if attr in self.tags: | |
494 return self.tags[attr] | |
495 | 471 |
496 def AffectedFiles(self, include_dirs=False, include_deletes=True): | 472 def AffectedFiles(self, include_dirs=False, include_deletes=True): |
497 """Returns a list of AffectedFile instances for all files in the change. | 473 """Returns a list of AffectedFile instances for all files in the change. |
498 | 474 |
499 Args: | 475 Args: |
500 include_deletes: If false, deleted files will be filtered out. | 476 include_deletes: If false, deleted files will be filtered out. |
501 include_dirs: True to include directories in the list | 477 include_dirs: True to include directories in the list |
502 | 478 |
503 Returns: | 479 Returns: |
504 [AffectedFile(path, action), AffectedFile(path, action)] | 480 [AffectedFile(path, action), AffectedFile(path, action)] |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 return not DoPresubmitChecks(gcl.ChangeInfo(name='temp', files=files), | 720 return not DoPresubmitChecks(gcl.ChangeInfo(name='temp', files=files), |
745 options.commit, | 721 options.commit, |
746 options.verbose, | 722 options.verbose, |
747 sys.stdout, | 723 sys.stdout, |
748 sys.stdin, | 724 sys.stdin, |
749 default_presubmit=None) | 725 default_presubmit=None) |
750 | 726 |
751 | 727 |
752 if __name__ == '__main__': | 728 if __name__ == '__main__': |
753 sys.exit(Main(sys.argv)) | 729 sys.exit(Main(sys.argv)) |
OLD | NEW |