| 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 2498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2509 'single commit.') | 2509 'single commit.') |
| 2510 ask_for_data('About to upload; enter to confirm.') | 2510 ask_for_data('About to upload; enter to confirm.') |
| 2511 | 2511 |
| 2512 if options.reviewers or options.tbr_owners: | 2512 if options.reviewers or options.tbr_owners: |
| 2513 change_desc.update_reviewers(options.reviewers, options.tbr_owners, | 2513 change_desc.update_reviewers(options.reviewers, options.tbr_owners, |
| 2514 change) | 2514 change) |
| 2515 | 2515 |
| 2516 # Extra options that can be specified at push time. Doc: | 2516 # Extra options that can be specified at push time. Doc: |
| 2517 # https://gerrit-review.googlesource.com/Documentation/user-upload.html | 2517 # https://gerrit-review.googlesource.com/Documentation/user-upload.html |
| 2518 refspec_opts = [] | 2518 refspec_opts = [] |
| 2519 if change_desc.get_reviewers(tbr_only=True): |
| 2520 print('Adding self-LGTM (Code-Review +1) because of TBRs') |
| 2521 refspec_opts.append('l=Code-Review+1') |
| 2522 |
| 2519 if options.title: | 2523 if options.title: |
| 2520 if not re.match(r'^[\w ]+$', options.title): | 2524 if not re.match(r'^[\w ]+$', options.title): |
| 2521 options.title = re.sub(r'[^\w ]', '', options.title) | 2525 options.title = re.sub(r'[^\w ]', '', options.title) |
| 2522 print('WARNING: Patchset title may only contain alphanumeric chars ' | 2526 print('WARNING: Patchset title may only contain alphanumeric chars ' |
| 2523 'and spaces. Cleaned up title:\n%s' % options.title) | 2527 'and spaces. Cleaned up title:\n%s' % options.title) |
| 2524 if not options.force: | 2528 if not options.force: |
| 2525 ask_for_data('Press enter to continue, Ctrl+C to abort') | 2529 ask_for_data('Press enter to continue, Ctrl+C to abort') |
| 2526 # Per doc, spaces must be converted to underscores, and Gerrit will do the | 2530 # Per doc, spaces must be converted to underscores, and Gerrit will do the |
| 2527 # reverse on its side. | 2531 # reverse on its side. |
| 2528 refspec_opts.append('m=' + options.title.replace(' ', '_')) | 2532 refspec_opts.append('m=' + options.title.replace(' ', '_')) |
| 2529 | 2533 |
| 2530 if options.send_mail: | 2534 if options.send_mail: |
| 2531 if not change_desc.get_reviewers(): | 2535 if not change_desc.get_reviewers(): |
| 2532 DieWithError('Must specify reviewers to send email.') | 2536 DieWithError('Must specify reviewers to send email.') |
| 2533 refspec_opts.append('notify=ALL') | 2537 refspec_opts.append('notify=ALL') |
| 2534 else: | 2538 else: |
| 2535 refspec_opts.append('notify=NONE') | 2539 refspec_opts.append('notify=NONE') |
| 2536 | 2540 |
| 2537 cc = self.GetCCList().split(',') | 2541 cc = self.GetCCList().split(',') |
| 2538 if options.cc: | 2542 if options.cc: |
| 2539 cc.extend(options.cc) | 2543 cc.extend(options.cc) |
| 2540 cc = filter(None, cc) | 2544 cc = filter(None, cc) |
| 2541 if cc: | 2545 if cc: |
| 2542 refspec_opts.extend('cc=' + email.strip() for email in cc) | 2546 refspec_opts.extend('cc=' + email.strip() for email in cc) |
| 2543 | 2547 |
| 2544 if change_desc.get_reviewers(): | 2548 reviewers = change_desc.get_reviewers() |
| 2545 refspec_opts.extend('r=' + email.strip() | 2549 if reviewers: |
| 2546 for email in change_desc.get_reviewers()) | 2550 refspec_opts.extend('r=' + email.strip() for email in reviewers) |
| 2547 | 2551 |
| 2548 refspec_suffix = '' | 2552 refspec_suffix = '' |
| 2549 if refspec_opts: | 2553 if refspec_opts: |
| 2550 refspec_suffix = '%' + ','.join(refspec_opts) | 2554 refspec_suffix = '%' + ','.join(refspec_opts) |
| 2551 assert ' ' not in refspec_suffix, ( | 2555 assert ' ' not in refspec_suffix, ( |
| 2552 'spaces not allowed in refspec: "%s"' % refspec_suffix) | 2556 'spaces not allowed in refspec: "%s"' % refspec_suffix) |
| 2553 refspec = '%s:refs/for/%s%s' % (ref_to_push, branch, refspec_suffix) | 2557 refspec = '%s:refs/for/%s%s' % (ref_to_push, branch, refspec_suffix) |
| 2554 | 2558 |
| 2555 push_stdout = gclient_utils.CheckCallAndFilter( | 2559 push_stdout = gclient_utils.CheckCallAndFilter( |
| 2556 ['git', 'push', gerrit_remote, refspec], | 2560 ['git', 'push', gerrit_remote, refspec], |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2797 else: | 2801 else: |
| 2798 separator = [] # No need for separator if there are no gerrit_footers. | 2802 separator = [] # No need for separator if there are no gerrit_footers. |
| 2799 | 2803 |
| 2800 prev_line = top_lines[-1] if top_lines else '' | 2804 prev_line = top_lines[-1] if top_lines else '' |
| 2801 if (not presubmit_support.Change.TAG_LINE_RE.match(prev_line) or | 2805 if (not presubmit_support.Change.TAG_LINE_RE.match(prev_line) or |
| 2802 not presubmit_support.Change.TAG_LINE_RE.match(line)): | 2806 not presubmit_support.Change.TAG_LINE_RE.match(line)): |
| 2803 top_lines.append('') | 2807 top_lines.append('') |
| 2804 top_lines.append(line) | 2808 top_lines.append(line) |
| 2805 self._description_lines = top_lines + separator + gerrit_footers | 2809 self._description_lines = top_lines + separator + gerrit_footers |
| 2806 | 2810 |
| 2807 def get_reviewers(self): | 2811 def get_reviewers(self, tbr_only=False): |
| 2808 """Retrieves the list of reviewers.""" | 2812 """Retrieves the list of reviewers.""" |
| 2809 matches = [re.match(self.R_LINE, line) for line in self._description_lines] | 2813 matches = [re.match(self.R_LINE, line) for line in self._description_lines] |
| 2810 reviewers = [match.group(2).strip() for match in matches if match] | 2814 reviewers = [match.group(2).strip() |
| 2815 for match in matches |
| 2816 if match and (not tbr_only or match.group(1).upper() == 'TBR')] |
| 2811 return cleanup_list(reviewers) | 2817 return cleanup_list(reviewers) |
| 2812 | 2818 |
| 2813 | 2819 |
| 2814 def get_approving_reviewers(props): | 2820 def get_approving_reviewers(props): |
| 2815 """Retrieves the reviewers that approved a CL from the issue properties with | 2821 """Retrieves the reviewers that approved a CL from the issue properties with |
| 2816 messages. | 2822 messages. |
| 2817 | 2823 |
| 2818 Note that the list may contain reviewers that are not committer, thus are not | 2824 Note that the list may contain reviewers that are not committer, thus are not |
| 2819 considered by the CQ. | 2825 considered by the CQ. |
| 2820 """ | 2826 """ |
| (...skipping 2294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5115 if __name__ == '__main__': | 5121 if __name__ == '__main__': |
| 5116 # These affect sys.stdout so do it outside of main() to simplify mocks in | 5122 # These affect sys.stdout so do it outside of main() to simplify mocks in |
| 5117 # unit testing. | 5123 # unit testing. |
| 5118 fix_encoding.fix_encoding() | 5124 fix_encoding.fix_encoding() |
| 5119 setup_color.init() | 5125 setup_color.init() |
| 5120 try: | 5126 try: |
| 5121 sys.exit(main(sys.argv[1:])) | 5127 sys.exit(main(sys.argv[1:])) |
| 5122 except KeyboardInterrupt: | 5128 except KeyboardInterrupt: |
| 5123 sys.stderr.write('interrupted\n') | 5129 sys.stderr.write('interrupted\n') |
| 5124 sys.exit(1) | 5130 sys.exit(1) |
| OLD | NEW |