Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(850)

Side by Side Diff: presubmit_support.py

Issue 6719004: refactor parsing of change descriptions, fix TBR= (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: rebase to head, fix bugs Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « git_cl/git_cl.py ('k') | tests/gcl_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2010 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.4' 9 __version__ = '1.4'
10 10
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after
807 807
808 808
809 class GitChange(Change): 809 class GitChange(Change):
810 _AFFECTED_FILES = GitAffectedFile 810 _AFFECTED_FILES = GitAffectedFile
811 811
812 def __init__(self, *args, **kwargs): 812 def __init__(self, *args, **kwargs):
813 Change.__init__(self, *args, **kwargs) 813 Change.__init__(self, *args, **kwargs)
814 self.scm = 'git' 814 self.scm = 'git'
815 815
816 816
817 class ChangeDescription(object):
818 """Contains a parsed form of the change description."""
819 MAX_SUBJECT_LENGTH = 100
820
821 def __init__(self, subject=None, description=None, reviewers=None, tbr=False,
822 editor=None):
823 self.subject = (subject or '').strip()
824 self.description = (description or '').strip()
825 self.reviewers = reviewers or []
826 self.tbr = tbr
827 self.editor = editor or gclient_utils.UserEdit
828
829 if self.description:
830 if not self.description.startswith(self.subject):
831 self.description = self.subject + '\n\n' + self.description
832 elif self.subject:
833 self.description = self.subject
834 self.Parse(self.EditableDescription())
835
836 def EditableDescription(self):
837 text = self.description.strip()
838 if text:
839 text += '\n'
840
841 tbr_present = False
842 r_present = False
843 bug_present = False
844 test_present = False
845 for l in text.splitlines():
846 l = l.strip()
847 r_present = r_present or l.startswith('R=')
848 tbr_present = tbr_present or l.startswith('TBR=')
849
850 if text and not (r_present or tbr_present):
851 text += '\n'
852
853 if not tbr_present and not r_present:
854 if self.tbr:
855 text += 'TBR=' + ','.join(self.reviewers) + '\n'
856 else:
857 text += 'R=' + ','.join(self.reviewers) + '\n'
858 if not bug_present:
859 text += 'BUG=\n'
860 if not test_present:
861 text += 'TEST=\n'
862
863 return text
864
865 def UserEdit(self):
866 """Allows the user to update the description.
867
868 Uses the editor callback passed to the constructor."""
869 self.Parse(self.editor(self.EditableDescription()))
870
871 def Parse(self, text):
872 """Parse the text returned from UserEdit() and update our state."""
873 parsed_lines = []
874 reviewers_regexp = re.compile('\s*(TBR|R)=(.+)')
875 reviewers = []
876 subject = ''
877 tbr = False
878 for l in text.splitlines():
879 l = l.strip()
880
881 # Throw away empty BUG=, TEST=, and R= lines. We leave in TBR= lines
882 # to indicate that this change was meant to be "unreviewed".
883 if l in ('BUG=', 'TEST=', 'R='):
884 continue
885
886 if not subject:
887 subject = l
888 matched_reviewers = reviewers_regexp.match(l)
889 if matched_reviewers:
890 tbr = (matched_reviewers.group(1) == 'TBR')
891 reviewers.extend(matched_reviewers.group(2).split(','))
892 parsed_lines.append(l)
893
894 if len(subject) > self.MAX_SUBJECT_LENGTH:
895 subject = subject[:self.MAX_SUBJECT_LENGTH - 3] + '...'
896
897 self.description = '\n'.join(parsed_lines).strip()
898 self.subject = subject
899 self.reviewers = reviewers
900 self.tbr = tbr
901
902 def IsEmpty(self):
903 return not self.description
904
905
906
817 def ListRelevantPresubmitFiles(files, root): 907 def ListRelevantPresubmitFiles(files, root):
818 """Finds all presubmit files that apply to a given set of source files. 908 """Finds all presubmit files that apply to a given set of source files.
819 909
820 If inherit-review-settings-ok is present right under root, looks for 910 If inherit-review-settings-ok is present right under root, looks for
821 PRESUBMIT.py in directories enclosing root. 911 PRESUBMIT.py in directories enclosing root.
822 912
823 Args: 913 Args:
824 files: An iterable container containing file paths. 914 files: An iterable container containing file paths.
825 root: Path where to stop searching. 915 root: Path where to stop searching.
826 916
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 sys.stdout, 1279 sys.stdout,
1190 sys.stdin, 1280 sys.stdin,
1191 options.default_presubmit, 1281 options.default_presubmit,
1192 options.may_prompt) 1282 options.may_prompt)
1193 return not results.should_continue() 1283 return not results.should_continue()
1194 1284
1195 1285
1196 if __name__ == '__main__': 1286 if __name__ == '__main__':
1197 fix_encoding.fix_encoding() 1287 fix_encoding.fix_encoding()
1198 sys.exit(Main(None)) 1288 sys.exit(Main(None))
OLDNEW
« no previous file with comments | « git_cl/git_cl.py ('k') | tests/gcl_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698