Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # git-cl -- a git-command for integrating reviews on Rietveld | 2 # git-cl -- a git-command for integrating reviews on Rietveld |
| 3 # Copyright (C) 2008 Evan Martin <martine@danga.com> | 3 # Copyright (C) 2008 Evan Martin <martine@danga.com> |
| 4 | 4 |
| 5 import errno | 5 import errno |
| 6 import logging | 6 import logging |
| 7 import optparse | 7 import optparse |
| 8 import os | 8 import os |
| 9 import re | 9 import re |
| 10 import StringIO | |
| 10 import subprocess | 11 import subprocess |
| 11 import sys | 12 import sys |
| 12 import tempfile | 13 import tempfile |
| 13 import textwrap | 14 import textwrap |
| 14 import upload | 15 import upload |
| 15 import urlparse | 16 import urlparse |
| 16 import urllib2 | 17 import urllib2 |
| 17 | 18 |
| 18 try: | 19 try: |
| 19 import readline | 20 import readline |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 59 if redirect_stdout: | 60 if redirect_stdout: |
| 60 stdout = subprocess.PIPE | 61 stdout = subprocess.PIPE |
| 61 else: | 62 else: |
| 62 stdout = None | 63 stdout = None |
| 63 if swallow_stderr: | 64 if swallow_stderr: |
| 64 stderr = subprocess.PIPE | 65 stderr = subprocess.PIPE |
| 65 else: | 66 else: |
| 66 stderr = None | 67 stderr = None |
| 67 proc = Popen(cmd, stdout=stdout, stderr=stderr, **kwargs) | 68 proc = Popen(cmd, stdout=stdout, stderr=stderr, **kwargs) |
| 68 output = proc.communicate()[0] | 69 output = proc.communicate()[0] |
| 70 | |
| 69 if not error_ok and proc.returncode != 0: | 71 if not error_ok and proc.returncode != 0: |
| 70 DieWithError('Command "%s" failed.\n' % (' '.join(cmd)) + | 72 DieWithError('Command "%s" failed.\n' % (' '.join(cmd)) + |
| 71 (error_message or output or '')) | 73 (error_message or output or '')) |
| 72 return output | 74 return output |
| 73 | 75 |
| 74 | 76 |
| 75 def RunGit(args, **kwargs): | 77 def RunGit(args, **kwargs): |
| 76 cmd = ['git'] + args | 78 cmd = ['git'] + args |
| 77 return RunCommand(cmd, **kwargs) | 79 return RunCommand(cmd, **kwargs) |
| 78 | 80 |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 473 | 475 |
| 474 SetProperty(settings.GetCCList(), 'CC list', 'cc') | 476 SetProperty(settings.GetCCList(), 'CC list', 'cc') |
| 475 SetProperty(settings.GetTreeStatusUrl(error_ok=True), 'Tree status URL', | 477 SetProperty(settings.GetTreeStatusUrl(error_ok=True), 'Tree status URL', |
| 476 'tree-status-url') | 478 'tree-status-url') |
| 477 SetProperty(settings.GetViewVCUrl(), 'ViewVC URL', 'viewvc-url') | 479 SetProperty(settings.GetViewVCUrl(), 'ViewVC URL', 'viewvc-url') |
| 478 | 480 |
| 479 # TODO: configure a default branch to diff against, rather than this | 481 # TODO: configure a default branch to diff against, rather than this |
| 480 # svn-based hackery. | 482 # svn-based hackery. |
| 481 | 483 |
| 482 | 484 |
| 485 class HookResults(object): | |
| 486 """Contains the parsed output of the presubmit hooks.""" | |
| 487 def __init__(self, output_from_hooks=None): | |
| 488 self.reviewers = [] | |
| 489 self.output = None | |
| 490 self._ParseOutputFromHooks(output_from_hooks) | |
| 491 | |
| 492 def _ParseOutputFromHooks(self, output_from_hooks): | |
| 493 if not output_from_hooks: | |
| 494 return | |
| 495 lines = [] | |
| 496 reviewers = [] | |
| 497 reviewer_regexp = re.compile('ADD: R=(.+)') | |
| 498 for l in output_from_hooks.splitlines(): | |
| 499 m = reviewer_regexp.match(l) | |
| 500 if m: | |
| 501 reviewers.extend(m.group(1).split(',')) | |
| 502 else: | |
| 503 lines.append(l) | |
| 504 self.output = '\n'.join(lines) | |
| 505 self.reviewers = ','.join(reviewers) | |
| 506 | |
| 507 | |
| 508 class ChangeDescription(object): | |
| 509 """Contains a parsed form of the change description.""" | |
| 510 def __init__(self, subject, log_desc, reviewers): | |
| 511 self.subject = subject | |
| 512 self.log_desc = log_desc | |
| 513 self.reviewers = reviewers | |
| 514 self.description = self.log_desc | |
| 515 | |
| 516 def Update(self): | |
| 517 initial_text = """# Enter a description of the change. | |
| 518 # This will displayed on the codereview site. | |
| 519 # The first line will also be used as the subject of the review. | |
| 520 """ | |
| 521 initial_text += self.description | |
| 522 if 'R=' not in self.description and self.reviewers: | |
| 523 initial_text += '\nR=' + self.reviewers | |
| 524 if 'BUG=' not in self.description: | |
| 525 initial_text += '\nBUG=' | |
| 526 if 'TEST=' not in self.description: | |
| 527 initial_text += '\nTEST=' | |
| 528 self._ParseDescription(UserEditedLog(initial_text)) | |
| 529 | |
| 530 def _ParseDescription(self, description): | |
| 531 if not description: | |
| 532 self.description = description | |
| 533 return | |
| 534 | |
| 535 parsed_lines = [] | |
| 536 reviewers_regexp = re.compile('\s*R=(.+)') | |
| 537 reviewers = '' | |
| 538 subject = '' | |
| 539 for l in description.splitlines(): | |
| 540 if not subject: | |
| 541 subject = l | |
| 542 matched_reviewers = reviewers_regexp.match(l) | |
| 543 if matched_reviewers: | |
| 544 reviewers = matched_reviewers.group(1) | |
| 545 parsed_lines.append(l) | |
| 546 | |
| 547 self.description = '\n'.join(parsed_lines) + '\n' | |
| 548 self.subject = subject | |
| 549 self.reviewers = reviewers | |
| 550 | |
| 551 def IsEmpty(self): | |
| 552 return not self.description | |
| 553 | |
| 554 | |
| 483 def FindCodereviewSettingsFile(filename='codereview.settings'): | 555 def FindCodereviewSettingsFile(filename='codereview.settings'): |
| 484 """Finds the given file starting in the cwd and going up. | 556 """Finds the given file starting in the cwd and going up. |
| 485 | 557 |
| 486 Only looks up to the top of the repository unless an | 558 Only looks up to the top of the repository unless an |
| 487 'inherit-review-settings-ok' file exists in the root of the repository. | 559 'inherit-review-settings-ok' file exists in the root of the repository. |
| 488 """ | 560 """ |
| 489 inherit_ok_file = 'inherit-review-settings-ok' | 561 inherit_ok_file = 'inherit-review-settings-ok' |
| 490 cwd = os.getcwd() | 562 cwd = os.getcwd() |
| 491 root = os.path.abspath(RunGit(['rev-parse', '--show-cdup']).strip()) | 563 root = os.path.abspath(RunGit(['rev-parse', '--show-cdup']).strip()) |
| 492 if os.path.isfile(os.path.join(root, inherit_ok_file)): | 564 if os.path.isfile(os.path.join(root, inherit_ok_file)): |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 664 | 736 |
| 665 | 737 |
| 666 def ConvertToInteger(inputval): | 738 def ConvertToInteger(inputval): |
| 667 """Convert a string to integer, but returns either an int or None.""" | 739 """Convert a string to integer, but returns either an int or None.""" |
| 668 try: | 740 try: |
| 669 return int(inputval) | 741 return int(inputval) |
| 670 except (TypeError, ValueError): | 742 except (TypeError, ValueError): |
| 671 return None | 743 return None |
| 672 | 744 |
| 673 | 745 |
| 674 def RunHook(committing, upstream_branch): | 746 def RunHook(committing, upstream_branch, rietveld_server, tbr=False): |
| 747 """Calls sys.exit() if the hook fails; returns a HookResults otherwise.""" | |
| 675 import presubmit_support | 748 import presubmit_support |
| 676 import scm | 749 import scm |
| 677 import watchlists | 750 import watchlists |
| 678 | 751 |
| 679 root = RunCommand(['git', 'rev-parse', '--show-cdup']).strip() | 752 root = RunCommand(['git', 'rev-parse', '--show-cdup']).strip() |
| 680 if not root: | 753 if not root: |
| 681 root = "." | 754 root = "." |
| 682 absroot = os.path.abspath(root) | 755 absroot = os.path.abspath(root) |
| 683 if not root: | 756 if not root: |
| 684 raise Exception("Could not get root directory.") | 757 raise Exception("Could not get root directory.") |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 702 issue, patchset) | 775 issue, patchset) |
| 703 | 776 |
| 704 # Apply watchlists on upload. | 777 # Apply watchlists on upload. |
| 705 if not committing: | 778 if not committing: |
| 706 watchlist = watchlists.Watchlists(change.RepositoryRoot()) | 779 watchlist = watchlists.Watchlists(change.RepositoryRoot()) |
| 707 files = [f.LocalPath() for f in change.AffectedFiles()] | 780 files = [f.LocalPath() for f in change.AffectedFiles()] |
| 708 watchers = watchlist.GetWatchersForPaths(files) | 781 watchers = watchlist.GetWatchersForPaths(files) |
| 709 RunCommand(['git', 'config', '--replace-all', | 782 RunCommand(['git', 'config', '--replace-all', |
| 710 'rietveld.extracc', ','.join(watchers)]) | 783 'rietveld.extracc', ','.join(watchers)]) |
| 711 | 784 |
| 712 return presubmit_support.DoPresubmitChecks(change, committing, | 785 output = StringIO.StringIO() |
| 713 verbose=None, output_stream=sys.stdout, input_stream=sys.stdin, | 786 res = presubmit_support.DoPresubmitChecks(change, committing, |
| 714 default_presubmit=None, may_prompt=None) | 787 verbose=None, output_stream=output, input_stream=sys.stdin, |
| 788 default_presubmit=None, may_prompt=None, tbr=tbr, | |
|
M-A Ruel
2011/03/11 23:11:14
You disable may_prompt so that converts all warnin
| |
| 789 host_url=cl.GetRietveldServer()) | |
| 790 hook_results = HookResults(output.getvalue()) | |
| 791 if hook_results.output: | |
| 792 print hook_results.output | |
| 793 | |
| 794 # TODO(dpranke): We should propagate the error out instead of calling exit(). | |
| 795 if not res: | |
| 796 sys.exit(1) | |
| 797 return hook_results | |
| 715 | 798 |
| 716 | 799 |
| 717 def CMDpresubmit(parser, args): | 800 def CMDpresubmit(parser, args): |
| 718 """run presubmit tests on the current changelist""" | 801 """run presubmit tests on the current changelist""" |
| 719 parser.add_option('--upload', action='store_true', | 802 parser.add_option('--upload', action='store_true', |
| 720 help='Run upload hook instead of the push/dcommit hook') | 803 help='Run upload hook instead of the push/dcommit hook') |
| 721 (options, args) = parser.parse_args(args) | 804 (options, args) = parser.parse_args(args) |
| 722 | 805 |
| 723 # Make sure index is up-to-date before running diff-index. | 806 # Make sure index is up-to-date before running diff-index. |
| 724 RunGit(['update-index', '--refresh', '-q'], error_ok=True) | 807 RunGit(['update-index', '--refresh', '-q'], error_ok=True) |
| 725 if RunGit(['diff-index', 'HEAD']): | 808 if RunGit(['diff-index', 'HEAD']): |
| 726 # TODO(maruel): Is this really necessary? | 809 # TODO(maruel): Is this really necessary? |
| 727 print 'Cannot presubmit with a dirty tree. You must commit locally first.' | 810 print 'Cannot presubmit with a dirty tree. You must commit locally first.' |
| 728 return 1 | 811 return 1 |
| 729 | 812 |
| 813 cl = Changelist() | |
| 730 if args: | 814 if args: |
| 731 base_branch = args[0] | 815 base_branch = args[0] |
| 732 else: | 816 else: |
| 733 # Default to diffing against the "upstream" branch. | 817 # Default to diffing against the "upstream" branch. |
| 734 base_branch = Changelist().GetUpstreamBranch() | 818 base_branch = cl.GetUpstreamBranch() |
| 735 | 819 |
| 736 if options.upload: | 820 if options.upload: |
| 737 print '*** Presubmit checks for UPLOAD would report: ***' | 821 print '*** Presubmit checks for UPLOAD would report: ***' |
| 738 return RunHook(committing=False, upstream_branch=base_branch) | 822 RunHook(committing=False, upstream_branch=base_branch, |
| 823 rietveld_server=cl.GetRietveldServer(), tbr=False) | |
| 824 return 0 | |
| 739 else: | 825 else: |
| 740 print '*** Presubmit checks for DCOMMIT would report: ***' | 826 print '*** Presubmit checks for DCOMMIT would report: ***' |
| 741 return RunHook(committing=True, upstream_branch=base_branch) | 827 RunHook(committing=True, upstream_branch=base_branch, |
| 828 rietveld_server=cl.GetRietveldServer, tbr=False) | |
| 829 return 0 | |
| 742 | 830 |
| 743 | 831 |
| 744 @usage('[args to "git diff"]') | 832 @usage('[args to "git diff"]') |
| 745 def CMDupload(parser, args): | 833 def CMDupload(parser, args): |
| 746 """upload the current changelist to codereview""" | 834 """upload the current changelist to codereview""" |
| 747 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', | 835 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', |
| 748 help='bypass upload presubmit hook') | 836 help='bypass upload presubmit hook') |
| 749 parser.add_option('-m', dest='message', help='message for patch') | 837 parser.add_option('-m', dest='message', help='message for patch') |
| 750 parser.add_option('-r', '--reviewers', | 838 parser.add_option('-r', '--reviewers', |
| 751 help='reviewer email addresses') | 839 help='reviewer email addresses') |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 770 | 858 |
| 771 cl = Changelist() | 859 cl = Changelist() |
| 772 if args: | 860 if args: |
| 773 base_branch = args[0] | 861 base_branch = args[0] |
| 774 else: | 862 else: |
| 775 # Default to diffing against the "upstream" branch. | 863 # Default to diffing against the "upstream" branch. |
| 776 base_branch = cl.GetUpstreamBranch() | 864 base_branch = cl.GetUpstreamBranch() |
| 777 args = [base_branch + "..."] | 865 args = [base_branch + "..."] |
| 778 | 866 |
| 779 if not options.bypass_hooks: | 867 if not options.bypass_hooks: |
| 780 RunHook(committing=False, upstream_branch=base_branch) | 868 hook_results = RunHook(committing=False, upstream_branch=base_branch, |
| 869 rietveld_server=cl.GetRietveldServer(), tbr=False) | |
| 870 else: | |
| 871 hook_results = HookResults() | |
| 872 | |
| 873 if not options.reviewers and hook_results.reviewers: | |
| 874 options.reviewers = hook_results.reviewers | |
| 781 | 875 |
| 782 # --no-ext-diff is broken in some versions of Git, so try to work around | 876 # --no-ext-diff is broken in some versions of Git, so try to work around |
| 783 # this by overriding the environment (but there is still a problem if the | 877 # this by overriding the environment (but there is still a problem if the |
| 784 # git config key "diff.external" is used). | 878 # git config key "diff.external" is used). |
| 785 env = os.environ.copy() | 879 env = os.environ.copy() |
| 786 if 'GIT_EXTERNAL_DIFF' in env: | 880 if 'GIT_EXTERNAL_DIFF' in env: |
| 787 del env['GIT_EXTERNAL_DIFF'] | 881 del env['GIT_EXTERNAL_DIFF'] |
| 788 subprocess.call(['git', 'diff', '--no-ext-diff', '--stat', '-M'] + args, | 882 subprocess.call(['git', 'diff', '--no-ext-diff', '--stat', '-M'] + args, |
| 789 env=env) | 883 env=env) |
| 790 | 884 |
| 791 upload_args = ['--assume_yes'] # Don't ask about untracked files. | 885 upload_args = ['--assume_yes'] # Don't ask about untracked files. |
| 792 upload_args.extend(['--server', cl.GetRietveldServer()]) | 886 upload_args.extend(['--server', cl.GetRietveldServer()]) |
| 793 if options.reviewers: | |
| 794 upload_args.extend(['--reviewers', options.reviewers]) | |
| 795 if options.emulate_svn_auto_props: | 887 if options.emulate_svn_auto_props: |
| 796 upload_args.append('--emulate_svn_auto_props') | 888 upload_args.append('--emulate_svn_auto_props') |
| 797 if options.send_mail: | 889 if options.send_mail: |
| 798 if not options.reviewers: | 890 if not options.reviewers: |
| 799 DieWithError("Must specify reviewers to send email.") | 891 DieWithError("Must specify reviewers to send email.") |
| 800 upload_args.append('--send_mail') | 892 upload_args.append('--send_mail') |
| 801 if options.from_logs and not options.message: | 893 if options.from_logs and not options.message: |
| 802 print 'Must set message for subject line if using desc_from_logs' | 894 print 'Must set message for subject line if using desc_from_logs' |
| 803 return 1 | 895 return 1 |
| 804 | 896 |
| 805 change_desc = None | 897 change_desc = None |
| 806 | 898 |
| 807 if cl.GetIssue(): | 899 if cl.GetIssue(): |
| 808 if options.message: | 900 if options.message: |
| 809 upload_args.extend(['--message', options.message]) | 901 upload_args.extend(['--message', options.message]) |
| 810 upload_args.extend(['--issue', cl.GetIssue()]) | 902 upload_args.extend(['--issue', cl.GetIssue()]) |
| 811 print ("This branch is associated with issue %s. " | 903 print ("This branch is associated with issue %s. " |
| 812 "Adding patch to that issue." % cl.GetIssue()) | 904 "Adding patch to that issue." % cl.GetIssue()) |
| 813 else: | 905 else: |
| 814 log_desc = CreateDescriptionFromLog(args) | 906 log_desc = CreateDescriptionFromLog(args) |
| 815 if options.from_logs: | 907 change_desc = ChangeDescription(options.message, log_desc, |
| 816 # Uses logs as description and message as subject. | 908 options.reviewers) |
| 817 subject = options.message | 909 if not options.from_logs: |
| 818 change_desc = subject + '\n\n' + log_desc | 910 change_desc.Update() |
| 819 else: | 911 |
| 820 initial_text = """# Enter a description of the change. | 912 if change_desc.IsEmpty(): |
| 821 # This will displayed on the codereview site. | |
| 822 # The first line will also be used as the subject of the review. | |
| 823 """ | |
| 824 if 'BUG=' not in log_desc: | |
| 825 log_desc += '\nBUG=' | |
| 826 if 'TEST=' not in log_desc: | |
| 827 log_desc += '\nTEST=' | |
| 828 change_desc = UserEditedLog(initial_text + log_desc) | |
| 829 subject = '' | |
| 830 if change_desc: | |
| 831 subject = change_desc.splitlines()[0] | |
| 832 if not change_desc: | |
| 833 print "Description is empty; aborting." | 913 print "Description is empty; aborting." |
| 834 return 1 | 914 return 1 |
| 835 upload_args.extend(['--message', subject]) | 915 |
| 836 upload_args.extend(['--description', change_desc]) | 916 upload_args.extend(['--message', change_desc.subject]) |
| 917 upload_args.extend(['--description', change_desc.description]) | |
| 918 if change_desc.reviewers: | |
| 919 upload_args.extend(['--reviewers', change_desc.reviewers]) | |
| 837 cc = ','.join(filter(None, (settings.GetCCList(), options.cc))) | 920 cc = ','.join(filter(None, (settings.GetCCList(), options.cc))) |
| 838 if cc: | 921 if cc: |
| 839 upload_args.extend(['--cc', cc]) | 922 upload_args.extend(['--cc', cc]) |
| 840 | 923 |
| 841 # Include the upstream repo's URL in the change -- this is useful for | 924 # Include the upstream repo's URL in the change -- this is useful for |
| 842 # projects that have their source spread across multiple repos. | 925 # projects that have their source spread across multiple repos. |
| 843 remote_url = None | 926 remote_url = None |
| 844 if settings.GetIsGitSvn(): | 927 if settings.GetIsGitSvn(): |
| 845 # URL is dependent on the current directory. | 928 # URL is dependent on the current directory. |
| 846 data = RunGit(['svn', 'info'], cwd=settings.GetRoot()) | 929 data = RunGit(['svn', 'info'], cwd=settings.GetRoot()) |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 858 try: | 941 try: |
| 859 issue, patchset = upload.RealMain(['upload'] + upload_args + args) | 942 issue, patchset = upload.RealMain(['upload'] + upload_args + args) |
| 860 except: | 943 except: |
| 861 # If we got an exception after the user typed a description for their | 944 # If we got an exception after the user typed a description for their |
| 862 # change, back up the description before re-raising. | 945 # change, back up the description before re-raising. |
| 863 if change_desc: | 946 if change_desc: |
| 864 backup_path = os.path.expanduser(DESCRIPTION_BACKUP_FILE) | 947 backup_path = os.path.expanduser(DESCRIPTION_BACKUP_FILE) |
| 865 print '\nGot exception while uploading -- saving description to %s\n' \ | 948 print '\nGot exception while uploading -- saving description to %s\n' \ |
| 866 % backup_path | 949 % backup_path |
| 867 backup_file = open(backup_path, 'w') | 950 backup_file = open(backup_path, 'w') |
| 868 backup_file.write(change_desc) | 951 backup_file.write(change_desc.description) |
| 869 backup_file.close() | 952 backup_file.close() |
| 870 raise | 953 raise |
| 871 | 954 |
| 872 if not cl.GetIssue(): | 955 if not cl.GetIssue(): |
| 873 cl.SetIssue(issue) | 956 cl.SetIssue(issue) |
| 874 cl.SetPatchset(patchset) | 957 cl.SetPatchset(patchset) |
| 875 return 0 | 958 return 0 |
| 876 | 959 |
| 877 | 960 |
| 878 def SendUpstream(parser, args, cmd): | 961 def SendUpstream(parser, args, cmd): |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 926 svn_head = RunGit(['log', '--grep=^git-svn-id:', '-1', | 1009 svn_head = RunGit(['log', '--grep=^git-svn-id:', '-1', |
| 927 '--pretty=format:%H']) | 1010 '--pretty=format:%H']) |
| 928 extra_commits = RunGit(['rev-list', '^' + svn_head, base_branch]) | 1011 extra_commits = RunGit(['rev-list', '^' + svn_head, base_branch]) |
| 929 if extra_commits: | 1012 if extra_commits: |
| 930 print ('This branch has %d additional commits not upstreamed yet.' | 1013 print ('This branch has %d additional commits not upstreamed yet.' |
| 931 % len(extra_commits.splitlines())) | 1014 % len(extra_commits.splitlines())) |
| 932 print ('Upstream "%s" or rebase this branch on top of the upstream trunk ' | 1015 print ('Upstream "%s" or rebase this branch on top of the upstream trunk ' |
| 933 'before attempting to %s.' % (base_branch, cmd)) | 1016 'before attempting to %s.' % (base_branch, cmd)) |
| 934 return 1 | 1017 return 1 |
| 935 | 1018 |
| 936 if not options.force and not options.bypass_hooks: | 1019 if not options.bypass_hooks: |
| 937 RunHook(committing=False, upstream_branch=base_branch) | 1020 hook_results = RunHook(committing=True, upstream_branch=base_branch, |
| 1021 rietveld_server=cl.GetRietveldServer(), tbr=options.tbr) | |
| 938 | 1022 |
| 939 if cmd == 'dcommit': | 1023 if cmd == 'dcommit': |
| 940 # Check the tree status if the tree status URL is set. | 1024 # Check the tree status if the tree status URL is set. |
| 941 status = GetTreeStatus() | 1025 status = GetTreeStatus() |
| 942 if 'closed' == status: | 1026 if 'closed' == status: |
| 943 print ('The tree is closed. Please wait for it to reopen. Use ' | 1027 print ('The tree is closed. Please wait for it to reopen. Use ' |
| 944 '"git cl dcommit -f" to commit on a closed tree.') | 1028 '"git cl dcommit -f" to commit on a closed tree.') |
| 945 return 1 | 1029 return 1 |
| 946 elif 'unknown' == status: | 1030 elif 'unknown' == status: |
| 947 print ('Unable to determine tree status. Please verify manually and ' | 1031 print ('Unable to determine tree status. Please verify manually and ' |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 967 | 1051 |
| 968 description += "\n\nReview URL: %s" % cl.GetIssueURL() | 1052 description += "\n\nReview URL: %s" % cl.GetIssueURL() |
| 969 else: | 1053 else: |
| 970 if not description: | 1054 if not description: |
| 971 # Submitting TBR. See if there's already a description in Rietveld, else | 1055 # Submitting TBR. See if there's already a description in Rietveld, else |
| 972 # create a template description. Eitherway, give the user a chance to edit | 1056 # create a template description. Eitherway, give the user a chance to edit |
| 973 # it to fill in the TBR= field. | 1057 # it to fill in the TBR= field. |
| 974 if cl.GetIssue(): | 1058 if cl.GetIssue(): |
| 975 description = cl.GetDescription() | 1059 description = cl.GetDescription() |
| 976 | 1060 |
| 1061 # TODO(dpranke): Update to use ChangeDescription object. | |
| 977 if not description: | 1062 if not description: |
| 978 description = """# Enter a description of the change. | 1063 description = """# Enter a description of the change. |
| 979 # This will be used as the change log for the commit. | 1064 # This will be used as the change log for the commit. |
| 980 | 1065 |
| 981 """ | 1066 """ |
| 982 description += CreateDescriptionFromLog(args) | 1067 description += CreateDescriptionFromLog(args) |
| 983 | 1068 |
| 984 description = UserEditedLog(description + '\nTBR=') | 1069 description = UserEditedLog(description + '\nTBR=') |
| 985 | 1070 |
| 986 if not description: | 1071 if not description: |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1308 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' | 1393 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' |
| 1309 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 1394 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
| 1310 | 1395 |
| 1311 # Not a known command. Default to help. | 1396 # Not a known command. Default to help. |
| 1312 GenUsage(parser, 'help') | 1397 GenUsage(parser, 'help') |
| 1313 return CMDhelp(parser, argv) | 1398 return CMDhelp(parser, argv) |
| 1314 | 1399 |
| 1315 | 1400 |
| 1316 if __name__ == '__main__': | 1401 if __name__ == '__main__': |
| 1317 sys.exit(main(sys.argv[1:])) | 1402 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |