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 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 self._is_text_file = False | 619 self._is_text_file = False |
620 elif self.IsDirectory(): | 620 elif self.IsDirectory(): |
621 self._is_text_file = False | 621 self._is_text_file = False |
622 else: | 622 else: |
623 self._is_text_file = os.path.isfile(self.AbsoluteLocalPath()) | 623 self._is_text_file = os.path.isfile(self.AbsoluteLocalPath()) |
624 return self._is_text_file | 624 return self._is_text_file |
625 | 625 |
626 def GenerateScmDiff(self): | 626 def GenerateScmDiff(self): |
627 return scm.GIT.GenerateDiff(self._local_root, files=[self.LocalPath(),]) | 627 return scm.GIT.GenerateDiff(self._local_root, files=[self.LocalPath(),]) |
628 | 628 |
| 629 |
629 class Change(object): | 630 class Change(object): |
630 """Describe a change. | 631 """Describe a change. |
631 | 632 |
632 Used directly by the presubmit scripts to query the current change being | 633 Used directly by the presubmit scripts to query the current change being |
633 tested. | 634 tested. |
634 | 635 |
635 Instance members: | 636 Instance members: |
636 tags: Dictionnary of KEY=VALUE pairs found in the change description. | 637 tags: Dictionnary of KEY=VALUE pairs found in the change description. |
637 self.KEY: equivalent to tags['KEY'] | 638 self.KEY: equivalent to tags['KEY'] |
638 """ | 639 """ |
639 | 640 |
640 _AFFECTED_FILES = AffectedFile | 641 _AFFECTED_FILES = AffectedFile |
641 | 642 |
642 # Matches key/value (or "tag") lines in changelist descriptions. | 643 # Matches key/value (or "tag") lines in changelist descriptions. |
643 _TAG_LINE_RE = re.compile( | 644 _TAG_LINE_RE = re.compile( |
644 '^\s*(?P<key>[A-Z][A-Z_0-9]*)\s*=\s*(?P<value>.*?)\s*$') | 645 '^\s*(?P<key>[A-Z][A-Z_0-9]*)\s*=\s*(?P<value>.*?)\s*$') |
| 646 scm = '' |
645 | 647 |
646 def __init__(self, name, description, local_root, files, issue, patchset): | 648 def __init__(self, name, description, local_root, files, issue, patchset): |
647 if files is None: | 649 if files is None: |
648 files = [] | 650 files = [] |
649 self._name = name | 651 self._name = name |
650 self._full_description = description | 652 self._full_description = description |
651 # Convert root into an absolute path. | 653 # Convert root into an absolute path. |
652 self._local_root = os.path.abspath(local_root) | 654 self._local_root = os.path.abspath(local_root) |
653 self.issue = issue | 655 self.issue = issue |
654 self.patchset = patchset | 656 self.patchset = patchset |
655 self.scm = '' | |
656 | 657 |
657 # From the description text, build up a dictionary of key/value pairs | 658 # From the description text, build up a dictionary of key/value pairs |
658 # plus the description minus all key/value or "tag" lines. | 659 # plus the description minus all key/value or "tag" lines. |
659 description_without_tags = [] | 660 description_without_tags = [] |
660 self.tags = {} | 661 self.tags = {} |
661 for line in self._full_description.splitlines(): | 662 for line in self._full_description.splitlines(): |
662 m = self._TAG_LINE_RE.match(line) | 663 m = self._TAG_LINE_RE.match(line) |
663 if m: | 664 if m: |
664 self.tags[m.group('key')] = m.group('value') | 665 self.tags[m.group('key')] = m.group('value') |
665 else: | 666 else: |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 integer line number (1-based); and | 760 integer line number (1-based); and |
760 the contents of the line as a string. | 761 the contents of the line as a string. |
761 """ | 762 """ |
762 return _RightHandSideLinesImpl( | 763 return _RightHandSideLinesImpl( |
763 x for x in self.AffectedFiles(include_deletes=False) | 764 x for x in self.AffectedFiles(include_deletes=False) |
764 if x.IsTextFile()) | 765 if x.IsTextFile()) |
765 | 766 |
766 | 767 |
767 class SvnChange(Change): | 768 class SvnChange(Change): |
768 _AFFECTED_FILES = SvnAffectedFile | 769 _AFFECTED_FILES = SvnAffectedFile |
769 | 770 scm = 'svn' |
770 def __init__(self, *args, **kwargs): | 771 _changelists = None |
771 Change.__init__(self, *args, **kwargs) | |
772 self.scm = 'svn' | |
773 self._changelists = None | |
774 | 772 |
775 def _GetChangeLists(self): | 773 def _GetChangeLists(self): |
776 """Get all change lists.""" | 774 """Get all change lists.""" |
777 if self._changelists == None: | 775 if self._changelists == None: |
778 previous_cwd = os.getcwd() | 776 previous_cwd = os.getcwd() |
779 os.chdir(self.RepositoryRoot()) | 777 os.chdir(self.RepositoryRoot()) |
780 # Need to import here to avoid circular dependency. | 778 # Need to import here to avoid circular dependency. |
781 import gcl | 779 import gcl |
782 self._changelists = gcl.GetModifiedFiles() | 780 self._changelists = gcl.GetModifiedFiles() |
783 os.chdir(previous_cwd) | 781 os.chdir(previous_cwd) |
(...skipping 10 matching lines...) Expand all Loading... |
794 | 792 |
795 def GetModifiedFiles(self): | 793 def GetModifiedFiles(self): |
796 """Get modified files in the current CL.""" | 794 """Get modified files in the current CL.""" |
797 changelists = self._GetChangeLists() | 795 changelists = self._GetChangeLists() |
798 return [os.path.join(self.RepositoryRoot(), f[1]) | 796 return [os.path.join(self.RepositoryRoot(), f[1]) |
799 for f in changelists[self.Name()]] | 797 for f in changelists[self.Name()]] |
800 | 798 |
801 | 799 |
802 class GitChange(Change): | 800 class GitChange(Change): |
803 _AFFECTED_FILES = GitAffectedFile | 801 _AFFECTED_FILES = GitAffectedFile |
804 | 802 scm = 'git' |
805 def __init__(self, *args, **kwargs): | |
806 Change.__init__(self, *args, **kwargs) | |
807 self.scm = 'git' | |
808 | 803 |
809 | 804 |
810 def ListRelevantPresubmitFiles(files, root): | 805 def ListRelevantPresubmitFiles(files, root): |
811 """Finds all presubmit files that apply to a given set of source files. | 806 """Finds all presubmit files that apply to a given set of source files. |
812 | 807 |
813 If inherit-review-settings-ok is present right under root, looks for | 808 If inherit-review-settings-ok is present right under root, looks for |
814 PRESUBMIT.py in directories enclosing root. | 809 PRESUBMIT.py in directories enclosing root. |
815 | 810 |
816 Args: | 811 Args: |
817 files: An iterable container containing file paths. | 812 files: An iterable container containing file paths. |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1205 except PresubmitFailure, e: | 1200 except PresubmitFailure, e: |
1206 print >> sys.stderr, e | 1201 print >> sys.stderr, e |
1207 print >> sys.stderr, 'Maybe your depot_tools is out of date?' | 1202 print >> sys.stderr, 'Maybe your depot_tools is out of date?' |
1208 print >> sys.stderr, 'If all fails, contact maruel@' | 1203 print >> sys.stderr, 'If all fails, contact maruel@' |
1209 return 2 | 1204 return 2 |
1210 | 1205 |
1211 | 1206 |
1212 if __name__ == '__main__': | 1207 if __name__ == '__main__': |
1213 fix_encoding.fix_encoding() | 1208 fix_encoding.fix_encoding() |
1214 sys.exit(Main(None)) | 1209 sys.exit(Main(None)) |
OLD | NEW |