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

Side by Side Diff: git_cl.py

Issue 2117483002: Implement git cl upload -b BUG --bug=BUG. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 4 years, 5 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
« no previous file with comments | « no previous file | tests/git_cl_test.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/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 1898 matching lines...) Expand 10 before | Expand all | Expand 10 after
1909 if options.title: 1909 if options.title:
1910 upload_args.extend(['--title', options.title]) 1910 upload_args.extend(['--title', options.title])
1911 message = (options.title or options.message or 1911 message = (options.title or options.message or
1912 CreateDescriptionFromLog(args)) 1912 CreateDescriptionFromLog(args))
1913 change_desc = ChangeDescription(message) 1913 change_desc = ChangeDescription(message)
1914 if options.reviewers or options.tbr_owners: 1914 if options.reviewers or options.tbr_owners:
1915 change_desc.update_reviewers(options.reviewers, 1915 change_desc.update_reviewers(options.reviewers,
1916 options.tbr_owners, 1916 options.tbr_owners,
1917 change) 1917 change)
1918 if not options.force: 1918 if not options.force:
1919 change_desc.prompt() 1919 change_desc.prompt(bug=options.bug)
1920 1920
1921 if not change_desc.description: 1921 if not change_desc.description:
1922 print('Description is empty; aborting.') 1922 print('Description is empty; aborting.')
1923 return 1 1923 return 1
1924 1924
1925 upload_args.extend(['--message', change_desc.description]) 1925 upload_args.extend(['--message', change_desc.description])
1926 if change_desc.get_reviewers(): 1926 if change_desc.get_reviewers():
1927 upload_args.append('--reviewers=%s' % ','.join( 1927 upload_args.append('--reviewers=%s' % ','.join(
1928 change_desc.get_reviewers())) 1928 change_desc.get_reviewers()))
1929 if options.send_mail: 1929 if options.send_mail:
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
2458 'WARNING: issue %s has Change-Id footer(s):\n' 2458 'WARNING: issue %s has Change-Id footer(s):\n'
2459 ' %s\n' 2459 ' %s\n'
2460 'but issue has Change-Id %s, according to Gerrit.\n' 2460 'but issue has Change-Id %s, according to Gerrit.\n'
2461 'Please, check the proposed correction to the description, ' 2461 'Please, check the proposed correction to the description, '
2462 'and edit it if necessary but keep the "Change-Id: %s" footer\n' 2462 'and edit it if necessary but keep the "Change-Id: %s" footer\n'
2463 % (self.GetIssue(), '\n '.join(footer_change_ids), change_id, 2463 % (self.GetIssue(), '\n '.join(footer_change_ids), change_id,
2464 change_id)) 2464 change_id))
2465 ask_for_data('Press enter to edit now, Ctrl+C to abort') 2465 ask_for_data('Press enter to edit now, Ctrl+C to abort')
2466 if not options.force: 2466 if not options.force:
2467 change_desc = ChangeDescription(message) 2467 change_desc = ChangeDescription(message)
2468 change_desc.prompt() 2468 change_desc.prompt(bug=options.bug)
2469 message = change_desc.description 2469 message = change_desc.description
2470 if not message: 2470 if not message:
2471 DieWithError("Description is empty. Aborting...") 2471 DieWithError("Description is empty. Aborting...")
2472 # Continue the while loop. 2472 # Continue the while loop.
2473 # Sanity check of this code - we should end up with proper message 2473 # Sanity check of this code - we should end up with proper message
2474 # footer. 2474 # footer.
2475 assert [change_id] == git_footers.get_footer_change_id(message) 2475 assert [change_id] == git_footers.get_footer_change_id(message)
2476 change_desc = ChangeDescription(message) 2476 change_desc = ChangeDescription(message)
2477 else: 2477 else:
2478 change_desc = ChangeDescription( 2478 change_desc = ChangeDescription(
2479 options.message or CreateDescriptionFromLog(args)) 2479 options.message or CreateDescriptionFromLog(args))
2480 if not options.force: 2480 if not options.force:
2481 change_desc.prompt() 2481 change_desc.prompt(bug=options.bug)
2482 if not change_desc.description: 2482 if not change_desc.description:
2483 DieWithError("Description is empty. Aborting...") 2483 DieWithError("Description is empty. Aborting...")
2484 message = change_desc.description 2484 message = change_desc.description
2485 change_ids = git_footers.get_footer_change_id(message) 2485 change_ids = git_footers.get_footer_change_id(message)
2486 if len(change_ids) > 1: 2486 if len(change_ids) > 1:
2487 DieWithError('too many Change-Id footers, at most 1 allowed.') 2487 DieWithError('too many Change-Id footers, at most 1 allowed.')
2488 if not change_ids: 2488 if not change_ids:
2489 # Generate the Change-Id automatically. 2489 # Generate the Change-Id automatically.
2490 message = git_footers.add_footer_change_id( 2490 message = git_footers.add_footer_change_id(
2491 message, GenerateGerritChangeId(message)) 2491 message, GenerateGerritChangeId(message))
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2653 def _process_codereview_select_options(parser, options): 2653 def _process_codereview_select_options(parser, options):
2654 if options.gerrit and options.rietveld: 2654 if options.gerrit and options.rietveld:
2655 parser.error('Options --gerrit and --rietveld are mutually exclusive') 2655 parser.error('Options --gerrit and --rietveld are mutually exclusive')
2656 options.forced_codereview = None 2656 options.forced_codereview = None
2657 if options.gerrit: 2657 if options.gerrit:
2658 options.forced_codereview = 'gerrit' 2658 options.forced_codereview = 'gerrit'
2659 elif options.rietveld: 2659 elif options.rietveld:
2660 options.forced_codereview = 'rietveld' 2660 options.forced_codereview = 'rietveld'
2661 2661
2662 2662
2663 def _get_bug_line_value(prefix, bugs):
2664 """Given prefix and comma separated list of bugs, returns a proper bug line.
2665
2666 Each bug can be either:
2667 * a number, which is combined with prefix
2668 * string, which is left as is.
2669
2670 >>> _get_bug_line_value('v8', '123,chromium:789')
2671 'v8:123,chromium:789'
Sergiy Byelozyorov 2016/07/01 14:41:12 I'd also check if each bug is in '\w+:\d+' format.
tandrii(chromium) 2016/07/01 15:27:04 Acknowledged.
2672 """
2673 def to_str(bug):
2674 bug = bug.strip()
2675 if not prefix:
2676 return bug
2677 try:
2678 return '%s:%d' % (prefix, int(bug))
2679 except ValueError:
2680 return bug
2681 return bug
Sergiy Byelozyorov 2016/07/01 14:41:12 Why is this necessary? You either return inside tr
tandrii(chromium) 2016/07/01 15:27:04 yep, leftover.
2682 return ','.join(map(to_str, bugs.split(',')))
Sergiy Byelozyorov 2016/07/01 14:41:12 How about ', '.join(...)? Looks nicer for humans,
tandrii(chromium) 2016/07/01 15:27:04 Rietveld doens't care, neither does Gerrit. It's a
2683
2684
2685
2663 class ChangeDescription(object): 2686 class ChangeDescription(object):
2664 """Contains a parsed form of the change description.""" 2687 """Contains a parsed form of the change description."""
2665 R_LINE = r'^[ \t]*(TBR|R)[ \t]*=[ \t]*(.*?)[ \t]*$' 2688 R_LINE = r'^[ \t]*(TBR|R)[ \t]*=[ \t]*(.*?)[ \t]*$'
2666 BUG_LINE = r'^[ \t]*(BUG)[ \t]*=[ \t]*(.*?)[ \t]*$' 2689 BUG_LINE = r'^[ \t]*(BUG)[ \t]*=[ \t]*(.*?)[ \t]*$'
2667 2690
2668 def __init__(self, description): 2691 def __init__(self, description):
2669 self._description_lines = (description or '').strip().splitlines() 2692 self._description_lines = (description or '').strip().splitlines()
2670 2693
2671 @property # www.logilab.org/ticket/89786 2694 @property # www.logilab.org/ticket/89786
2672 def description(self): # pylint: disable=E0202 2695 def description(self): # pylint: disable=E0202
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2728 if new_tbr_line: 2751 if new_tbr_line:
2729 self._description_lines.insert(line_loc, new_tbr_line) 2752 self._description_lines.insert(line_loc, new_tbr_line)
2730 if new_r_line: 2753 if new_r_line:
2731 self._description_lines.insert(line_loc, new_r_line) 2754 self._description_lines.insert(line_loc, new_r_line)
2732 else: 2755 else:
2733 if new_r_line: 2756 if new_r_line:
2734 self.append_footer(new_r_line) 2757 self.append_footer(new_r_line)
2735 if new_tbr_line: 2758 if new_tbr_line:
2736 self.append_footer(new_tbr_line) 2759 self.append_footer(new_tbr_line)
2737 2760
2738 def prompt(self): 2761 def prompt(self, bug=None):
2739 """Asks the user to update the description.""" 2762 """Asks the user to update the description."""
2740 self.set_description([ 2763 self.set_description([
2741 '# Enter a description of the change.', 2764 '# Enter a description of the change.',
2742 '# This will be displayed on the codereview site.', 2765 '# This will be displayed on the codereview site.',
2743 '# The first line will also be used as the subject of the review.', 2766 '# The first line will also be used as the subject of the review.',
2744 '#--------------------This line is 72 characters long' 2767 '#--------------------This line is 72 characters long'
2745 '--------------------', 2768 '--------------------',
2746 ] + self._description_lines) 2769 ] + self._description_lines)
2747 2770
2748 regexp = re.compile(self.BUG_LINE) 2771 regexp = re.compile(self.BUG_LINE)
2749 if not any((regexp.match(line) for line in self._description_lines)): 2772 if not any((regexp.match(line) for line in self._description_lines)):
2750 self.append_footer('BUG=%s' % settings.GetBugPrefix()) 2773 prefix = settings.GetBugPrefix()
2774 value = _get_bug_line_value(prefix, bug) if bug else prefix
2775 # TODO(tandrii): change this to 'Bug: xxx' to be a proper Gerrit footer.
2776 self.append_footer('BUG=%s' % value)
2751 content = gclient_utils.RunEditor(self.description, True, 2777 content = gclient_utils.RunEditor(self.description, True,
2752 git_editor=settings.GetGitEditor()) 2778 git_editor=settings.GetGitEditor())
2753 if not content: 2779 if not content:
2754 DieWithError('Running editor failed') 2780 DieWithError('Running editor failed')
2755 lines = content.splitlines() 2781 lines = content.splitlines()
2756 2782
2757 # Strip off comments. 2783 # Strip off comments.
2758 clean_lines = [line.rstrip() for line in lines if not line.startswith('#')] 2784 clean_lines = [line.rstrip() for line in lines if not line.startswith('#')]
2759 if not clean_lines: 2785 if not clean_lines:
2760 DieWithError('No CL description, aborting') 2786 DieWithError('No CL description, aborting')
(...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after
3718 Can also set the above globally by using the --global flag. 3744 Can also set the above globally by using the --global flag.
3719 """ 3745 """
3720 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', 3746 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks',
3721 help='bypass upload presubmit hook') 3747 help='bypass upload presubmit hook')
3722 parser.add_option('--bypass-watchlists', action='store_true', 3748 parser.add_option('--bypass-watchlists', action='store_true',
3723 dest='bypass_watchlists', 3749 dest='bypass_watchlists',
3724 help='bypass watchlists auto CC-ing reviewers') 3750 help='bypass watchlists auto CC-ing reviewers')
3725 parser.add_option('-f', action='store_true', dest='force', 3751 parser.add_option('-f', action='store_true', dest='force',
3726 help="force yes to questions (don't prompt)") 3752 help="force yes to questions (don't prompt)")
3727 parser.add_option('-m', dest='message', help='message for patchset') 3753 parser.add_option('-m', dest='message', help='message for patchset')
3754 parser.add_option('-b', '--bug',
3755 help='pre-populate the bug number(s) for this issue. '
3756 'If several, separate with commas')
3728 parser.add_option('--message-file', dest='message_file', 3757 parser.add_option('--message-file', dest='message_file',
3729 help='file which contains message for patchset') 3758 help='file which contains message for patchset')
3730 parser.add_option('-t', dest='title', 3759 parser.add_option('-t', dest='title',
3731 help='title for patchset (Rietveld only)') 3760 help='title for patchset (Rietveld only)')
3732 parser.add_option('-r', '--reviewers', 3761 parser.add_option('-r', '--reviewers',
3733 action='append', default=[], 3762 action='append', default=[],
3734 help='reviewer email addresses') 3763 help='reviewer email addresses')
3735 parser.add_option('--cc', 3764 parser.add_option('--cc',
3736 action='append', default=[], 3765 action='append', default=[],
3737 help='cc email addresses') 3766 help='cc email addresses')
(...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after
5079 if __name__ == '__main__': 5108 if __name__ == '__main__':
5080 # These affect sys.stdout so do it outside of main() to simplify mocks in 5109 # These affect sys.stdout so do it outside of main() to simplify mocks in
5081 # unit testing. 5110 # unit testing.
5082 fix_encoding.fix_encoding() 5111 fix_encoding.fix_encoding()
5083 setup_color.init() 5112 setup_color.init()
5084 try: 5113 try:
5085 sys.exit(main(sys.argv[1:])) 5114 sys.exit(main(sys.argv[1:]))
5086 except KeyboardInterrupt: 5115 except KeyboardInterrupt:
5087 sys.stderr.write('interrupted\n') 5116 sys.stderr.write('interrupted\n')
5088 sys.exit(1) 5117 sys.exit(1)
OLDNEW
« no previous file with comments | « no previous file | tests/git_cl_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698