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

Side by Side Diff: gcl.py

Issue 2096003: Refactor gcl.py to use a similar pattern for every commands. (Closed)
Patch Set: Small fix Created 10 years, 7 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/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) 2006-2009 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2006-2009 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 """Wrapper script around Rietveld's upload.py that groups files into 6 """Wrapper script around Rietveld's upload.py that groups files into
7 changelists.""" 7 changelists."""
8 8
9 import getpass 9 import getpass
10 import os 10 import os
11 import random 11 import random
12 import re 12 import re
13 import shutil 13 import shutil
14 import string 14 import string
15 import subprocess 15 import subprocess
16 import sys 16 import sys
17 import tempfile 17 import tempfile
18 import time 18 import time
19 from third_party import upload 19 from third_party import upload
20 import urllib2 20 import urllib2
21 21
22 __pychecker__ = 'unusednames=breakpad'
22 import breakpad 23 import breakpad
24 __pychecker__ = ''
23 25
24 # gcl now depends on gclient. 26 # gcl now depends on gclient.
25 from scm import SVN 27 from scm import SVN
26 import gclient_utils 28 import gclient_utils
27 29
28 __version__ = '1.1.3' 30 __version__ = '1.1.3'
29 31
30 32
31 CODEREVIEW_SETTINGS = { 33 CODEREVIEW_SETTINGS = {
32 # Ideally, we want to set |CODE_REVIEW_SERVER| to a generic server like 34 # Ideally, we want to set |CODE_REVIEW_SERVER| to a generic server like
(...skipping 19 matching lines...) Expand all
52 54
53 # Filename where we store repository specific information for gcl. 55 # Filename where we store repository specific information for gcl.
54 CODEREVIEW_SETTINGS_FILE = "codereview.settings" 56 CODEREVIEW_SETTINGS_FILE = "codereview.settings"
55 57
56 # Warning message when the change appears to be missing tests. 58 # Warning message when the change appears to be missing tests.
57 MISSING_TEST_MSG = "Change contains new or modified methods, but no new tests!" 59 MISSING_TEST_MSG = "Change contains new or modified methods, but no new tests!"
58 60
59 # Global cache of files cached in GetCacheDir(). 61 # Global cache of files cached in GetCacheDir().
60 FILES_CACHE = {} 62 FILES_CACHE = {}
61 63
64 # Valid extensions for files we want to lint.
65 DEFAULT_LINT_REGEX = r"(.*\.cpp|.*\.cc|.*\.h)"
66 DEFAULT_LINT_IGNORE_REGEX = r"$^"
67
68
62 def CheckHomeForFile(filename): 69 def CheckHomeForFile(filename):
63 """Checks the users home dir for the existence of the given file. Returns 70 """Checks the users home dir for the existence of the given file. Returns
64 the path to the file if it's there, or None if it is not. 71 the path to the file if it's there, or None if it is not.
65 """ 72 """
66 home_vars = ['HOME'] 73 home_vars = ['HOME']
67 if sys.platform in ('cygwin', 'win32'): 74 if sys.platform in ('cygwin', 'win32'):
68 home_vars.append('USERPROFILE') 75 home_vars.append('USERPROFILE')
69 for home_var in home_vars: 76 for home_var in home_vars:
70 home = os.getenv(home_var) 77 home = os.getenv(home_var)
71 if home != None: 78 if home != None:
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 ErrorExit("Error accessing url %s" % request_path) 588 ErrorExit("Error accessing url %s" % request_path)
582 else: 589 else:
583 return None 590 return None
584 591
585 592
586 def GetIssueDescription(issue): 593 def GetIssueDescription(issue):
587 """Returns the issue description from Rietveld.""" 594 """Returns the issue description from Rietveld."""
588 return SendToRietveld("/%d/description" % issue) 595 return SendToRietveld("/%d/description" % issue)
589 596
590 597
591 def Opened(show_unknown_files): 598 def ListFiles(show_unknown_files):
592 """Prints a list of modified files in the current directory down."""
593 files = GetModifiedFiles() 599 files = GetModifiedFiles()
594 cl_keys = files.keys() 600 cl_keys = files.keys()
595 cl_keys.sort() 601 cl_keys.sort()
596 for cl_name in cl_keys: 602 for cl_name in cl_keys:
597 if not cl_name: 603 if not cl_name:
598 continue 604 continue
599 note = "" 605 note = ""
600 change_info = ChangeInfo.Load(cl_name, GetRepositoryRoot(), 606 change_info = ChangeInfo.Load(cl_name, GetRepositoryRoot(),
601 fail_on_not_found=True, update_status=False) 607 fail_on_not_found=True, update_status=False)
602 if len(change_info.GetFiles()) != len(files[cl_name]): 608 if len(change_info.GetFiles()) != len(files[cl_name]):
603 note = " (Note: this changelist contains files outside this directory)" 609 note = " (Note: this changelist contains files outside this directory)"
604 print "\n--- Changelist " + cl_name + note + ":" 610 print "\n--- Changelist " + cl_name + note + ":"
605 for filename in files[cl_name]: 611 for filename in files[cl_name]:
606 print "".join(filename) 612 print "".join(filename)
607 if show_unknown_files: 613 if show_unknown_files:
608 unknown_files = UnknownFiles([]) 614 unknown_files = UnknownFiles([])
609 if (files.get('') or (show_unknown_files and len(unknown_files))): 615 if (files.get('') or (show_unknown_files and len(unknown_files))):
610 print "\n--- Not in any changelist:" 616 print "\n--- Not in any changelist:"
611 for item in files.get('', []): 617 for item in files.get('', []):
612 print "".join(item) 618 print "".join(item)
613 if show_unknown_files: 619 if show_unknown_files:
614 for filename in unknown_files: 620 for filename in unknown_files:
615 print "? %s" % filename 621 print "? %s" % filename
622 return 0
616 623
617 624
618 def Help(argv=None): 625 def CMDopened(argv):
619 if argv: 626 """Lists modified files in the current directory down."""
620 if argv[0] == 'try': 627 __pychecker__ = 'unusednames=argv'
628 return ListFiles(False)
629
630
631 def CMDstatus(argv):
632 """Lists modified and unknown files in the current directory down."""
633 __pychecker__ = 'unusednames=argv'
634 return ListFiles(True)
635
636
637 def CMDhelp(argv=None):
638 """Prints this help or help for the given command."""
639 if len(argv) > 2:
640 if argv[2] == 'try':
621 TryChange(None, ['--help'], swallow_exception=False) 641 TryChange(None, ['--help'], swallow_exception=False)
622 return 642 return 0
623 if argv[0] == 'upload': 643 if argv[2] == 'upload':
624 upload.RealMain(['upload.py', '--help']) 644 upload.RealMain(['upload.py', '--help'])
625 return 645 return 0
626 646
627 print ( 647 print (
628 """GCL is a wrapper for Subversion that simplifies working with groups of files. 648 """GCL is a wrapper for Subversion that simplifies working with groups of files.
629 version """ + __version__ + """ 649 version """ + __version__ + """
630 650
631 Basic commands: 651 Basic commands:
632 ----------------------------------------- 652 -----------------------------------------
633 gcl change change_name 653 gcl change change_name
634 Add/remove files to a changelist. Only scans the current directory and 654 Add/remove files to a changelist. Only scans the current directory and
635 subdirectories. 655 subdirectories.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 of changenames. 710 of changenames.
691 --> Use 'gcl help try' for more information! 711 --> Use 'gcl help try' for more information!
692 712
693 gcl deleteempties 713 gcl deleteempties
694 Deletes all changelists that have no files associated with them. Careful, 714 Deletes all changelists that have no files associated with them. Careful,
695 you can lose your descriptions. 715 you can lose your descriptions.
696 716
697 gcl help [command] 717 gcl help [command]
698 Print this help menu, or help for the given command if it exists. 718 Print this help menu, or help for the given command if it exists.
699 """) 719 """)
720 return 0
721
700 722
701 def GetEditor(): 723 def GetEditor():
702 editor = os.environ.get("SVN_EDITOR") 724 editor = os.environ.get("SVN_EDITOR")
703 if not editor: 725 if not editor:
704 editor = os.environ.get("EDITOR") 726 editor = os.environ.get("EDITOR")
705 727
706 if not editor: 728 if not editor:
707 if sys.platform.startswith("win"): 729 if sys.platform.startswith("win"):
708 editor = "notepad" 730 editor = "notepad"
709 else: 731 else:
710 editor = "vi" 732 editor = "vi"
711 733
712 return editor 734 return editor
713 735
714 736
715 def GenerateDiff(files, root=None): 737 def GenerateDiff(files, root=None):
716 return SVN.GenerateDiff(files, root=root) 738 return SVN.GenerateDiff(files, root=root)
717 739
718 740
719 def OptionallyDoPresubmitChecks(change_info, committing, args): 741 def OptionallyDoPresubmitChecks(change_info, committing, args):
720 if FilterFlag(args, "--no_presubmit") or FilterFlag(args, "--force"): 742 if FilterFlag(args, "--no_presubmit") or FilterFlag(args, "--force"):
721 return True 743 return True
722 return DoPresubmitChecks(change_info, committing, True) 744 return DoPresubmitChecks(change_info, committing, True)
723 745
724 746
725 def UploadCL(change_info, args): 747 def CMDupload(change_info, args):
726 if not change_info.GetFiles(): 748 if not change_info.GetFiles():
727 print "Nothing to upload, changelist is empty." 749 print "Nothing to upload, changelist is empty."
728 return 750 return
729 if not OptionallyDoPresubmitChecks(change_info, False, args): 751 if not OptionallyDoPresubmitChecks(change_info, False, args):
730 return 752 return
731 # Might want to support GetInfoDir()/GetRepositoryRoot() like 753 # Might want to support GetInfoDir()/GetRepositoryRoot() like
732 # CheckHomeForFile() so the skip of tries can be per tree basis instead 754 # CheckHomeForFile() so the skip of tries can be per tree basis instead
733 # of user global. 755 # of user global.
734 no_try = FilterFlag(args, "--no_try") or \ 756 no_try = FilterFlag(args, "--no_try") or \
735 FilterFlag(args, "--no-try") or \ 757 FilterFlag(args, "--no-try") or \
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 if not no_try: 853 if not no_try:
832 try_on_upload = GetCodeReviewSetting('TRY_ON_UPLOAD') 854 try_on_upload = GetCodeReviewSetting('TRY_ON_UPLOAD')
833 if try_on_upload and try_on_upload.lower() == 'true': 855 if try_on_upload and try_on_upload.lower() == 'true':
834 trychange_args = [] 856 trychange_args = []
835 if clobber: 857 if clobber:
836 trychange_args.append('--clobber') 858 trychange_args.append('--clobber')
837 TryChange(change_info, trychange_args, swallow_exception=True) 859 TryChange(change_info, trychange_args, swallow_exception=True)
838 860
839 861
840 862
841 def PresubmitCL(change_info): 863 def CMDpresubmit(change_info, argv):
842 """Reports what presubmit checks on the change would report.""" 864 """Runs presubmit checks on the change."""
865 __pychecker__ = 'unusednames=argv'
843 if not change_info.GetFiles(): 866 if not change_info.GetFiles():
844 print "Nothing to presubmit check, changelist is empty." 867 print "Nothing to presubmit check, changelist is empty."
845 return 868 return 0
846 869
847 print "*** Presubmit checks for UPLOAD would report: ***" 870 print "*** Presubmit checks for UPLOAD would report: ***"
848 DoPresubmitChecks(change_info, False, False) 871 result = DoPresubmitChecks(change_info, False, False)
849 872
850 print "\n*** Presubmit checks for COMMIT would report: ***" 873 print "\n*** Presubmit checks for COMMIT would report: ***"
851 DoPresubmitChecks(change_info, True, False) 874 result &= DoPresubmitChecks(change_info, True, False)
875 return not result
852 876
853 877
854 def TryChange(change_info, args, swallow_exception): 878 def TryChange(change_info, args, swallow_exception):
855 """Create a diff file of change_info and send it to the try server.""" 879 """Create a diff file of change_info and send it to the try server."""
856 try: 880 try:
857 import trychange 881 import trychange
858 except ImportError: 882 except ImportError:
859 if swallow_exception: 883 if swallow_exception:
860 return 884 return
861 ErrorExit("You need to install trychange.py to use the try server.") 885 ErrorExit("You need to install trychange.py to use the try server.")
862 886
863 trychange_args = [] 887 trychange_args = []
864 if change_info: 888 if change_info:
865 trychange_args.extend(['--name', change_info.name]) 889 trychange_args.extend(['--name', change_info.name])
866 if change_info.issue: 890 if change_info.issue:
867 trychange_args.extend(["--issue", str(change_info.issue)]) 891 trychange_args.extend(["--issue", str(change_info.issue)])
868 if change_info.patchset: 892 if change_info.patchset:
869 trychange_args.extend(["--patchset", str(change_info.patchset)]) 893 trychange_args.extend(["--patchset", str(change_info.patchset)])
870 trychange_args.extend(args) 894 trychange_args.extend(args)
871 file_list = change_info.GetFileNames() 895 file_list = change_info.GetFileNames()
872 else: 896 else:
873 trychange_args.extend(args) 897 trychange_args.extend(args)
874 file_list = None 898 file_list = None
875 trychange.TryChange(trychange_args, 899 trychange.TryChange(trychange_args,
876 file_list=file_list, 900 file_list=file_list,
877 swallow_exception=swallow_exception, 901 swallow_exception=swallow_exception,
878 prog='gcl try') 902 prog='gcl try')
879 903
880 904
881 def Commit(change_info, args): 905 def CMDcommit(change_info, args):
882 if not change_info.GetFiles(): 906 if not change_info.GetFiles():
883 print "Nothing to commit, changelist is empty." 907 print "Nothing to commit, changelist is empty."
884 return 908 return 1
885 if not OptionallyDoPresubmitChecks(change_info, True, args): 909 if not OptionallyDoPresubmitChecks(change_info, True, args):
886 return 910 return 1
887 911
888 # We face a problem with svn here: Let's say change 'bleh' modifies 912 # We face a problem with svn here: Let's say change 'bleh' modifies
889 # svn:ignore on dir1\. but another unrelated change 'pouet' modifies 913 # svn:ignore on dir1\. but another unrelated change 'pouet' modifies
890 # dir1\foo.cc. When the user `gcl commit bleh`, foo.cc is *also committed*. 914 # dir1\foo.cc. When the user `gcl commit bleh`, foo.cc is *also committed*.
891 # The only fix is to use --non-recursive but that has its issues too: 915 # The only fix is to use --non-recursive but that has its issues too:
892 # Let's say if dir1 is deleted, --non-recursive must *not* be used otherwise 916 # Let's say if dir1 is deleted, --non-recursive must *not* be used otherwise
893 # you'll get "svn: Cannot non-recursively commit a directory deletion of a 917 # you'll get "svn: Cannot non-recursively commit a directory deletion of a
894 # directory with child nodes". Yay... 918 # directory with child nodes". Yay...
895 commit_cmd = ["svn", "commit"] 919 commit_cmd = ["svn", "commit"]
896 if change_info.issue: 920 if change_info.issue:
(...skipping 28 matching lines...) Expand all
925 949
926 if change_info.issue: 950 if change_info.issue:
927 revision = re.compile(".*?\nCommitted revision (\d+)", 951 revision = re.compile(".*?\nCommitted revision (\d+)",
928 re.DOTALL).match(output).group(1) 952 re.DOTALL).match(output).group(1)
929 viewvc_url = GetCodeReviewSetting("VIEW_VC") 953 viewvc_url = GetCodeReviewSetting("VIEW_VC")
930 change_info.description = change_info.description + '\n' 954 change_info.description = change_info.description + '\n'
931 if viewvc_url: 955 if viewvc_url:
932 change_info.description += "\nCommitted: " + viewvc_url + revision 956 change_info.description += "\nCommitted: " + viewvc_url + revision
933 change_info.CloseIssue() 957 change_info.CloseIssue()
934 os.chdir(previous_cwd) 958 os.chdir(previous_cwd)
959 return 0
935 960
936 961
937 def Change(change_info, args): 962 def CMDchange(change_info, args):
938 """Creates/edits a changelist.""" 963 """Creates/edits a changelist."""
939 silent = FilterFlag(args, "--silent") 964 silent = FilterFlag(args, "--silent")
940 965
941 # Verify the user is running the change command from a read-write checkout. 966 # Verify the user is running the change command from a read-write checkout.
942 svn_info = SVN.CaptureInfo('.') 967 svn_info = SVN.CaptureInfo('.')
943 if not svn_info: 968 if not svn_info:
944 ErrorExit("Current checkout is unversioned. Please retry with a versioned " 969 ErrorExit("Current checkout is unversioned. Please retry with a versioned "
945 "directory.") 970 "directory.")
946 971
947 if (len(args) == 1): 972 if (len(args) == 1):
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 os.write(handle, text) 1021 os.write(handle, text)
997 os.close(handle) 1022 os.close(handle)
998 1023
999 if not silent: 1024 if not silent:
1000 os.system(GetEditor() + " " + filename) 1025 os.system(GetEditor() + " " + filename)
1001 1026
1002 result = gclient_utils.FileRead(filename, 'r') 1027 result = gclient_utils.FileRead(filename, 'r')
1003 os.remove(filename) 1028 os.remove(filename)
1004 1029
1005 if not result: 1030 if not result:
1006 return 1031 return 0
1007 1032
1008 split_result = result.split(separator1, 1) 1033 split_result = result.split(separator1, 1)
1009 if len(split_result) != 2: 1034 if len(split_result) != 2:
1010 ErrorExit("Don't modify the text starting with ---!\n\n" + result) 1035 ErrorExit("Don't modify the text starting with ---!\n\n" + result)
1011 1036
1012 # Update the CL description if it has changed. 1037 # Update the CL description if it has changed.
1013 new_description = split_result[0] 1038 new_description = split_result[0]
1014 cl_files_text = split_result[1] 1039 cl_files_text = split_result[1]
1015 if new_description != description or override_description: 1040 if new_description != description or override_description:
1016 change_info.description = new_description 1041 change_info.description = new_description
(...skipping 21 matching lines...) Expand all
1038 1063
1039 print change_info.name + " changelist saved." 1064 print change_info.name + " changelist saved."
1040 if change_info.MissingTests(): 1065 if change_info.MissingTests():
1041 Warn("WARNING: " + MISSING_TEST_MSG) 1066 Warn("WARNING: " + MISSING_TEST_MSG)
1042 1067
1043 # Update the Rietveld issue. 1068 # Update the Rietveld issue.
1044 if change_info.issue and change_info.NeedsUpload(): 1069 if change_info.issue and change_info.NeedsUpload():
1045 change_info.UpdateRietveldDescription() 1070 change_info.UpdateRietveldDescription()
1046 change_info.needs_upload = False 1071 change_info.needs_upload = False
1047 change_info.Save() 1072 change_info.Save()
1073 return 0
1048 1074
1049 1075
1050 # Valid extensions for files we want to lint. 1076 def CMDlint(change_info, args):
1051 DEFAULT_LINT_REGEX = r"(.*\.cpp|.*\.cc|.*\.h)"
1052 DEFAULT_LINT_IGNORE_REGEX = r"$^"
1053
1054 def Lint(change_info, args):
1055 """Runs cpplint.py on all the files in |change_info|""" 1077 """Runs cpplint.py on all the files in |change_info|"""
1056 try: 1078 try:
1057 import cpplint 1079 import cpplint
1058 except ImportError: 1080 except ImportError:
1059 ErrorExit("You need to install cpplint.py to lint C++ files.") 1081 ErrorExit("You need to install cpplint.py to lint C++ files.")
1060 1082
1061 # Change the current working directory before calling lint so that it 1083 # Change the current working directory before calling lint so that it
1062 # shows the correct base. 1084 # shows the correct base.
1063 previous_cwd = os.getcwd() 1085 previous_cwd = os.getcwd()
1064 os.chdir(change_info.GetLocalRoot()) 1086 os.chdir(change_info.GetLocalRoot())
(...skipping 13 matching lines...) Expand all
1078 if white_regex.match(filename): 1100 if white_regex.match(filename):
1079 if black_regex.match(filename): 1101 if black_regex.match(filename):
1080 print "Ignoring file %s" % filename 1102 print "Ignoring file %s" % filename
1081 else: 1103 else:
1082 cpplint.ProcessFile(filename, cpplint._cpplint_state.verbose_level) 1104 cpplint.ProcessFile(filename, cpplint._cpplint_state.verbose_level)
1083 else: 1105 else:
1084 print "Skipping file %s" % filename 1106 print "Skipping file %s" % filename
1085 1107
1086 print "Total errors found: %d\n" % cpplint._cpplint_state.error_count 1108 print "Total errors found: %d\n" % cpplint._cpplint_state.error_count
1087 os.chdir(previous_cwd) 1109 os.chdir(previous_cwd)
1110 return 1
1088 1111
1089 1112
1090 def DoPresubmitChecks(change_info, committing, may_prompt): 1113 def DoPresubmitChecks(change_info, committing, may_prompt):
1091 """Imports presubmit, then calls presubmit.DoPresubmitChecks.""" 1114 """Imports presubmit, then calls presubmit.DoPresubmitChecks."""
1092 # Need to import here to avoid circular dependency. 1115 # Need to import here to avoid circular dependency.
1093 import presubmit_support 1116 import presubmit_support
1094 root_presubmit = GetCachedFile('PRESUBMIT.py', use_root=True) 1117 root_presubmit = GetCachedFile('PRESUBMIT.py', use_root=True)
1095 change = presubmit_support.SvnChange(change_info.name, 1118 change = presubmit_support.SvnChange(change_info.name,
1096 change_info.description, 1119 change_info.description,
1097 change_info.GetLocalRoot(), 1120 change_info.GetLocalRoot(),
1098 change_info.GetFiles(), 1121 change_info.GetFiles(),
1099 change_info.issue, 1122 change_info.issue,
1100 change_info.patchset) 1123 change_info.patchset)
1101 result = presubmit_support.DoPresubmitChecks(change=change, 1124 result = presubmit_support.DoPresubmitChecks(change=change,
1102 committing=committing, 1125 committing=committing,
1103 verbose=False, 1126 verbose=False,
1104 output_stream=sys.stdout, 1127 output_stream=sys.stdout,
1105 input_stream=sys.stdin, 1128 input_stream=sys.stdin,
1106 default_presubmit=root_presubmit, 1129 default_presubmit=root_presubmit,
1107 may_prompt=may_prompt) 1130 may_prompt=may_prompt)
1108 if not result and may_prompt: 1131 if not result and may_prompt:
1109 print "\nPresubmit errors, can't continue (use --no_presubmit to bypass)" 1132 print "\nPresubmit errors, can't continue (use --no_presubmit to bypass)"
1110 return result 1133 return result
1111 1134
1112 1135
1113 def Changes(): 1136 def CMDchanges(argv):
1114 """Print all the changelists and their files.""" 1137 """Lists all the changelists and their files."""
1138 __pychecker__ = 'unusednames=argv'
1115 for cl in GetCLs(): 1139 for cl in GetCLs():
1116 change_info = ChangeInfo.Load(cl, GetRepositoryRoot(), True, True) 1140 change_info = ChangeInfo.Load(cl, GetRepositoryRoot(), True, True)
1117 print "\n--- Changelist " + change_info.name + ":" 1141 print "\n--- Changelist " + change_info.name + ":"
1118 for filename in change_info.GetFiles(): 1142 for filename in change_info.GetFiles():
1119 print "".join(filename) 1143 print "".join(filename)
1144 return 0
1120 1145
1121 1146
1122 def DeleteEmptyChangeLists(): 1147 def CMDdeleteempties(argv):
1123 """Delete all changelists that have no files.""" 1148 """Delete all changelists that have no files."""
1149 __pychecker__ = 'unusednames=argv'
1124 print "\n--- Deleting:" 1150 print "\n--- Deleting:"
1125 for cl in GetCLs(): 1151 for cl in GetCLs():
1126 change_info = ChangeInfo.Load(cl, GetRepositoryRoot(), True, True) 1152 change_info = ChangeInfo.Load(cl, GetRepositoryRoot(), True, True)
1127 if not len(change_info._files): 1153 if not len(change_info._files):
1128 print change_info.name 1154 print change_info.name
1129 change_info.Delete() 1155 change_info.Delete()
1156 return 0
1157
1158
1159 def CMDnothave(argv):
1160 """Lists files unknown to Subversion."""
1161 __pychecker__ = 'unusednames=argv'
1162 for filename in UnknownFiles(argv[2:]):
1163 print "? " + "".join(filename)
1164 return 0
1165
1166
1167 def CMDdiff(argv):
1168 """Diffs all files in the changelist."""
1169 __pychecker__ = 'unusednames=argv'
1170 files = GetFilesNotInCL()
1171 print GenerateDiff([x[1] for x in files])
1172 return 0
1173
1174
1175 def CMDsettings(argv):
1176 """Prints code review settings."""
1177 __pychecker__ = 'unusednames=argv'
1178 # Force load settings
1179 GetCodeReviewSetting("UNKNOWN");
1180 del CODEREVIEW_SETTINGS['__just_initialized']
1181 print '\n'.join(("%s: %s" % (str(k), str(v))
1182 for (k,v) in CODEREVIEW_SETTINGS.iteritems()))
1183 return 0
1184
1185
1186 def CMDdescription(change_info, argv):
1187 """Prints the description of the specified change to stdout."""
1188 __pychecker__ = 'unusednames=argv'
1189 print change_info.description
1190 return 0
1191
1192
1193 def CMDdelete(change_info, argv):
1194 """Deletes a changelist."""
1195 __pychecker__ = 'unusednames=argv'
1196 change_info.Delete()
1197 return 0
1198
1199
1200 def CMDtry(change_info, argv):
1201 """Sends the change to the tryserver so a trybot can do a test run on your
1202 code.
1203
1204 To send multiple changes as one path, use a comma-separated list of
1205 changenames. Use 'gcl help try' for more information!"""
1206 # When the change contains no file, send the "changename" positional
1207 # argument to trychange.py.
1208 __pychecker__ = 'unusednames=argv'
1209 if change_info.GetFiles():
1210 args = argv[3:]
1211 else:
1212 change_info = None
1213 args = argv[2:]
1214 TryChange(change_info, args, swallow_exception=False)
1215 return 0
1216
1217
1218 def CMDrename(argv):
1219 """Renames an existing change."""
1220 if len(argv) != 4:
1221 ErrorExit("Usage: gcl rename <old-name> <new-name>.")
1222 src, dst = argv[2:4]
1223 src_file = GetChangelistInfoFile(src)
1224 if not os.path.isfile(src_file):
1225 ErrorExit("Change '%s' does not exist." % src)
1226 dst_file = GetChangelistInfoFile(dst)
1227 if os.path.isfile(dst_file):
1228 ErrorExit("Change '%s' already exists; pick a new name." % dst)
1229 os.rename(src_file, dst_file)
1230 print "Change '%s' renamed '%s'." % (src, dst)
1231 return 0
1130 1232
1131 1233
1132 def main(argv=None): 1234 def main(argv=None):
1235 __pychecker__ = 'maxreturns=0'
1133 if argv is None: 1236 if argv is None:
1134 argv = sys.argv 1237 argv = sys.argv
1135 1238
1136 if len(argv) == 1: 1239 if len(argv) == 1:
1137 Help() 1240 return CMDhelp()
1138 return 0;
1139 1241
1140 try: 1242 try:
1141 # Create the directories where we store information about changelists if it 1243 # Create the directories where we store information about changelists if it
1142 # doesn't exist. 1244 # doesn't exist.
1143 if not os.path.exists(GetInfoDir()): 1245 if not os.path.exists(GetInfoDir()):
1144 os.mkdir(GetInfoDir()) 1246 os.mkdir(GetInfoDir())
1145 if not os.path.exists(GetChangesDir()): 1247 if not os.path.exists(GetChangesDir()):
1146 os.mkdir(GetChangesDir()) 1248 os.mkdir(GetChangesDir())
1147 if not os.path.exists(GetCacheDir()): 1249 if not os.path.exists(GetCacheDir()):
1148 os.mkdir(GetCacheDir()) 1250 os.mkdir(GetCacheDir())
1149 except gclient_utils.Error: 1251 except gclient_utils.Error:
1150 # Will throw an exception if not run in a svn checkout. 1252 # Will throw an exception if not run in a svn checkout.
1151 pass 1253 pass
1152 1254
1153 # Commands that don't require an argument. 1255 # Commands that don't require an argument.
1154 command = argv[1] 1256 command = argv[1]
1155 if command == "opened" or command == "status": 1257 if command == "opened":
1156 Opened(command == "status") 1258 return CMDopened(argv)
1157 return 0 1259 if command == "status":
1260 return CMDstatus(argv)
1158 if command == "nothave": 1261 if command == "nothave":
1159 __pychecker__ = 'no-returnvalues' 1262 return CMDnothave(argv)
1160 for filename in UnknownFiles(argv[2:]):
1161 print "? " + "".join(filename)
1162 return 0
1163 if command == "changes": 1263 if command == "changes":
1164 Changes() 1264 return CMDchanges(argv)
1165 return 0
1166 if command == "help": 1265 if command == "help":
1167 Help(argv[2:]) 1266 return CMDhelp(argv)
1168 return 0
1169 if command == "diff" and len(argv) == 2: 1267 if command == "diff" and len(argv) == 2:
1170 files = GetFilesNotInCL() 1268 return CMDdiff(argv)
1171 print GenerateDiff([x[1] for x in files])
1172 return 0
1173 if command == "settings": 1269 if command == "settings":
1174 # Force load settings 1270 return CMDsettings(argv)
1175 GetCodeReviewSetting("UNKNOWN");
1176 del CODEREVIEW_SETTINGS['__just_initialized']
1177 print '\n'.join(("%s: %s" % (str(k), str(v))
1178 for (k,v) in CODEREVIEW_SETTINGS.iteritems()))
1179 return 0
1180 if command == "deleteempties": 1271 if command == "deleteempties":
1181 DeleteEmptyChangeLists() 1272 return CMDdeleteempties(argv)
1182 return 0
1183
1184 if command == "rename": 1273 if command == "rename":
1185 if len(argv) != 4: 1274 return CMDrename(argv)
1186 ErrorExit("Usage: gcl rename <old-name> <new-name>.")
1187 src, dst = argv[2:4]
1188 src_file = GetChangelistInfoFile(src)
1189 if not os.path.isfile(src_file):
1190 ErrorExit("Change '%s' does not exist." % src)
1191 dst_file = GetChangelistInfoFile(dst)
1192 if os.path.isfile(dst_file):
1193 ErrorExit("Change '%s' already exists; pick a new name." % dst)
1194 os.rename(src_file, dst_file)
1195 print "Change '%s' renamed '%s'." % (src, dst)
1196 return 0
1197 if command == "change": 1275 if command == "change":
1198 if len(argv) == 2: 1276 if len(argv) == 2:
1199 # Generate a random changelist name. 1277 # Generate a random changelist name.
1200 changename = GenerateChangeName() 1278 changename = GenerateChangeName()
1201 elif argv[2] == '--force': 1279 elif argv[2] == '--force':
1202 changename = GenerateChangeName() 1280 changename = GenerateChangeName()
1203 # argv[3:] is passed to Change() as |args| later. Change() should receive 1281 # argv[3:] is passed to Change() as |args| later. Change() should receive
1204 # |args| which includes '--force'. 1282 # |args| which includes '--force'.
1205 argv.insert(2, changename) 1283 argv.insert(2, changename)
1206 else: 1284 else:
1207 changename = argv[2] 1285 changename = argv[2]
1208 elif len(argv) == 2: 1286 elif len(argv) == 2:
1209 ErrorExit("Need a changelist name.") 1287 ErrorExit("Need a changelist name.")
1210 else: 1288 else:
1211 changename = argv[2] 1289 changename = argv[2]
1212 1290
1213 # When the command is 'try' and --patchset is used, the patch to try 1291 # When the command is 'try' and --patchset is used, the patch to try
1214 # is on the Rietveld server. 'change' creates a change so it's fine if the 1292 # is on the Rietveld server. 'change' creates a change so it's fine if the
1215 # change didn't exist. All other commands require an existing change. 1293 # change didn't exist. All other commands require an existing change.
1216 fail_on_not_found = command != "try" and command != "change" 1294 fail_on_not_found = command != "try" and command != "change"
1217 if command == "try" and changename.find(',') != -1: 1295 if command == "try" and changename.find(',') != -1:
1218 change_info = LoadChangelistInfoForMultiple(changename, GetRepositoryRoot(), 1296 change_info = LoadChangelistInfoForMultiple(changename, GetRepositoryRoot(),
1219 True, True) 1297 True, True)
1220 else: 1298 else:
1221 change_info = ChangeInfo.Load(changename, GetRepositoryRoot(), 1299 change_info = ChangeInfo.Load(changename, GetRepositoryRoot(),
1222 fail_on_not_found, True) 1300 fail_on_not_found, True)
1223 1301
1224 if command == "change": 1302 if command == "change":
1225 Change(change_info, argv[3:]) 1303 return CMDchange(change_info, argv[3:])
1226 elif command == "description": 1304 elif command == "description":
1227 print change_info.description 1305 return CMDdescription(change_info, argv[3:])
1228 elif command == "lint": 1306 elif command == "lint":
1229 Lint(change_info, argv[3:]) 1307 return CMDlint(change_info, argv[3:])
1230 elif command == "upload": 1308 elif command == "upload":
1231 UploadCL(change_info, argv[3:]) 1309 return CMDupload(change_info, argv[3:])
1232 elif command == "presubmit": 1310 elif command == "presubmit":
1233 PresubmitCL(change_info) 1311 return CMDpresubmit(change_info, argv[3:])
1234 elif command in ("commit", "submit"): 1312 elif command in ("commit", "submit"):
1235 Commit(change_info, argv[3:]) 1313 return CMDcommit(change_info, argv[3:])
1236 elif command == "delete": 1314 elif command == "delete":
1237 change_info.Delete() 1315 return CMDdelete(change_info, argv[3:])
1238 elif command == "try": 1316 elif command == "try":
1239 # When the change contains no file, send the "changename" positional 1317 return CMDtry(change_info, argv)
1240 # argument to trychange.py.
1241 if change_info.GetFiles():
1242 args = argv[3:]
1243 else:
1244 change_info = None
1245 args = argv[2:]
1246 TryChange(change_info, args, swallow_exception=False)
1247 else: 1318 else:
1248 # Everything else that is passed into gcl we redirect to svn, after adding 1319 # Everything else that is passed into gcl we redirect to svn, after adding
1249 # the files. This allows commands such as 'gcl diff xxx' to work. 1320 # the files. This allows commands such as 'gcl diff xxx' to work.
1250 if command == "diff" and not change_info.GetFileNames(): 1321 if command == "diff" and not change_info.GetFileNames():
1251 return 0 1322 return 0
1252 args =["svn", command] 1323 args =["svn", command]
1253 root = GetRepositoryRoot() 1324 root = GetRepositoryRoot()
1254 args.extend([os.path.join(root, x) for x in change_info.GetFileNames()]) 1325 args.extend([os.path.join(root, x) for x in change_info.GetFileNames()])
1255 RunShell(args, True) 1326 RunShell(args, True)
1256 return 0 1327 return 0
1257 1328
1258 1329
1259 if __name__ == "__main__": 1330 if __name__ == "__main__":
1260 sys.exit(main()) 1331 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | tests/gcl_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698