| OLD | NEW |
| 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 string | 14 import string |
| 14 import subprocess | 15 import subprocess |
| 15 import sys | 16 import sys |
| 16 import tempfile | 17 import tempfile |
| 17 import upload | 18 import upload |
| 18 import urllib2 | 19 import urllib2 |
| 19 import xml.dom.minidom | 20 import xml.dom.minidom |
| 20 | 21 |
| 21 # gcl now depends on gclient. | 22 # gcl now depends on gclient. |
| 22 import gclient | 23 import gclient |
| 23 | 24 |
| 24 __version__ = '1.0' | 25 __version__ = '1.1' |
| 25 | 26 |
| 26 | 27 |
| 27 CODEREVIEW_SETTINGS = { | 28 CODEREVIEW_SETTINGS = { |
| 28 # Default values. | 29 # Default values. |
| 29 "CODE_REVIEW_SERVER": "codereview.chromium.org", | 30 "CODE_REVIEW_SERVER": "codereview.chromium.org", |
| 30 "CC_LIST": "chromium-reviews@googlegroups.com", | 31 "CC_LIST": "chromium-reviews@googlegroups.com", |
| 31 "VIEW_VC": "http://src.chromium.org/viewvc/chrome?view=rev&revision=", | 32 "VIEW_VC": "http://src.chromium.org/viewvc/chrome?view=rev&revision=", |
| 32 } | 33 } |
| 33 | 34 |
| 34 # globals that store the root of the current repository and the directory where | 35 # globals that store the root of the current repository and the directory where |
| 35 # we store information about changelists. | 36 # we store information about changelists. |
| 36 repository_root = "" | 37 repository_root = "" |
| 37 gcl_info_dir = "" | |
| 38 | 38 |
| 39 # Filename where we store repository specific information for gcl. | 39 # Filename where we store repository specific information for gcl. |
| 40 CODEREVIEW_SETTINGS_FILE = "codereview.settings" | 40 CODEREVIEW_SETTINGS_FILE = "codereview.settings" |
| 41 | 41 |
| 42 # Warning message when the change appears to be missing tests. | 42 # Warning message when the change appears to be missing tests. |
| 43 MISSING_TEST_MSG = "Change contains new or modified methods, but no new tests!" | 43 MISSING_TEST_MSG = "Change contains new or modified methods, but no new tests!" |
| 44 | 44 |
| 45 # Caches whether we read the codereview.settings file yet or not. | 45 # Caches whether we read the codereview.settings file yet or not. |
| 46 read_gcl_info = False | 46 read_gcl_info = False |
| 47 | 47 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 parent = os.path.dirname(repository_root) | 103 parent = os.path.dirname(repository_root) |
| 104 if (gclient.CaptureSVNInfo(parent, print_error=False).get( | 104 if (gclient.CaptureSVNInfo(parent, print_error=False).get( |
| 105 "Repository Root") != cur_dir_repo_root): | 105 "Repository Root") != cur_dir_repo_root): |
| 106 break | 106 break |
| 107 repository_root = parent | 107 repository_root = parent |
| 108 return repository_root | 108 return repository_root |
| 109 | 109 |
| 110 | 110 |
| 111 def GetInfoDir(): | 111 def GetInfoDir(): |
| 112 """Returns the directory where gcl info files are stored.""" | 112 """Returns the directory where gcl info files are stored.""" |
| 113 global gcl_info_dir | 113 return os.path.join(GetRepositoryRoot(), '.svn', 'gcl_info') |
| 114 if not gcl_info_dir: | 114 |
| 115 gcl_info_dir = os.path.join(GetRepositoryRoot(), '.svn', 'gcl_info') | 115 |
| 116 return gcl_info_dir | 116 def GetChangesDir(): |
| 117 """Returns the directory where gcl change files are stored.""" |
| 118 return os.path.join(GetInfoDir(), 'changes') |
| 117 | 119 |
| 118 | 120 |
| 119 def GetCodeReviewSetting(key): | 121 def GetCodeReviewSetting(key): |
| 120 """Returns a value for the given key for this repository.""" | 122 """Returns a value for the given key for this repository.""" |
| 121 global read_gcl_info | 123 global read_gcl_info |
| 122 if not read_gcl_info: | 124 if not read_gcl_info: |
| 123 read_gcl_info = True | 125 read_gcl_info = True |
| 124 # First we check if we have a cached version. | 126 # First we check if we have a cached version. |
| 125 cached_settings_file = os.path.join(GetInfoDir(), CODEREVIEW_SETTINGS_FILE) | 127 cached_settings_file = os.path.join(GetInfoDir(), CODEREVIEW_SETTINGS_FILE) |
| 126 if (not os.path.exists(cached_settings_file) or | 128 if (not os.path.exists(cached_settings_file) or |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 # . | 368 # . |
| 367 # filepathn\n | 369 # filepathn\n |
| 368 # SEPARATOR\n | 370 # SEPARATOR\n |
| 369 # description | 371 # description |
| 370 | 372 |
| 371 | 373 |
| 372 def GetChangelistInfoFile(changename): | 374 def GetChangelistInfoFile(changename): |
| 373 """Returns the file that stores information about a changelist.""" | 375 """Returns the file that stores information about a changelist.""" |
| 374 if not changename or re.search(r'[^\w-]', changename): | 376 if not changename or re.search(r'[^\w-]', changename): |
| 375 ErrorExit("Invalid changelist name: " + changename) | 377 ErrorExit("Invalid changelist name: " + changename) |
| 376 return os.path.join(GetInfoDir(), changename) | 378 return os.path.join(GetChangesDir(), changename) |
| 377 | 379 |
| 378 | 380 |
| 379 def LoadChangelistInfoForMultiple(changenames, fail_on_not_found=True, | 381 def LoadChangelistInfoForMultiple(changenames, fail_on_not_found=True, |
| 380 update_status=False): | 382 update_status=False): |
| 381 """Loads many changes and merge their files list into one pseudo change. | 383 """Loads many changes and merge their files list into one pseudo change. |
| 382 | 384 |
| 383 This is mainly usefull to concatenate many changes into one for a 'gcl try'. | 385 This is mainly usefull to concatenate many changes into one for a 'gcl try'. |
| 384 """ | 386 """ |
| 385 changes = changenames.split(',') | 387 changes = changenames.split(',') |
| 386 aggregate_change_info = ChangeInfo(name=changenames) | 388 aggregate_change_info = ChangeInfo(name=changenames) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 save = True | 437 save = True |
| 436 files[files.index(file)] = (status, file[1]) | 438 files[files.index(file)] = (status, file[1]) |
| 437 change_info = ChangeInfo(changename, issue, description, files) | 439 change_info = ChangeInfo(changename, issue, description, files) |
| 438 if save: | 440 if save: |
| 439 change_info.Save() | 441 change_info.Save() |
| 440 return change_info | 442 return change_info |
| 441 | 443 |
| 442 | 444 |
| 443 def GetCLs(): | 445 def GetCLs(): |
| 444 """Returns a list of all the changelists in this repository.""" | 446 """Returns a list of all the changelists in this repository.""" |
| 445 cls = os.listdir(GetInfoDir()) | 447 cls = os.listdir(GetChangesDir()) |
| 446 if CODEREVIEW_SETTINGS_FILE in cls: | 448 if CODEREVIEW_SETTINGS_FILE in cls: |
| 447 cls.remove(CODEREVIEW_SETTINGS_FILE) | 449 cls.remove(CODEREVIEW_SETTINGS_FILE) |
| 448 return cls | 450 return cls |
| 449 | 451 |
| 450 | 452 |
| 451 def GenerateChangeName(): | 453 def GenerateChangeName(): |
| 452 """Generate a random changelist name.""" | 454 """Generate a random changelist name.""" |
| 453 random.seed() | 455 random.seed() |
| 454 current_cl_names = GetCLs() | 456 current_cl_names = GetCLs() |
| 455 while True: | 457 while True: |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1013 | 1015 |
| 1014 | 1016 |
| 1015 def main(argv=None): | 1017 def main(argv=None): |
| 1016 if argv is None: | 1018 if argv is None: |
| 1017 argv = sys.argv | 1019 argv = sys.argv |
| 1018 | 1020 |
| 1019 if len(argv) == 1: | 1021 if len(argv) == 1: |
| 1020 Help() | 1022 Help() |
| 1021 return 0; | 1023 return 0; |
| 1022 | 1024 |
| 1023 # Create the directory where we store information about changelists if it | 1025 # Create the directories where we store information about changelists if it |
| 1024 # doesn't exist. | 1026 # doesn't exist. |
| 1025 if not os.path.exists(GetInfoDir()): | 1027 if not os.path.exists(GetInfoDir()): |
| 1026 os.mkdir(GetInfoDir()) | 1028 os.mkdir(GetInfoDir()) |
| 1029 if not os.path.exists(GetChangesDir()): |
| 1030 os.mkdir(GetChangesDir()) |
| 1031 # For smooth upgrade support, move the files in GetInfoDir() to |
| 1032 # GetChangesDir(). |
| 1033 # TODO(maruel): Remove this code in August 2009. |
| 1034 for file in os.listdir(unicode(GetInfoDir())): |
| 1035 file_path = os.path.join(unicode(GetInfoDir()), file) |
| 1036 if os.path.isfile(file_path) and file != CODEREVIEW_SETTINGS_FILE: |
| 1037 shutil.move(file_path, GetChangesDir()) |
| 1027 | 1038 |
| 1028 # Commands that don't require an argument. | 1039 # Commands that don't require an argument. |
| 1029 command = argv[1] | 1040 command = argv[1] |
| 1030 if command == "opened": | 1041 if command == "opened": |
| 1031 Opened() | 1042 Opened() |
| 1032 return 0 | 1043 return 0 |
| 1033 if command == "status": | 1044 if command == "status": |
| 1034 Opened() | 1045 Opened() |
| 1035 print "\n--- Not in any changelist:" | 1046 print "\n--- Not in any changelist:" |
| 1036 UnknownFiles([]) | 1047 UnknownFiles([]) |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1097 # the files. This allows commands such as 'gcl diff xxx' to work. | 1108 # the files. This allows commands such as 'gcl diff xxx' to work. |
| 1098 args =["svn", command] | 1109 args =["svn", command] |
| 1099 root = GetRepositoryRoot() | 1110 root = GetRepositoryRoot() |
| 1100 args.extend([os.path.join(root, x) for x in change_info.FileList()]) | 1111 args.extend([os.path.join(root, x) for x in change_info.FileList()]) |
| 1101 RunShell(args, True) | 1112 RunShell(args, True) |
| 1102 return 0 | 1113 return 0 |
| 1103 | 1114 |
| 1104 | 1115 |
| 1105 if __name__ == "__main__": | 1116 if __name__ == "__main__": |
| 1106 sys.exit(main()) | 1117 sys.exit(main()) |
| OLD | NEW |