OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 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 # Copyright (C) 2008 Evan Martin <martine@danga.com> | 6 # Copyright (C) 2008 Evan Martin <martine@danga.com> |
7 | 7 |
8 """A git-command for integrating reviews on Rietveld and Gerrit.""" | 8 """A git-command for integrating reviews on Rietveld and Gerrit.""" |
9 | 9 |
10 from __future__ import print_function | 10 from __future__ import print_function |
(...skipping 2107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2118 # rietveld.cc only addresses which we can send private CLs to are listed | 2118 # rietveld.cc only addresses which we can send private CLs to are listed |
2119 # if rietveld.private is set, and so we should ignore rietveld.cc only | 2119 # if rietveld.private is set, and so we should ignore rietveld.cc only |
2120 # when --private is specified explicitly on the command line. | 2120 # when --private is specified explicitly on the command line. |
2121 if options.private: | 2121 if options.private: |
2122 logging.warn('rietveld.cc is ignored since private flag is specified. ' | 2122 logging.warn('rietveld.cc is ignored since private flag is specified. ' |
2123 'You need to review and add them manually if necessary.') | 2123 'You need to review and add them manually if necessary.') |
2124 cc = self.GetCCListWithoutDefault() | 2124 cc = self.GetCCListWithoutDefault() |
2125 else: | 2125 else: |
2126 cc = self.GetCCList() | 2126 cc = self.GetCCList() |
2127 cc = ','.join(filter(None, (cc, ','.join(options.cc)))) | 2127 cc = ','.join(filter(None, (cc, ','.join(options.cc)))) |
| 2128 if change_desc.get_cced(): |
| 2129 cc = ','.join(filter(None, (cc, ','.join(change_desc.get_cced())))) |
2128 if cc: | 2130 if cc: |
2129 upload_args.extend(['--cc', cc]) | 2131 upload_args.extend(['--cc', cc]) |
2130 | 2132 |
2131 if options.private or settings.GetDefaultPrivateFlag() == "True": | 2133 if options.private or settings.GetDefaultPrivateFlag() == "True": |
2132 upload_args.append('--private') | 2134 upload_args.append('--private') |
2133 | 2135 |
2134 upload_args.extend(['--git_similarity', str(options.similarity)]) | 2136 upload_args.extend(['--git_similarity', str(options.similarity)]) |
2135 if not options.find_copies: | 2137 if not options.find_copies: |
2136 upload_args.extend(['--git_no_find_copies']) | 2138 upload_args.extend(['--git_no_find_copies']) |
2137 | 2139 |
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2765 ('Created|Updated %d issues on Gerrit, but only 1 expected.\n' | 2767 ('Created|Updated %d issues on Gerrit, but only 1 expected.\n' |
2766 'Change-Id: %s') % (len(change_numbers), change_id)) | 2768 'Change-Id: %s') % (len(change_numbers), change_id)) |
2767 self.SetIssue(change_numbers[0]) | 2769 self.SetIssue(change_numbers[0]) |
2768 self._GitSetBranchConfigValue('gerritsquashhash', ref_to_push) | 2770 self._GitSetBranchConfigValue('gerritsquashhash', ref_to_push) |
2769 | 2771 |
2770 # Add cc's from the CC_LIST and --cc flag (if any). | 2772 # Add cc's from the CC_LIST and --cc flag (if any). |
2771 cc = self.GetCCList().split(',') | 2773 cc = self.GetCCList().split(',') |
2772 if options.cc: | 2774 if options.cc: |
2773 cc.extend(options.cc) | 2775 cc.extend(options.cc) |
2774 cc = filter(None, [email.strip() for email in cc]) | 2776 cc = filter(None, [email.strip() for email in cc]) |
| 2777 if change_desc.get_cced(): |
| 2778 cc.extend(change_desc.get_cced()) |
2775 if cc: | 2779 if cc: |
2776 gerrit_util.AddReviewers( | 2780 gerrit_util.AddReviewers( |
2777 self._GetGerritHost(), self.GetIssue(), cc, is_reviewer=False) | 2781 self._GetGerritHost(), self.GetIssue(), cc, is_reviewer=False) |
2778 | 2782 |
2779 return 0 | 2783 return 0 |
2780 | 2784 |
2781 def _AddChangeIdToCommitMessage(self, options, args): | 2785 def _AddChangeIdToCommitMessage(self, options, args): |
2782 """Re-commits using the current message, assumes the commit hook is in | 2786 """Re-commits using the current message, assumes the commit hook is in |
2783 place. | 2787 place. |
2784 """ | 2788 """ |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2891 else: | 2895 else: |
2892 yield default_bugs | 2896 yield default_bugs |
2893 for other in sorted(others): | 2897 for other in sorted(others): |
2894 # Don't bother finding common prefixes, CLs with >2 bugs are very very rare. | 2898 # Don't bother finding common prefixes, CLs with >2 bugs are very very rare. |
2895 yield other | 2899 yield other |
2896 | 2900 |
2897 | 2901 |
2898 class ChangeDescription(object): | 2902 class ChangeDescription(object): |
2899 """Contains a parsed form of the change description.""" | 2903 """Contains a parsed form of the change description.""" |
2900 R_LINE = r'^[ \t]*(TBR|R)[ \t]*=[ \t]*(.*?)[ \t]*$' | 2904 R_LINE = r'^[ \t]*(TBR|R)[ \t]*=[ \t]*(.*?)[ \t]*$' |
| 2905 CC_LINE = r'^[ \t]*(CC)[ \t]*=[ \t]*(.*?)[ \t]*$' |
2901 BUG_LINE = r'^[ \t]*(BUG)[ \t]*=[ \t]*(.*?)[ \t]*$' | 2906 BUG_LINE = r'^[ \t]*(BUG)[ \t]*=[ \t]*(.*?)[ \t]*$' |
2902 | 2907 |
2903 def __init__(self, description): | 2908 def __init__(self, description): |
2904 self._description_lines = (description or '').strip().splitlines() | 2909 self._description_lines = (description or '').strip().splitlines() |
2905 | 2910 |
2906 @property # www.logilab.org/ticket/89786 | 2911 @property # www.logilab.org/ticket/89786 |
2907 def description(self): # pylint: disable=E0202 | 2912 def description(self): # pylint: disable=E0202 |
2908 return '\n'.join(self._description_lines) | 2913 return '\n'.join(self._description_lines) |
2909 | 2914 |
2910 def set_description(self, desc): | 2915 def set_description(self, desc): |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3038 self._description_lines = top_lines + separator + gerrit_footers | 3043 self._description_lines = top_lines + separator + gerrit_footers |
3039 | 3044 |
3040 def get_reviewers(self, tbr_only=False): | 3045 def get_reviewers(self, tbr_only=False): |
3041 """Retrieves the list of reviewers.""" | 3046 """Retrieves the list of reviewers.""" |
3042 matches = [re.match(self.R_LINE, line) for line in self._description_lines] | 3047 matches = [re.match(self.R_LINE, line) for line in self._description_lines] |
3043 reviewers = [match.group(2).strip() | 3048 reviewers = [match.group(2).strip() |
3044 for match in matches | 3049 for match in matches |
3045 if match and (not tbr_only or match.group(1).upper() == 'TBR')] | 3050 if match and (not tbr_only or match.group(1).upper() == 'TBR')] |
3046 return cleanup_list(reviewers) | 3051 return cleanup_list(reviewers) |
3047 | 3052 |
| 3053 def get_cced(self): |
| 3054 """Retrieves the list of reviewers.""" |
| 3055 matches = [re.match(self.CC_LINE, line) for line in self._description_lines] |
| 3056 cced = [match.group(2).strip() for match in matches if match] |
| 3057 return cleanup_list(cced) |
| 3058 |
3048 | 3059 |
3049 def get_approving_reviewers(props): | 3060 def get_approving_reviewers(props): |
3050 """Retrieves the reviewers that approved a CL from the issue properties with | 3061 """Retrieves the reviewers that approved a CL from the issue properties with |
3051 messages. | 3062 messages. |
3052 | 3063 |
3053 Note that the list may contain reviewers that are not committer, thus are not | 3064 Note that the list may contain reviewers that are not committer, thus are not |
3054 considered by the CQ. | 3065 considered by the CQ. |
3055 """ | 3066 """ |
3056 return sorted( | 3067 return sorted( |
3057 set( | 3068 set( |
(...skipping 2356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5414 if __name__ == '__main__': | 5425 if __name__ == '__main__': |
5415 # These affect sys.stdout so do it outside of main() to simplify mocks in | 5426 # These affect sys.stdout so do it outside of main() to simplify mocks in |
5416 # unit testing. | 5427 # unit testing. |
5417 fix_encoding.fix_encoding() | 5428 fix_encoding.fix_encoding() |
5418 setup_color.init() | 5429 setup_color.init() |
5419 try: | 5430 try: |
5420 sys.exit(main(sys.argv[1:])) | 5431 sys.exit(main(sys.argv[1:])) |
5421 except KeyboardInterrupt: | 5432 except KeyboardInterrupt: |
5422 sys.stderr.write('interrupted\n') | 5433 sys.stderr.write('interrupted\n') |
5423 sys.exit(1) | 5434 sys.exit(1) |
OLD | NEW |