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

Side by Side Diff: gcl.py

Issue 119442: A step closer to make presubmit SCM independent. (Closed)
Patch Set: oops Created 11 years, 6 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 | presubmit_support.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
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 # _SEPARATOR\n 279 # _SEPARATOR\n
280 # description 280 # description
281 281
282 def __init__(self, name, issue, patchset, description, files): 282 def __init__(self, name, issue, patchset, description, files):
283 self.name = name 283 self.name = name
284 self.issue = int(issue) 284 self.issue = int(issue)
285 self.patchset = int(patchset) 285 self.patchset = int(patchset)
286 self.description = description 286 self.description = description
287 if files is None: 287 if files is None:
288 files = [] 288 files = []
289 self.files = files 289 self._files = files
290 self.patch = None 290 self.patch = None
291 self._local_root = GetRepositoryRoot()
291 292
292 def FileList(self): 293 def GetFileNames(self):
293 """Returns a list of files.""" 294 """Returns the list of file names included in this change."""
294 return [file[1] for file in self.files] 295 return [file[1] for file in self._files]
296
297 def GetFiles(self):
298 """Returns the list of files included in this change with their status."""
299 return self._files
300
301 def GetLocalRoot(self):
302 """Returns the local repository checkout root directory."""
303 return self._local_root
295 304
296 def _NonDeletedFileList(self): 305 def _NonDeletedFileList(self):
297 """Returns a list of files in this change, not including deleted files.""" 306 """Returns a list of files in this change, not including deleted files."""
298 return [file[1] for file in self.files if not file[0].startswith("D")] 307 return [file[1] for file in self.GetFiles()
308 if not file[0].startswith("D")]
299 309
300 def _AddedFileList(self): 310 def _AddedFileList(self):
301 """Returns a list of files added in this change.""" 311 """Returns a list of files added in this change."""
302 return [file[1] for file in self.files if file[0].startswith("A")] 312 return [file[1] for file in self.GetFiles() if file[0].startswith("A")]
303 313
304 def Save(self): 314 def Save(self):
305 """Writes the changelist information to disk.""" 315 """Writes the changelist information to disk."""
306 data = ChangeInfo._SEPARATOR.join([ 316 data = ChangeInfo._SEPARATOR.join([
307 "%d, %d" % (self.issue, self.patchset), 317 "%d, %d" % (self.issue, self.patchset),
308 "\n".join([f[0] + f[1] for f in self.files]), 318 "\n".join([f[0] + f[1] for f in self.GetFiles()]),
309 self.description]) 319 self.description])
310 WriteFile(GetChangelistInfoFile(self.name), data) 320 WriteFile(GetChangelistInfoFile(self.name), data)
311 321
312 def Delete(self): 322 def Delete(self):
313 """Removes the changelist information from disk.""" 323 """Removes the changelist information from disk."""
314 os.remove(GetChangelistInfoFile(self.name)) 324 os.remove(GetChangelistInfoFile(self.name))
315 325
316 def CloseIssue(self): 326 def CloseIssue(self):
317 """Closes the Rietveld issue for this changelist.""" 327 """Closes the Rietveld issue for this changelist."""
318 data = [("description", self.description),] 328 data = [("description", self.description),]
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 380
371 Inline methods added to header files won't be detected by this. That's 381 Inline methods added to header files won't be detected by this. That's
372 acceptable for purposes of determining if a unit test is needed, since 382 acceptable for purposes of determining if a unit test is needed, since
373 inline methods should be trivial. 383 inline methods should be trivial.
374 """ 384 """
375 # To check for methods added to source or header files, we need the diffs. 385 # To check for methods added to source or header files, we need the diffs.
376 # We'll generate them all, since there aren't likely to be many files 386 # We'll generate them all, since there aren't likely to be many files
377 # apart from source and headers; besides, we'll want them all if we're 387 # apart from source and headers; besides, we'll want them all if we're
378 # uploading anyway. 388 # uploading anyway.
379 if self.patch is None: 389 if self.patch is None:
380 self.patch = GenerateDiff(self.FileList()) 390 self.patch = GenerateDiff(self.GetFileNames())
381 391
382 definition = "" 392 definition = ""
383 for line in self.patch.splitlines(): 393 for line in self.patch.splitlines():
384 if not line.startswith("+"): 394 if not line.startswith("+"):
385 continue 395 continue
386 line = line.strip("+").rstrip(" \t") 396 line = line.strip("+").rstrip(" \t")
387 # Skip empty lines, comments, and preprocessor directives. 397 # Skip empty lines, comments, and preprocessor directives.
388 # TODO(pamg): Handle multiline comments if it turns out to be a problem. 398 # TODO(pamg): Handle multiline comments if it turns out to be a problem.
389 if line == "" or line.startswith("/") or line.startswith("#"): 399 if line == "" or line.startswith("/") or line.startswith("#"):
390 continue 400 continue
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 478
469 def LoadChangelistInfoForMultiple(changenames, fail_on_not_found=True, 479 def LoadChangelistInfoForMultiple(changenames, fail_on_not_found=True,
470 update_status=False): 480 update_status=False):
471 """Loads many changes and merge their files list into one pseudo change. 481 """Loads many changes and merge their files list into one pseudo change.
472 482
473 This is mainly usefull to concatenate many changes into one for a 'gcl try'. 483 This is mainly usefull to concatenate many changes into one for a 'gcl try'.
474 """ 484 """
475 changes = changenames.split(',') 485 changes = changenames.split(',')
476 aggregate_change_info = ChangeInfo(changenames, 0, 0, '', None) 486 aggregate_change_info = ChangeInfo(changenames, 0, 0, '', None)
477 for change in changes: 487 for change in changes:
478 aggregate_change_info.files += ChangeInfo.Load(change, fail_on_not_found, 488 aggregate_change_info._files += ChangeInfo.Load(change, fail_on_not_found,
479 update_status).files 489 update_status).GetFiles()
480 return aggregate_change_info 490 return aggregate_change_info
481 491
482 492
483 def GetCLs(): 493 def GetCLs():
484 """Returns a list of all the changelists in this repository.""" 494 """Returns a list of all the changelists in this repository."""
485 cls = os.listdir(GetChangesDir()) 495 cls = os.listdir(GetChangesDir())
486 if CODEREVIEW_SETTINGS_FILE in cls: 496 if CODEREVIEW_SETTINGS_FILE in cls:
487 cls.remove(CODEREVIEW_SETTINGS_FILE) 497 cls.remove(CODEREVIEW_SETTINGS_FILE)
488 return cls 498 return cls
489 499
(...skipping 22 matching lines...) Expand all
512 files = {} 522 files = {}
513 523
514 # Since the files are normalized to the root folder of the repositary, figure 524 # Since the files are normalized to the root folder of the repositary, figure
515 # out what we need to add to the paths. 525 # out what we need to add to the paths.
516 dir_prefix = os.getcwd()[len(GetRepositoryRoot()):].strip(os.sep) 526 dir_prefix = os.getcwd()[len(GetRepositoryRoot()):].strip(os.sep)
517 527
518 # Get a list of all files in changelists. 528 # Get a list of all files in changelists.
519 files_in_cl = {} 529 files_in_cl = {}
520 for cl in GetCLs(): 530 for cl in GetCLs():
521 change_info = ChangeInfo.Load(cl) 531 change_info = ChangeInfo.Load(cl)
522 for status, filename in change_info.files: 532 for status, filename in change_info.GetFiles():
523 files_in_cl[filename] = change_info.name 533 files_in_cl[filename] = change_info.name
524 534
525 # Get all the modified files. 535 # Get all the modified files.
526 status_result = gclient.CaptureSVNStatus(None) 536 status_result = gclient.CaptureSVNStatus(None)
527 for line in status_result: 537 for line in status_result:
528 status = line[0] 538 status = line[0]
529 filename = line[1] 539 filename = line[1]
530 if status[0] == "?": 540 if status[0] == "?":
531 continue 541 continue
532 if dir_prefix: 542 if dir_prefix:
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 590
581 591
582 def Opened(): 592 def Opened():
583 """Prints a list of modified files in the current directory down.""" 593 """Prints a list of modified files in the current directory down."""
584 files = GetModifiedFiles() 594 files = GetModifiedFiles()
585 cl_keys = files.keys() 595 cl_keys = files.keys()
586 cl_keys.sort() 596 cl_keys.sort()
587 for cl_name in cl_keys: 597 for cl_name in cl_keys:
588 if cl_name: 598 if cl_name:
589 note = "" 599 note = ""
590 if len(ChangeInfo.Load(cl_name).files) != len(files[cl_name]): 600 if len(ChangeInfo.Load(cl_name).GetFiles()) != len(files[cl_name]):
591 note = " (Note: this changelist contains files outside this directory)" 601 note = " (Note: this changelist contains files outside this directory)"
592 print "\n--- Changelist " + cl_name + note + ":" 602 print "\n--- Changelist " + cl_name + note + ":"
593 for file in files[cl_name]: 603 for file in files[cl_name]:
594 print "".join(file) 604 print "".join(file)
595 605
596 606
597 def Help(argv=None): 607 def Help(argv=None):
598 if argv: 608 if argv:
599 if argv[0] == 'try': 609 if argv[0] == 'try':
600 TryChange(None, ['--help'], swallow_exception=False) 610 TryChange(None, ['--help'], swallow_exception=False)
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 736
727 737
728 738
729 def OptionallyDoPresubmitChecks(change_info, committing, args): 739 def OptionallyDoPresubmitChecks(change_info, committing, args):
730 if FilterFlag(args, "--no_presubmit") or FilterFlag(args, "--force"): 740 if FilterFlag(args, "--no_presubmit") or FilterFlag(args, "--force"):
731 return True 741 return True
732 return DoPresubmitChecks(change_info, committing, True) 742 return DoPresubmitChecks(change_info, committing, True)
733 743
734 744
735 def UploadCL(change_info, args): 745 def UploadCL(change_info, args):
736 if not change_info.FileList(): 746 if not change_info.GetFiles():
737 print "Nothing to upload, changelist is empty." 747 print "Nothing to upload, changelist is empty."
738 return 748 return
739 if not OptionallyDoPresubmitChecks(change_info, False, args): 749 if not OptionallyDoPresubmitChecks(change_info, False, args):
740 return 750 return
741 no_try = FilterFlag(args, "--no_try") or FilterFlag(args, "--no-try") 751 no_try = FilterFlag(args, "--no_try") or FilterFlag(args, "--no-try")
742 no_watchlists = FilterFlag(args, "--no_watchlists") or \ 752 no_watchlists = FilterFlag(args, "--no_watchlists") or \
743 FilterFlag(args, "--no-watchlists") 753 FilterFlag(args, "--no-watchlists")
744 754
745 # Map --send-mail to --send_mail 755 # Map --send-mail to --send_mail
746 if FilterFlag(args, "--send-mail"): 756 if FilterFlag(args, "--send-mail"):
(...skipping 28 matching lines...) Expand all
775 upload_arg.append("--issue=%d" % change_info.issue) 785 upload_arg.append("--issue=%d" % change_info.issue)
776 else: # First time we upload. 786 else: # First time we upload.
777 handle, desc_file = tempfile.mkstemp(text=True) 787 handle, desc_file = tempfile.mkstemp(text=True)
778 os.write(handle, change_info.description) 788 os.write(handle, change_info.description)
779 os.close(handle) 789 os.close(handle)
780 790
781 # Watchlist processing -- CC people interested in this changeset 791 # Watchlist processing -- CC people interested in this changeset
782 # http://dev.chromium.org/developers/contributing-code/watchlists 792 # http://dev.chromium.org/developers/contributing-code/watchlists
783 if not no_watchlists: 793 if not no_watchlists:
784 import watchlists 794 import watchlists
785 watchlist = watchlists.Watchlists(GetRepositoryRoot()) 795 watchlist = watchlists.Watchlists(change_info.GetLocalRoot())
786 watchers = watchlist.GetWatchersForPaths(change_info.FileList()) 796 watchers = watchlist.GetWatchersForPaths(change_info.FileList())
787 797
788 cc_list = GetCodeReviewSetting("CC_LIST") 798 cc_list = GetCodeReviewSetting("CC_LIST")
789 if not no_watchlists and watchers: 799 if not no_watchlists and watchers:
790 # Filter out all empty elements and join by ',' 800 # Filter out all empty elements and join by ','
791 cc_list = ','.join(filter(None, [cc_list] + watchers)) 801 cc_list = ','.join(filter(None, [cc_list] + watchers))
792 if cc_list: 802 if cc_list:
793 upload_arg.append("--cc=" + cc_list) 803 upload_arg.append("--cc=" + cc_list)
794 upload_arg.append("--description_file=" + desc_file + "") 804 upload_arg.append("--description_file=" + desc_file + "")
795 if change_info.description: 805 if change_info.description:
796 subject = change_info.description[:77] 806 subject = change_info.description[:77]
797 if subject.find("\r\n") != -1: 807 if subject.find("\r\n") != -1:
798 subject = subject[:subject.find("\r\n")] 808 subject = subject[:subject.find("\r\n")]
799 if subject.find("\n") != -1: 809 if subject.find("\n") != -1:
800 subject = subject[:subject.find("\n")] 810 subject = subject[:subject.find("\n")]
801 if len(change_info.description) > 77: 811 if len(change_info.description) > 77:
802 subject = subject + "..." 812 subject = subject + "..."
803 upload_arg.append("--message=" + subject) 813 upload_arg.append("--message=" + subject)
804 814
805 # Change the current working directory before calling upload.py so that it 815 # Change the current working directory before calling upload.py so that it
806 # shows the correct base. 816 # shows the correct base.
807 previous_cwd = os.getcwd() 817 previous_cwd = os.getcwd()
808 os.chdir(GetRepositoryRoot()) 818 os.chdir(change_info.GetLocalRoot())
809 819
810 # If we have a lot of files with long paths, then we won't be able to fit 820 # If we have a lot of files with long paths, then we won't be able to fit
811 # the command to "svn diff". Instead, we generate the diff manually for 821 # the command to "svn diff". Instead, we generate the diff manually for
812 # each file and concatenate them before passing it to upload.py. 822 # each file and concatenate them before passing it to upload.py.
813 if change_info.patch is None: 823 if change_info.patch is None:
814 change_info.patch = GenerateDiff(change_info.FileList()) 824 change_info.patch = GenerateDiff(change_info.GetFileNames())
815 issue, patchset = upload.RealMain(upload_arg, change_info.patch) 825 issue, patchset = upload.RealMain(upload_arg, change_info.patch)
816 if issue and patchset: 826 if issue and patchset:
817 change_info.issue = int(issue) 827 change_info.issue = int(issue)
818 change_info.patchset = int(patchset) 828 change_info.patchset = int(patchset)
819 change_info.Save() 829 change_info.Save()
820 830
821 if desc_file: 831 if desc_file:
822 os.remove(desc_file) 832 os.remove(desc_file)
823 833
824 # Do background work on Rietveld to lint the file so that the results are 834 # Do background work on Rietveld to lint the file so that the results are
825 # ready when the issue is viewed. 835 # ready when the issue is viewed.
826 SendToRietveld("/lint/issue%s_%s" % (issue, patchset), timeout=0.5) 836 SendToRietveld("/lint/issue%s_%s" % (issue, patchset), timeout=0.5)
827 837
828 # Once uploaded to Rietveld, send it to the try server. 838 # Once uploaded to Rietveld, send it to the try server.
829 if not no_try: 839 if not no_try:
830 try_on_upload = GetCodeReviewSetting('TRY_ON_UPLOAD') 840 try_on_upload = GetCodeReviewSetting('TRY_ON_UPLOAD')
831 if try_on_upload and try_on_upload.lower() == 'true': 841 if try_on_upload and try_on_upload.lower() == 'true':
832 trychange_args = [] 842 trychange_args = []
833 if clobber: 843 if clobber:
834 trychange_args.append('--clobber') 844 trychange_args.append('--clobber')
835 TryChange(change_info, trychange_args, swallow_exception=True) 845 TryChange(change_info, trychange_args, swallow_exception=True)
836 846
837 os.chdir(previous_cwd) 847 os.chdir(previous_cwd)
838 848
839 849
840 def PresubmitCL(change_info): 850 def PresubmitCL(change_info):
841 """Reports what presubmit checks on the change would report.""" 851 """Reports what presubmit checks on the change would report."""
842 if not change_info.FileList(): 852 if not change_info.GetFiles():
843 print "Nothing to presubmit check, changelist is empty." 853 print "Nothing to presubmit check, changelist is empty."
844 return 854 return
845 855
846 print "*** Presubmit checks for UPLOAD would report: ***" 856 print "*** Presubmit checks for UPLOAD would report: ***"
847 DoPresubmitChecks(change_info, False, False) 857 DoPresubmitChecks(change_info, False, False)
848 858
849 print "\n*** Presubmit checks for COMMIT would report: ***" 859 print "\n*** Presubmit checks for COMMIT would report: ***"
850 DoPresubmitChecks(change_info, True, False) 860 DoPresubmitChecks(change_info, True, False)
851 861
852 862
853 def TryChange(change_info, args, swallow_exception): 863 def TryChange(change_info, args, swallow_exception):
854 """Create a diff file of change_info and send it to the try server.""" 864 """Create a diff file of change_info and send it to the try server."""
855 try: 865 try:
856 import trychange 866 import trychange
857 except ImportError: 867 except ImportError:
858 if swallow_exception: 868 if swallow_exception:
859 return 869 return
860 ErrorExit("You need to install trychange.py to use the try server.") 870 ErrorExit("You need to install trychange.py to use the try server.")
861 871
862 if change_info: 872 if change_info:
863 trychange_args = ['--name', change_info.name] 873 trychange_args = ['--name', change_info.name]
864 if change_info.issue: 874 if change_info.issue:
865 trychange_args.extend(["--issue", str(change_info.issue)]) 875 trychange_args.extend(["--issue", str(change_info.issue)])
866 if change_info.patchset: 876 if change_info.patchset:
867 trychange_args.extend(["--patchset", str(change_info.patchset)]) 877 trychange_args.extend(["--patchset", str(change_info.patchset)])
868 trychange_args.extend(args) 878 trychange_args.extend(args)
869 trychange.TryChange(trychange_args, 879 trychange.TryChange(trychange_args,
870 file_list=change_info.FileList(), 880 file_list=change_info.GetFileNames(),
871 swallow_exception=swallow_exception, 881 swallow_exception=swallow_exception,
872 prog='gcl try') 882 prog='gcl try')
873 else: 883 else:
874 trychange.TryChange(args, 884 trychange.TryChange(args,
875 file_list=None, 885 file_list=None,
876 swallow_exception=swallow_exception, 886 swallow_exception=swallow_exception,
877 prog='gcl try') 887 prog='gcl try')
878 888
879 889
880 def Commit(change_info, args): 890 def Commit(change_info, args):
881 if not change_info.FileList(): 891 if not change_info.GetFiles():
882 print "Nothing to commit, changelist is empty." 892 print "Nothing to commit, changelist is empty."
883 return 893 return
884 if not OptionallyDoPresubmitChecks(change_info, True, args): 894 if not OptionallyDoPresubmitChecks(change_info, True, args):
885 return 895 return
886 896
887 # We face a problem with svn here: Let's say change 'bleh' modifies 897 # We face a problem with svn here: Let's say change 'bleh' modifies
888 # svn:ignore on dir1\. but another unrelated change 'pouet' modifies 898 # svn:ignore on dir1\. but another unrelated change 'pouet' modifies
889 # dir1\foo.cc. When the user `gcl commit bleh`, foo.cc is *also committed*. 899 # dir1\foo.cc. When the user `gcl commit bleh`, foo.cc is *also committed*.
890 # The only fix is to use --non-recursive but that has its issues too: 900 # The only fix is to use --non-recursive but that has its issues too:
891 # Let's say if dir1 is deleted, --non-recursive must *not* be used otherwise 901 # Let's say if dir1 is deleted, --non-recursive must *not* be used otherwise
892 # you'll get "svn: Cannot non-recursively commit a directory deletion of a 902 # you'll get "svn: Cannot non-recursively commit a directory deletion of a
893 # directory with child nodes". Yay... 903 # directory with child nodes". Yay...
894 commit_cmd = ["svn", "commit"] 904 commit_cmd = ["svn", "commit"]
895 filename = '' 905 filename = ''
896 if change_info.issue: 906 if change_info.issue:
897 # Get the latest description from Rietveld. 907 # Get the latest description from Rietveld.
898 change_info.description = GetIssueDescription(change_info.issue) 908 change_info.description = GetIssueDescription(change_info.issue)
899 909
900 commit_message = change_info.description.replace('\r\n', '\n') 910 commit_message = change_info.description.replace('\r\n', '\n')
901 if change_info.issue: 911 if change_info.issue:
902 commit_message += ('\nReview URL: http://%s/%d' % 912 commit_message += ('\nReview URL: http://%s/%d' %
903 (GetCodeReviewSetting("CODE_REVIEW_SERVER"), 913 (GetCodeReviewSetting("CODE_REVIEW_SERVER"),
904 change_info.issue)) 914 change_info.issue))
905 915
906 handle, commit_filename = tempfile.mkstemp(text=True) 916 handle, commit_filename = tempfile.mkstemp(text=True)
907 os.write(handle, commit_message) 917 os.write(handle, commit_message)
908 os.close(handle) 918 os.close(handle)
909 919
910 handle, targets_filename = tempfile.mkstemp(text=True) 920 handle, targets_filename = tempfile.mkstemp(text=True)
911 os.write(handle, "\n".join(change_info.FileList())) 921 os.write(handle, "\n".join(change_info.GetFileNames()))
912 os.close(handle) 922 os.close(handle)
913 923
914 commit_cmd += ['--file=' + commit_filename] 924 commit_cmd += ['--file=' + commit_filename]
915 commit_cmd += ['--targets=' + targets_filename] 925 commit_cmd += ['--targets=' + targets_filename]
916 # Change the current working directory before calling commit. 926 # Change the current working directory before calling commit.
917 previous_cwd = os.getcwd() 927 previous_cwd = os.getcwd()
918 os.chdir(GetRepositoryRoot()) 928 os.chdir(change_info.GetLocalRoot())
919 output = RunShell(commit_cmd, True) 929 output = RunShell(commit_cmd, True)
920 os.remove(commit_filename) 930 os.remove(commit_filename)
921 os.remove(targets_filename) 931 os.remove(targets_filename)
922 if output.find("Committed revision") != -1: 932 if output.find("Committed revision") != -1:
923 change_info.Delete() 933 change_info.Delete()
924 934
925 if change_info.issue: 935 if change_info.issue:
926 revision = re.compile(".*?\nCommitted revision (\d+)", 936 revision = re.compile(".*?\nCommitted revision (\d+)",
927 re.DOTALL).match(output).group(1) 937 re.DOTALL).match(output).group(1)
928 viewvc_url = GetCodeReviewSetting("VIEW_VC") 938 viewvc_url = GetCodeReviewSetting("VIEW_VC")
(...skipping 25 matching lines...) Expand all
954 964
955 other_files = GetFilesNotInCL() 965 other_files = GetFilesNotInCL()
956 966
957 #Edited files will have a letter for the first character in a string. 967 #Edited files will have a letter for the first character in a string.
958 #This regex looks for the presence of that character. 968 #This regex looks for the presence of that character.
959 file_re = re.compile(r"^[a-z].+\Z", re.IGNORECASE) 969 file_re = re.compile(r"^[a-z].+\Z", re.IGNORECASE)
960 affected_files = filter(lambda x: file_re.match(x[0]), other_files) 970 affected_files = filter(lambda x: file_re.match(x[0]), other_files)
961 unaffected_files = filter(lambda x: not file_re.match(x[0]), other_files) 971 unaffected_files = filter(lambda x: not file_re.match(x[0]), other_files)
962 972
963 separator1 = ("\n---All lines above this line become the description.\n" 973 separator1 = ("\n---All lines above this line become the description.\n"
964 "---Repository Root: " + GetRepositoryRoot() + "\n" 974 "---Repository Root: " + change_info.GetLocalRoot() + "\n"
965 "---Paths in this changelist (" + change_info.name + "):\n") 975 "---Paths in this changelist (" + change_info.name + "):\n")
966 separator2 = "\n\n---Paths modified but not in any changelist:\n\n" 976 separator2 = "\n\n---Paths modified but not in any changelist:\n\n"
967 text = (description + separator1 + '\n' + 977 text = (description + separator1 + '\n' +
968 '\n'.join([f[0] + f[1] for f in change_info.files]) + separator2 + 978 '\n'.join([f[0] + f[1] for f in change_info.GetFiles()]) +
979 separator2 +
969 '\n'.join([f[0] + f[1] for f in affected_files]) + '\n' + 980 '\n'.join([f[0] + f[1] for f in affected_files]) + '\n' +
970 '\n'.join([f[0] + f[1] for f in unaffected_files]) + '\n') 981 '\n'.join([f[0] + f[1] for f in unaffected_files]) + '\n')
971 982
972 handle, filename = tempfile.mkstemp(text=True) 983 handle, filename = tempfile.mkstemp(text=True)
973 os.write(handle, text) 984 os.write(handle, text)
974 os.close(handle) 985 os.close(handle)
975 986
976 os.system(GetEditor() + " " + filename) 987 os.system(GetEditor() + " " + filename)
977 988
978 result = ReadFile(filename) 989 result = ReadFile(filename)
(...skipping 16 matching lines...) Expand all
995 1006
996 new_cl_files = [] 1007 new_cl_files = []
997 for line in cl_files_text.splitlines(): 1008 for line in cl_files_text.splitlines():
998 if not len(line): 1009 if not len(line):
999 continue 1010 continue
1000 if line.startswith("---"): 1011 if line.startswith("---"):
1001 break 1012 break
1002 status = line[:7] 1013 status = line[:7]
1003 file = line[7:] 1014 file = line[7:]
1004 new_cl_files.append((status, file)) 1015 new_cl_files.append((status, file))
1005 change_info.files = new_cl_files 1016 change_info._files = new_cl_files
1006 1017
1007 change_info.Save() 1018 change_info.Save()
1008 print change_info.name + " changelist saved." 1019 print change_info.name + " changelist saved."
1009 if change_info.MissingTests(): 1020 if change_info.MissingTests():
1010 Warn("WARNING: " + MISSING_TEST_MSG) 1021 Warn("WARNING: " + MISSING_TEST_MSG)
1011 1022
1012 # We don't lint files in these path prefixes. 1023 # We don't lint files in these path prefixes.
1013 IGNORE_PATHS = ("webkit",) 1024 IGNORE_PATHS = ("webkit",)
1014 1025
1015 # Valid extensions for files we want to lint. 1026 # Valid extensions for files we want to lint.
1016 CPP_EXTENSIONS = ("cpp", "cc", "h") 1027 CPP_EXTENSIONS = ("cpp", "cc", "h")
1017 1028
1018 def Lint(change_info, args): 1029 def Lint(change_info, args):
1019 """Runs cpplint.py on all the files in |change_info|""" 1030 """Runs cpplint.py on all the files in |change_info|"""
1020 try: 1031 try:
1021 import cpplint 1032 import cpplint
1022 except ImportError: 1033 except ImportError:
1023 ErrorExit("You need to install cpplint.py to lint C++ files.") 1034 ErrorExit("You need to install cpplint.py to lint C++ files.")
1024 1035
1025 # Change the current working directory before calling lint so that it 1036 # Change the current working directory before calling lint so that it
1026 # shows the correct base. 1037 # shows the correct base.
1027 previous_cwd = os.getcwd() 1038 previous_cwd = os.getcwd()
1028 os.chdir(GetRepositoryRoot()) 1039 os.chdir(change_info.GetLocalRoot())
1029 1040
1030 # Process cpplints arguments if any. 1041 # Process cpplints arguments if any.
1031 filenames = cpplint.ParseArguments(args + change_info.FileList()) 1042 filenames = cpplint.ParseArguments(args + change_info.GetFileNames())
1032 1043
1033 for file in filenames: 1044 for file in filenames:
1034 if len([file for suffix in CPP_EXTENSIONS if file.endswith(suffix)]): 1045 if len([file for suffix in CPP_EXTENSIONS if file.endswith(suffix)]):
1035 if len([file for prefix in IGNORE_PATHS if file.startswith(prefix)]): 1046 if len([file for prefix in IGNORE_PATHS if file.startswith(prefix)]):
1036 print "Ignoring non-Google styled file %s" % file 1047 print "Ignoring non-Google styled file %s" % file
1037 else: 1048 else:
1038 cpplint.ProcessFile(file, cpplint._cpplint_state.verbose_level) 1049 cpplint.ProcessFile(file, cpplint._cpplint_state.verbose_level)
1039 1050
1040 print "Total errors found: %d\n" % cpplint._cpplint_state.error_count 1051 print "Total errors found: %d\n" % cpplint._cpplint_state.error_count
1041 os.chdir(previous_cwd) 1052 os.chdir(previous_cwd)
(...skipping 14 matching lines...) Expand all
1056 if not result and may_prompt: 1067 if not result and may_prompt:
1057 print "\nPresubmit errors, can't continue (use --no_presubmit to bypass)" 1068 print "\nPresubmit errors, can't continue (use --no_presubmit to bypass)"
1058 return result 1069 return result
1059 1070
1060 1071
1061 def Changes(): 1072 def Changes():
1062 """Print all the changelists and their files.""" 1073 """Print all the changelists and their files."""
1063 for cl in GetCLs(): 1074 for cl in GetCLs():
1064 change_info = ChangeInfo.Load(cl, True, True) 1075 change_info = ChangeInfo.Load(cl, True, True)
1065 print "\n--- Changelist " + change_info.name + ":" 1076 print "\n--- Changelist " + change_info.name + ":"
1066 for file in change_info.files: 1077 for file in change_info.GetFiles():
1067 print "".join(file) 1078 print "".join(file)
1068 1079
1069 1080
1070 def main(argv=None): 1081 def main(argv=None):
1071 if argv is None: 1082 if argv is None:
1072 argv = sys.argv 1083 argv = sys.argv
1073 1084
1074 if len(argv) == 1: 1085 if len(argv) == 1:
1075 Help() 1086 Help()
1076 return 0; 1087 return 0;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 UploadCL(change_info, argv[3:]) 1163 UploadCL(change_info, argv[3:])
1153 elif command == "presubmit": 1164 elif command == "presubmit":
1154 PresubmitCL(change_info) 1165 PresubmitCL(change_info)
1155 elif command in ("commit", "submit"): 1166 elif command in ("commit", "submit"):
1156 Commit(change_info, argv[3:]) 1167 Commit(change_info, argv[3:])
1157 elif command == "delete": 1168 elif command == "delete":
1158 change_info.Delete() 1169 change_info.Delete()
1159 elif command == "try": 1170 elif command == "try":
1160 # When the change contains no file, send the "changename" positional 1171 # When the change contains no file, send the "changename" positional
1161 # argument to trychange.py. 1172 # argument to trychange.py.
1162 if change_info.files: 1173 if change_info.GetFiles():
1163 args = argv[3:] 1174 args = argv[3:]
1164 else: 1175 else:
1165 change_info = None 1176 change_info = None
1166 args = argv[2:] 1177 args = argv[2:]
1167 TryChange(change_info, args, swallow_exception=False) 1178 TryChange(change_info, args, swallow_exception=False)
1168 else: 1179 else:
1169 # Everything else that is passed into gcl we redirect to svn, after adding 1180 # Everything else that is passed into gcl we redirect to svn, after adding
1170 # the files. This allows commands such as 'gcl diff xxx' to work. 1181 # the files. This allows commands such as 'gcl diff xxx' to work.
1171 args =["svn", command] 1182 args =["svn", command]
1172 root = GetRepositoryRoot() 1183 root = GetRepositoryRoot()
1173 args.extend([os.path.join(root, x) for x in change_info.FileList()]) 1184 args.extend([os.path.join(root, x) for x in change_info.GetFileNames()])
1174 RunShell(args, True) 1185 RunShell(args, True)
1175 return 0 1186 return 0
1176 1187
1177 1188
1178 if __name__ == "__main__": 1189 if __name__ == "__main__":
1179 sys.exit(main()) 1190 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | presubmit_support.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698