OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 """\ | 6 """\ |
7 Wrapper script around Rietveld's upload.py that simplifies working with groups | 7 Wrapper script around Rietveld's upload.py that simplifies working with groups |
8 of files. | 8 of files. |
9 """ | 9 """ |
10 | 10 |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 | 226 |
227 | 227 |
228 def ErrorExit(msg): | 228 def ErrorExit(msg): |
229 print >> sys.stderr, msg | 229 print >> sys.stderr, msg |
230 sys.exit(1) | 230 sys.exit(1) |
231 | 231 |
232 | 232 |
233 def RunShellWithReturnCode(command, print_output=False): | 233 def RunShellWithReturnCode(command, print_output=False): |
234 """Executes a command and returns the output and the return code.""" | 234 """Executes a command and returns the output and the return code.""" |
235 p = subprocess2.Popen( | 235 p = subprocess2.Popen( |
236 command, stdout=subprocess2.PIPE, | 236 command, |
237 stderr=subprocess2.STDOUT, universal_newlines=True) | 237 cwd=GetRepositoryRoot(), |
| 238 stdout=subprocess2.PIPE, |
| 239 stderr=subprocess2.STDOUT, |
| 240 universal_newlines=True) |
238 if print_output: | 241 if print_output: |
239 output_array = [] | 242 output_array = [] |
240 while True: | 243 while True: |
241 line = p.stdout.readline() | 244 line = p.stdout.readline() |
242 if not line: | 245 if not line: |
243 break | 246 break |
244 if print_output: | 247 if print_output: |
245 print line.strip('\n') | 248 print line.strip('\n') |
246 output_array.append(line) | 249 output_array.append(line) |
247 output = "".join(output_array) | 250 output = "".join(output_array) |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 status = line[:7] | 609 status = line[:7] |
607 filename = line[7:] | 610 filename = line[7:] |
608 values['files'].append((status, filename)) | 611 values['files'].append((status, filename)) |
609 values['description'] = split_data[2] | 612 values['description'] = split_data[2] |
610 return values | 613 return values |
611 | 614 |
612 @staticmethod | 615 @staticmethod |
613 def _LoadNewFormat(content): | 616 def _LoadNewFormat(content): |
614 return json.loads(content) | 617 return json.loads(content) |
615 | 618 |
| 619 def __str__(self): |
| 620 out = ['%s:' % self.__class__.__name__] |
| 621 for k in dir(self): |
| 622 if k.startswith('__'): |
| 623 continue |
| 624 v = getattr(self, k) |
| 625 if v is self or callable(getattr(self, k)): |
| 626 continue |
| 627 out.append(' %s: %r' % (k, v)) |
| 628 return '\n'.join(out) |
| 629 |
616 | 630 |
617 def GetChangelistInfoFile(changename): | 631 def GetChangelistInfoFile(changename): |
618 """Returns the file that stores information about a changelist.""" | 632 """Returns the file that stores information about a changelist.""" |
619 if not changename or re.search(r'[^\w-]', changename): | 633 if not changename or re.search(r'[^\w-]', changename): |
620 ErrorExit("Invalid changelist name: " + changename) | 634 ErrorExit("Invalid changelist name: " + changename) |
621 return os.path.join(GetChangesDir(), changename) | 635 return os.path.join(GetChangesDir(), changename) |
622 | 636 |
623 | 637 |
624 def LoadChangelistInfoForMultiple(changenames, local_root, fail_on_not_found, | 638 def LoadChangelistInfoForMultiple(changenames, local_root, fail_on_not_found, |
625 update_status): | 639 update_status): |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
672 dir_prefix = os.getcwd()[len(GetRepositoryRoot()):].strip(os.sep) | 686 dir_prefix = os.getcwd()[len(GetRepositoryRoot()):].strip(os.sep) |
673 | 687 |
674 # Get a list of all files in changelists. | 688 # Get a list of all files in changelists. |
675 files_in_cl = {} | 689 files_in_cl = {} |
676 for cl in GetCLs(): | 690 for cl in GetCLs(): |
677 change_info = ChangeInfo.Load(cl, GetRepositoryRoot(), | 691 change_info = ChangeInfo.Load(cl, GetRepositoryRoot(), |
678 fail_on_not_found=True, update_status=False) | 692 fail_on_not_found=True, update_status=False) |
679 for status, filename in change_info.GetFiles(): | 693 for status, filename in change_info.GetFiles(): |
680 files_in_cl[filename] = change_info.name | 694 files_in_cl[filename] = change_info.name |
681 | 695 |
682 # Get all the modified files. | 696 # Get all the modified files down the current directory. |
683 status_result = SVN.CaptureStatus(None, GetRepositoryRoot()) | 697 for line in SVN.CaptureStatus(None, os.getcwd()): |
684 for line in status_result: | |
685 status = line[0] | 698 status = line[0] |
686 filename = line[1] | 699 filename = line[1] |
687 if status[0] == "?": | 700 if status[0] == "?": |
688 continue | 701 continue |
689 if dir_prefix: | 702 if dir_prefix: |
690 filename = os.path.join(dir_prefix, filename) | 703 filename = os.path.join(dir_prefix, filename) |
691 change_list_name = "" | 704 change_list_name = "" |
692 if filename in files_in_cl: | 705 if filename in files_in_cl: |
693 change_list_name = files_in_cl[filename] | 706 change_list_name = files_in_cl[filename] |
694 files.setdefault(change_list_name, []).append((status, filename)) | 707 files.setdefault(change_list_name, []).append((status, filename)) |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 cc_list = ','.join(filter(None, [cc_list] + watchers)) | 890 cc_list = ','.join(filter(None, [cc_list] + watchers)) |
878 if cc_list: | 891 if cc_list: |
879 upload_arg.append("--cc=" + cc_list) | 892 upload_arg.append("--cc=" + cc_list) |
880 upload_arg.append("--description_file=" + desc_file + "") | 893 upload_arg.append("--description_file=" + desc_file + "") |
881 if change_info.subject: | 894 if change_info.subject: |
882 upload_arg.append("--message=" + change_info.subject) | 895 upload_arg.append("--message=" + change_info.subject) |
883 | 896 |
884 if GetCodeReviewSetting("PRIVATE") == "True": | 897 if GetCodeReviewSetting("PRIVATE") == "True": |
885 upload_arg.append("--private") | 898 upload_arg.append("--private") |
886 | 899 |
| 900 # If we have a lot of files with long paths, then we won't be able to fit |
| 901 # the command to "svn diff". Instead, we generate the diff manually for |
| 902 # each file and concatenate them before passing it to upload.py. |
| 903 if change_info.patch is None: |
| 904 change_info.patch = GenerateDiff(change_info.GetFileNames()) |
| 905 |
887 # Change the current working directory before calling upload.py so that it | 906 # Change the current working directory before calling upload.py so that it |
888 # shows the correct base. | 907 # shows the correct base. |
889 previous_cwd = os.getcwd() | 908 previous_cwd = os.getcwd() |
890 os.chdir(change_info.GetLocalRoot()) | 909 os.chdir(change_info.GetLocalRoot()) |
891 # If we have a lot of files with long paths, then we won't be able to fit | |
892 # the command to "svn diff". Instead, we generate the diff manually for | |
893 # each file and concatenate them before passing it to upload.py. | |
894 if change_info.patch is None: | |
895 change_info.patch = GenerateDiff(change_info.GetFileNames()) | |
896 try: | 910 try: |
897 issue, patchset = upload.RealMain(upload_arg, change_info.patch) | 911 try: |
898 except KeyboardInterrupt: | 912 issue, patchset = upload.RealMain(upload_arg, change_info.patch) |
899 sys.exit(1) | 913 except KeyboardInterrupt: |
900 if issue and patchset: | 914 sys.exit(1) |
901 change_info.issue = int(issue) | 915 if issue and patchset: |
902 change_info.patchset = int(patchset) | 916 change_info.issue = int(issue) |
903 change_info.Save() | 917 change_info.patchset = int(patchset) |
| 918 change_info.Save() |
904 | 919 |
905 if desc_file: | 920 if desc_file: |
906 os.remove(desc_file) | 921 os.remove(desc_file) |
907 change_info.PrimeLint() | 922 change_info.PrimeLint() |
908 os.chdir(previous_cwd) | 923 finally: |
| 924 os.chdir(previous_cwd) |
909 print "*** Upload does not submit a try; use gcl try to submit a try. ***" | 925 print "*** Upload does not submit a try; use gcl try to submit a try. ***" |
910 return 0 | 926 return 0 |
911 | 927 |
912 | 928 |
913 @need_change_and_args | 929 @need_change_and_args |
914 @attrs(usage='[--upload]') | 930 @attrs(usage='[--upload]') |
915 def CMDpresubmit(change_info, args): | 931 def CMDpresubmit(change_info, args): |
916 """Runs presubmit checks on the change. | 932 """Runs presubmit checks on the change. |
917 | 933 |
918 The actual presubmit code is implemented in presubmit_support.py and looks | 934 The actual presubmit code is implemented in presubmit_support.py and looks |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 os.write(handle, commit_message) | 1020 os.write(handle, commit_message) |
1005 os.close(handle) | 1021 os.close(handle) |
1006 try: | 1022 try: |
1007 handle, targets_filename = tempfile.mkstemp(text=True) | 1023 handle, targets_filename = tempfile.mkstemp(text=True) |
1008 os.write(handle, "\n".join(change_info.GetFileNames())) | 1024 os.write(handle, "\n".join(change_info.GetFileNames())) |
1009 os.close(handle) | 1025 os.close(handle) |
1010 try: | 1026 try: |
1011 commit_cmd += ['--file=' + commit_filename] | 1027 commit_cmd += ['--file=' + commit_filename] |
1012 commit_cmd += ['--targets=' + targets_filename] | 1028 commit_cmd += ['--targets=' + targets_filename] |
1013 # Change the current working directory before calling commit. | 1029 # Change the current working directory before calling commit. |
1014 previous_cwd = os.getcwd() | |
1015 os.chdir(change_info.GetLocalRoot()) | |
1016 output = '' | 1030 output = '' |
1017 try: | 1031 try: |
1018 output = RunShell(commit_cmd, True) | 1032 output = RunShell(commit_cmd, True) |
1019 except subprocess2.CalledProcessError, e: | 1033 except subprocess2.CalledProcessError, e: |
1020 ErrorExit('Commit failed.\n%s' % e) | 1034 ErrorExit('Commit failed.\n%s' % e) |
1021 finally: | 1035 finally: |
1022 os.remove(commit_filename) | 1036 os.remove(commit_filename) |
1023 finally: | 1037 finally: |
1024 os.remove(targets_filename) | 1038 os.remove(targets_filename) |
1025 if output.find("Committed revision") != -1: | 1039 if output.find("Committed revision") != -1: |
1026 change_info.Delete() | 1040 change_info.Delete() |
1027 | 1041 |
1028 if change_info.issue: | 1042 if change_info.issue: |
1029 revision = re.compile(".*?\nCommitted revision (\d+)", | 1043 revision = re.compile(".*?\nCommitted revision (\d+)", |
1030 re.DOTALL).match(output).group(1) | 1044 re.DOTALL).match(output).group(1) |
1031 viewvc_url = GetCodeReviewSetting("VIEW_VC") | 1045 viewvc_url = GetCodeReviewSetting("VIEW_VC") |
1032 change_info.description += '\n' | 1046 change_info.description += '\n' |
1033 if viewvc_url: | 1047 if viewvc_url: |
1034 change_info.description += "\nCommitted: " + viewvc_url + revision | 1048 change_info.description += "\nCommitted: " + viewvc_url + revision |
1035 change_info.CloseIssue() | 1049 change_info.CloseIssue() |
1036 os.chdir(previous_cwd) | |
1037 return 0 | 1050 return 0 |
1038 | 1051 |
1039 | 1052 |
1040 def CMDchange(args): | 1053 def CMDchange(args): |
1041 """Creates or edits a changelist. | 1054 """Creates or edits a changelist. |
1042 | 1055 |
1043 Only scans the current directory and subdirectories. | 1056 Only scans the current directory and subdirectories. |
1044 """ | 1057 """ |
1045 # Verify the user is running the change command from a read-write checkout. | 1058 # Verify the user is running the change command from a read-write checkout. |
1046 svn_info = SVN.CaptureLocalInfo([], '.') | 1059 svn_info = SVN.CaptureLocalInfo([], '.') |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 change_info.Save() | 1168 change_info.Save() |
1156 return 0 | 1169 return 0 |
1157 | 1170 |
1158 | 1171 |
1159 @need_change_and_args | 1172 @need_change_and_args |
1160 def CMDlint(change_info, args): | 1173 def CMDlint(change_info, args): |
1161 """Runs cpplint.py on all the files in the change list. | 1174 """Runs cpplint.py on all the files in the change list. |
1162 | 1175 |
1163 Checks all the files in the changelist for possible style violations. | 1176 Checks all the files in the changelist for possible style violations. |
1164 """ | 1177 """ |
| 1178 # Access to a protected member _XX of a client class |
| 1179 # pylint: disable=W0212 |
1165 try: | 1180 try: |
1166 import cpplint | 1181 import cpplint |
1167 import cpplint_chromium | 1182 import cpplint_chromium |
1168 except ImportError: | 1183 except ImportError: |
1169 ErrorExit("You need to install cpplint.py to lint C++ files.") | 1184 ErrorExit("You need to install cpplint.py to lint C++ files.") |
1170 # Change the current working directory before calling lint so that it | 1185 # Change the current working directory before calling lint so that it |
1171 # shows the correct base. | 1186 # shows the correct base. |
1172 previous_cwd = os.getcwd() | 1187 previous_cwd = os.getcwd() |
1173 os.chdir(change_info.GetLocalRoot()) | 1188 os.chdir(change_info.GetLocalRoot()) |
1174 # Process cpplints arguments if any. | 1189 try: |
1175 filenames = cpplint.ParseArguments(args + change_info.GetFileNames()) | 1190 # Process cpplints arguments if any. |
| 1191 filenames = cpplint.ParseArguments(args + change_info.GetFileNames()) |
1176 | 1192 |
1177 white_list = GetCodeReviewSetting("LINT_REGEX") | 1193 white_list = GetCodeReviewSetting("LINT_REGEX") |
1178 if not white_list: | 1194 if not white_list: |
1179 white_list = DEFAULT_LINT_REGEX | 1195 white_list = DEFAULT_LINT_REGEX |
1180 white_regex = re.compile(white_list) | 1196 white_regex = re.compile(white_list) |
1181 black_list = GetCodeReviewSetting("LINT_IGNORE_REGEX") | 1197 black_list = GetCodeReviewSetting("LINT_IGNORE_REGEX") |
1182 if not black_list: | 1198 if not black_list: |
1183 black_list = DEFAULT_LINT_IGNORE_REGEX | 1199 black_list = DEFAULT_LINT_IGNORE_REGEX |
1184 black_regex = re.compile(black_list) | 1200 black_regex = re.compile(black_list) |
1185 extra_check_functions = [cpplint_chromium.CheckPointerDeclarationWhitespace] | 1201 extra_check_functions = [cpplint_chromium.CheckPointerDeclarationWhitespace] |
1186 # Access to a protected member _XX of a client class | 1202 for filename in filenames: |
1187 # pylint: disable=W0212 | 1203 if white_regex.match(filename): |
1188 for filename in filenames: | 1204 if black_regex.match(filename): |
1189 if white_regex.match(filename): | 1205 print "Ignoring file %s" % filename |
1190 if black_regex.match(filename): | 1206 else: |
1191 print "Ignoring file %s" % filename | 1207 cpplint.ProcessFile(filename, cpplint._cpplint_state.verbose_level, |
| 1208 extra_check_functions) |
1192 else: | 1209 else: |
1193 cpplint.ProcessFile(filename, cpplint._cpplint_state.verbose_level, | 1210 print "Skipping file %s" % filename |
1194 extra_check_functions) | 1211 finally: |
1195 else: | 1212 os.chdir(previous_cwd) |
1196 print "Skipping file %s" % filename | |
1197 | 1213 |
1198 print "Total errors found: %d\n" % cpplint._cpplint_state.error_count | 1214 print "Total errors found: %d\n" % cpplint._cpplint_state.error_count |
1199 os.chdir(previous_cwd) | |
1200 return 1 | 1215 return 1 |
1201 | 1216 |
1202 | 1217 |
1203 def DoPresubmitChecks(change_info, committing, may_prompt): | 1218 def DoPresubmitChecks(change_info, committing, may_prompt): |
1204 """Imports presubmit, then calls presubmit.DoPresubmitChecks.""" | 1219 """Imports presubmit, then calls presubmit.DoPresubmitChecks.""" |
1205 root_presubmit = GetCachedFile('PRESUBMIT.py', use_root=True) | 1220 root_presubmit = GetCachedFile('PRESUBMIT.py', use_root=True) |
1206 change = presubmit_support.SvnChange(change_info.name, | 1221 change = presubmit_support.SvnChange(change_info.name, |
1207 change_info.description, | 1222 change_info.description, |
1208 change_info.GetLocalRoot(), | 1223 change_info.GetLocalRoot(), |
1209 change_info.GetFiles(), | 1224 change_info.GetFiles(), |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1449 raise | 1464 raise |
1450 print >> sys.stderr, ( | 1465 print >> sys.stderr, ( |
1451 'AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' | 1466 'AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' |
1452 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e)) | 1467 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e)) |
1453 return 1 | 1468 return 1 |
1454 | 1469 |
1455 | 1470 |
1456 if __name__ == "__main__": | 1471 if __name__ == "__main__": |
1457 fix_encoding.fix_encoding() | 1472 fix_encoding.fix_encoding() |
1458 sys.exit(main(sys.argv[1:])) | 1473 sys.exit(main(sys.argv[1:])) |
OLD | NEW |