| OLD | NEW |
| 1 # Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import os | |
| 6 import re | |
| 7 import subprocess | 1 import subprocess |
| 8 import sys | 2 import sys |
| 3 import re |
| 4 import os |
| 9 import webbrowser | 5 import webbrowser |
| 10 | 6 |
| 7 export_map_ = None |
| 8 files_info_ = None |
| 9 delete_map_ = None |
| 10 file_pattern_ = r"[ ]+([MADUC])[ ]+/((?:trunk|branches/\d+)/src(.*)/(.*))" |
| 11 | 11 |
| 12 def deltree(root): | 12 def deltree(root): |
| 13 """Removes a given directory.""" | 13 """ |
| 14 Removes a given directory |
| 15 """ |
| 14 if (not os.path.exists(root)): | 16 if (not os.path.exists(root)): |
| 15 return | 17 return |
| 16 | 18 |
| 17 if sys.platform == 'win32': | 19 if sys.platform == 'win32': |
| 18 os.system('rmdir /S /Q ' + root.replace('/','\\')) | 20 os.system('rmdir /S /Q ' + root.replace('/','\\')) |
| 19 else: | 21 else: |
| 20 for name in os.listdir(root): | 22 for name in os.listdir(root): |
| 21 path = os.path.join(root, name) | 23 path = os.path.join(root, name) |
| 22 if os.path.isdir(path): | 24 if os.path.isdir(path): |
| 23 deltree(path) | 25 deltree(path) |
| 24 else: | 26 else: |
| 25 os.unlink(path) | 27 os.unlink(path) |
| 26 os.rmdir(root) | 28 os.rmdir(root) |
| 27 | 29 |
| 28 | |
| 29 def clobberDir(dir): | 30 def clobberDir(dir): |
| 30 """Removes a given directory.""" | 31 """ |
| 31 | 32 Removes a given directory |
| 33 """ |
| 34 |
| 32 if (os.path.exists(dir)): | 35 if (os.path.exists(dir)): |
| 33 print dir + " directory found, deleting" | 36 print dir + " directory found, deleting" |
| 34 # The following line was removed due to access controls in Windows | 37 #The following line was removed due to access controls in Windows |
| 35 # which make os.unlink(path) calls impossible. | 38 #which make os.unlink(path) calls impossible. |
| 36 # deltree(dir) | 39 #deltree(dir) |
| 37 os.system('rmdir /S /Q ' + dir.replace('/','\\')) | 40 os.system('rmdir /S /Q ' + dir.replace('/','\\')) |
| 38 | |
| 39 | 41 |
| 40 def gclUpload(revision, author): | 42 def gclUpload(revision, author): |
| 41 command = ("gcl upload " + str(revision) + | 43 command = ("gcl upload " + str(revision) + |
| 42 " --send_mail --no_try --no_presubmit --reviewers=" + author) | 44 " --send_mail --no_try --no_presubmit --reviewers=" + author) |
| 43 os.system(command) | 45 os.system(command) |
| 44 # subprocess.Popen(command, | 46 |
| 45 # shell=True, | 47 def getSVNInfo(url, revision): |
| 46 # stdout=None, | 48 command = 'svn info ' + url + "@"+str(revision) |
| 47 # stderr=subprocess.PIPE) | 49 svn_info = subprocess.Popen(command, |
| 48 # stderr=subprocess.PIPE).stdout.readlines() | 50 shell=True, |
| 49 # for line in svn_info: | 51 stdout=subprocess.PIPE, |
| 50 # match = re.search(r"Issue created. URL: (http://.+)", line) | 52 stderr=subprocess.PIPE).stdout.readlines()
|
| 51 # if match: | 53 rtn = {} |
| 52 # return match.group(1) | 54 for line in svn_info: |
| 55 match = re.search(r"(.*?):(.*)", line) |
| 56 if match: |
| 57 » rtn[match.group(1).strip()]=match.group(2).strip() |
| 58 |
| 59 return rtn |
| 60 |
| 61 def getAuthor(url, revision): |
| 62 info = getSVNInfo(url, revision) |
| 63 |
| 64 if (info.has_key("Last Changed Author")): |
| 65 return info["Last Changed Author"] |
| 66 |
| 53 return None | 67 return None |
| 54 | 68 |
| 69 def isSVNFile(url, revision): |
| 70 info = getSVNInfo(url, revision) |
| 71 |
| 72 if (info.has_key("Node Kind")): |
| 73 if (info["Node Kind"] == "file"): return True |
| 74 |
| 75 return False |
| 55 | 76 |
| 56 def getAuthor(url, revision): | 77 def isSVNDirectory(url, revision): |
| 57 command = 'svn info ' + url + "@"+str(revision) | 78 info = getSVNInfo(url, revision) |
| 58 svn_info = subprocess.Popen(command, | 79 |
| 59 shell=True, | 80 if (info.has_key("Node Kind")): |
| 60 stdout=subprocess.PIPE, | 81 if (info["Node Kind"] == "directory"): return True |
| 61 stderr=subprocess.PIPE).stdout.readlines() | 82 |
| 62 for line in svn_info: | 83 return False |
| 63 match = re.search(r"Last Changed Author: (.+)", line) | 84 |
| 64 if match: | |
| 65 return match.group(1) | |
| 66 return None | |
| 67 | |
| 68 | |
| 69 def getRevisionLog(url, revision): | 85 def getRevisionLog(url, revision): |
| 70 """Takes an svn url and gets the associated revision. """ | 86 """ |
| 87 Takes an svn url and gets the associated revision. |
| 88 """ |
| 71 command = 'svn log ' + url + " -r"+str(revision) | 89 command = 'svn log ' + url + " -r"+str(revision) |
| 72 svn_info = subprocess.Popen(command, | 90 svn_info = subprocess.Popen(command, |
| 73 shell=True, | 91 shell=True, |
| 74 stdout=subprocess.PIPE, | 92 stdout=subprocess.PIPE, |
| 75 stderr=subprocess.PIPE).stdout.readlines() | 93 stderr=subprocess.PIPE).stdout.readlines() |
| 76 rtn= "" | 94 rtn= "" |
| 77 pos = 0 | 95 pos = 0 |
| 78 for line in svn_info: | 96 for line in svn_info: |
| 79 if (pos > 2): | 97 if (pos > 2): |
| 80 rtn += line.replace('-','').replace('\r','') | 98 rtn += line.replace('-','').replace('\r','') |
| 81 else: | 99 else: |
| 82 pos = pos + 1 | 100 pos = pos + 1 |
| 83 | 101 |
| 84 return rtn | 102 return rtn |
| 85 | 103 |
| 86 | 104 def checkoutRevision(url, revision, branch_url, revert=False): |
| 87 def checkoutRevision(url, revision, branch_url): | 105 files_info = getFileInfo(url, revision) |
| 88 paths = getBestMergePaths(url, revision) | 106 paths = getBestMergePaths2(files_info, revision) |
| 89 deltree('./src') | 107 export_map = getBestExportPathsMap2(files_info, revision) |
| 90 if not os.path.exists('./src'): | 108 |
| 91 command = 'svn checkout -N ' + branch_url | 109 command = 'svn checkout -N ' + branch_url |
| 92 print command | 110 print command |
| 93 os.system(command) | 111 os.system(command) |
| 94 | 112 |
| 95 # This line is extremely important due to the way svn behaves in the | 113 match = re.search(r"svn://.*/(.*)", branch_url) |
| 96 # set-depths action. If parents aren't handled before children, the child | 114 |
| 97 # directories get clobbered and the merge step fails. | 115 if match: |
| 98 paths.sort() | 116 os.chdir(match.group(1)) |
| 99 for path in paths: | 117 |
| 100 subpaths = path.split('/') | 118 #This line is extremely important due to the way svn behaves in the set-depths |
| 101 subpaths.pop(0) | 119 #action. If parents aren't handled before children, the child directories get |
| 102 base = './src' | 120 #clobbered and the merge step fails. |
| 103 for subpath in subpaths: | 121 paths.sort() |
| 104 base += '/' + subpath | 122 |
| 105 if not os.path.exists(base): | 123 #Checkout the directories that already exist |
| 106 command = ('svn update --depth empty ' + base) | 124 for path in paths: |
| 107 print command | 125 if (export_map.has_key(path) and not revert): |
| 108 os.system(command) | 126 print "Exclude new directory " + path |
| 109 else: | 127 continue |
| 110 print "Found " + base | 128 subpaths = path.split('/') |
| 111 | 129 subpaths.pop(0) |
| 112 for file in getFilesInRevision(url, revision): | 130 base = '' |
| 113 # Prevent the tool from clobbering the src directory. | 131 for subpath in subpaths: |
| 132 base += '/' + subpath |
| 133 #This logic ensures that you don't empty out any directories |
| 134 if not os.path.exists("." + base): |
| 135 command = ('svn update --depth empty ' + "." + base) |
| 136 print command |
| 137 os.system(command) |
| 138 |
| 139 if (revert): |
| 140 files = getAllFilesInRevision(files_info) |
| 141 else: |
| 142 files = getExistingFilesInRevision(files_info) |
| 143 |
| 144 for file in files: |
| 145 #Prevent the tool from clobbering the src directory |
| 114 if (file == ""): | 146 if (file == ""): |
| 115 continue | 147 continue |
| 116 command = ('svn up ./src' + file) | 148 command = ('svn up ".' + file + '"') |
| 117 print command | 149 print command |
| 118 os.system(command) | 150 os.system(command) |
| 119 | 151 |
| 120 | 152 def mergeRevision(url, revision): |
| 121 def mergeRevision(url, revision, ignoreAncestry=False): | |
| 122 paths = getBestMergePaths(url, revision) | 153 paths = getBestMergePaths(url, revision) |
| 123 for path in paths: | 154 export_map = getBestExportPathsMap(url, revision) |
| 155 |
| 156 for path in paths: |
| 157 if export_map.has_key(path): |
| 158 continue |
| 124 command = ('svn merge -N -r ' + str(revision-1) + ":" + str(revision) + " ") | 159 command = ('svn merge -N -r ' + str(revision-1) + ":" + str(revision) + " ") |
| 125 if (ignoreAncestry): | 160 command = command + url + path + "@" + str(revision) + " ." + path |
| 126 command = command + " --ignore-ancestry " | 161 |
| 127 command = command + url + path + " ./src" + path | 162 print command |
| 128 print command | 163 os.system(command) |
| 129 os.system(command) | 164 |
| 130 | 165 def exportRevision(url, revision): |
| 166 paths = getBestExportPathsMap(url, revision).keys() |
| 167 |
| 168 paths.sort() |
| 169 |
| 170 for path in paths: |
| 171 command = ('svn export -N ' + url + path + "@" + str(revision) + " ." |
| 172 + path) |
| 173 print command |
| 174 os.system(command) |
| 175 |
| 176 command = ('svn add .' + path) |
| 177 print command |
| 178 os.system(command) |
| 179 |
| 180 def deleteRevision(url, revision): |
| 181 paths = getBestDeletePathsMap(url, revision).keys() |
| 182 paths.sort() |
| 183 paths.reverse() |
| 184 |
| 185 for path in paths: |
| 186 command = ("svn delete ." + path) |
| 187 print command |
| 188 os.system(command) |
| 189 |
| 190 |
| 191 def revertExportRevision(url, revision): |
| 192 paths = getBestExportPathsMap(url, revision).keys() |
| 193 paths.sort() |
| 194 paths.reverse() |
| 195 |
| 196 for path in paths: |
| 197 command = ("svn delete ." + path) |
| 198 print command |
| 199 os.system(command) |
| 131 | 200 |
| 132 def revertRevision(url, revision): | 201 def revertRevision(url, revision): |
| 133 paths = getBestMergePaths(url, revision) | 202 paths = getBestMergePaths(url, revision) |
| 134 for path in paths: | 203 for path in paths: |
| 135 command = ('svn merge -N -r ' + str(revision) + ":" + str(revision-1) + | 204 command = ('svn merge -N -r ' + str(revision) + ":" + str(revision-1) + |
| 136 " " + url + path + " ./src" + path) | 205 " " + url + path + " ." + path) |
| 137 print command | 206 print command |
| 138 os.system(command) | 207 os.system(command) |
| 139 | 208 |
| 209 def getFileInfo(url, revision): |
| 210 global files_info_, file_pattern_ |
| 211 |
| 212 if (files_info_ != None): |
| 213 return files_info_ |
| 214 |
| 215 command = 'svn log ' + url + " -r " + str(revision) + " -v" |
| 216 svn_log = subprocess.Popen(command, |
| 217 shell=True, |
| 218 stdout=subprocess.PIPE, |
| 219 stderr=subprocess.PIPE).stdout.readlines() |
| 220 |
| 221 rtn = [] |
| 222 for line in svn_log: |
| 223 #A workaround to dump the (from .*) stuff, regex not so friendly in the 2nd |
| 224 #pass... |
| 225 match = re.search(r"(.*) \(from.*\)", line) |
| 226 if match: |
| 227 line = match.group(1) |
| 228 match = re.search(file_pattern_, line) |
| 229 if match: |
| 230 rtn.append([match.group(1).strip(), match.group(2).strip(), |
| 231 match.group(3).strip(),match.group(4).strip()]) |
| 232 |
| 233 files_info_ = rtn |
| 234 return rtn |
| 140 | 235 |
| 141 def getBestMergePaths(url, revision): | 236 def getBestMergePaths(url, revision): |
| 142 """Takes an svn url and gets the associated revision.""" | 237 """ |
| 143 command = 'svn log ' + url + " -r "+str(revision) + " -v" | 238 Takes an svn url and gets the associated revision. |
| 144 svn_info = subprocess.Popen(command, | 239 """ |
| 145 shell=True, | 240 return getBestMergePaths2(getFileInfo(url, revision), revision) |
| 146 stdout=subprocess.PIPE, | 241 |
| 147 stderr=subprocess.PIPE).stdout.readlines() | 242 def getBestMergePaths2(files_info, revision): |
| 148 map = {} | 243 """ |
| 149 for line in svn_info: | 244 Takes an svn url and gets the associated revision. |
| 150 match = re.search(r"[\n\r ]+[MADUC][\n\r ]+/(?:trunk|branches/\d+)/src([^ ]*
)/[^ ]+", line) | 245 """ |
| 151 if match: | 246 |
| 152 map[match.group(1)] = match.group(1) | 247 map = dict() |
| 248 for file_info in files_info: |
| 249 map[file_info[2]] = file_info[2] |
| 153 | 250 |
| 154 return map.keys() | 251 return map.keys() |
| 155 | 252 |
| 156 | 253 def getBestExportPathsMap(url, revision): |
| 157 def getFilesInRevision(url, revision): | 254 return getBestExportPathsMap2(getFileInfo(url, revision), revision) |
| 158 """Takes an svn url and gets the associated revision.""" | 255 |
| 159 command = 'svn log ' + url + " -r "+str(revision) + " -v" | 256 def getBestExportPathsMap2(files_info, revision): |
| 160 svn_info = subprocess.Popen(command, | 257 """ |
| 161 shell=True, | 258 Takes an svn url and gets the associated revision. |
| 162 stdout=subprocess.PIPE, | 259 """ |
| 163 stderr=subprocess.PIPE).stdout.readlines() | 260 global export_map_ |
| 164 map = {} | 261 |
| 165 for line in svn_info: | 262 if export_map_: |
| 166 match = re.search(r"[\n\r ]+[MADUC][\n\r ]+/(?:trunk|branches/\d+)/src([^ ]*
)/([^ ]+)", line) | 263 return export_map_ |
| 167 if match: | 264 |
| 168 map[match.group(1) + "/" + match.group(2)] = match.group(1) + "/" + match.
group(2) | 265 map = dict() |
| 169 | 266 for file_info in files_info: |
| 170 return map.keys() | 267 if (file_info[0] == "A"): |
| 171 | 268 if(isSVNDirectory("svn://chrome-svn/chrome/" + file_info[1], revision)): |
| 172 | 269 map[file_info[2] + "/" + file_info[3]] = "" |
| 173 def getBestMergePath(url, revision): | 270 |
| 174 """Takes an svn url and gets the associated revision.""" | 271 export_map_ = map |
| 175 command = 'svn log ' + url + " -r "+str(revision) + " -v" | 272 |
| 176 svn_info = subprocess.Popen(command, | 273 return map |
| 177 shell=True, | 274 |
| 178 stdout=subprocess.PIPE, | 275 def getBestDeletePathsMap(url, revision): |
| 179 stderr=subprocess.PIPE).stdout.readlines() | 276 return getBestDeletePathsMap2(getFileInfo(url, revision), revision) |
| 180 best_path = None | 277 |
| 181 for line in svn_info: | 278 def getBestDeletePathsMap2(files_info, revision): |
| 182 match = re.search(r"[\n\r ]+[MADUC][\n\r ]+/.*/src(.*)/.+", line) | 279 """ |
| 183 if match: | 280 Takes an svn url and gets the associated revision. |
| 184 if (best_path == None): | 281 """ |
| 185 best_path = match.group(1) | 282 global delete_map_ |
| 186 else: | 283 |
| 187 best_path = leastPath(match.group(1),best_path) | 284 if delete_map_: |
| 188 | 285 return delete_map_ |
| 189 return best_path | 286 |
| 190 | 287 map = dict() |
| 191 | 288 for file_info in files_info: |
| 192 def leastPath(a, b): | 289 if (file_info[0] == "D"): |
| 193 if (not a) or (a == ""): | 290 if(isSVNDirectory("svn://chrome-svn/chrome/" + file_info[1], revision)): |
| 194 return "" | 291 map[file_info[2] + "/" + file_info[3]] = "" |
| 195 if (b == ""): | 292 |
| 196 return "" | 293 delete_map_ = map |
| 197 if (not b): | 294 |
| 198 return a | 295 return map |
| 199 | 296 |
| 200 a_list = a.lstrip("/").split("/") | 297 def getExistingFilesInRevision(files_info): |
| 201 b_list = b.lstrip("/").split("/") | 298 """ |
| 202 last_match = "" | 299 Checks for existing files in the revision, anything that's A will require |
| 203 while((len(a_list) != 0) and (len(b_list) != 0)): | 300 special treatment (either a merge or an export + add) |
| 204 a_value = a_list.pop(0) | 301 """ |
| 205 b_value = b_list.pop(0) | 302 map = [] |
| 206 if (a_value == b_value): | 303 for file_info in files_info: |
| 207 last_match = last_match + "/" + a_value | 304 if file_info[0] != "A": |
| 208 else: | 305 map.append(file_info[2] + "/" + file_info[3]) |
| 209 break | 306 |
| 210 | 307 return map |
| 211 return last_match | 308 |
| 212 | 309 def getAllFilesInRevision(files_info): |
| 310 """ |
| 311 Checks for existing files in the revision, anything that's A will require |
| 312 special treatment (either a merge or an export + add) |
| 313 """ |
| 314 map = [] |
| 315 for file_info in files_info: |
| 316 map.append(file_info[2] + "/" + file_info[3]) |
| 317 |
| 318 return map |
| 213 | 319 |
| 214 def prompt(question): | 320 def prompt(question): |
| 215 p = None | 321 p = None |
| 322 |
| 216 while not p: | 323 while not p: |
| 217 print question + " [y|n]:" | 324 print question + " [y|n]:" |
| 218 p = sys.stdin.readline() | 325 p = sys.stdin.readline() |
| 219 if p.lower().startswith('n'): | 326 if p.lower().startswith('n'): |
| 220 return False | 327 return False |
| 221 elif p.lower().startswith('y'): | 328 elif p.lower().startswith('y'): |
| 222 return True | 329 return True |
| 223 else: | 330 else: |
| 224 p = None | 331 p = None |
| 225 | 332 |
| 226 | 333 def text_prompt(question, default): |
| 334 print question + " [" + default + "]:" |
| 335 p = sys.stdin.readline() |
| 336 if p.strip() == "": |
| 337 return default |
| 338 return p |
| 339 |
| 227 def main(argv=None): | 340 def main(argv=None): |
| 228 BASE_URL = "svn://chrome-svn/chrome" | 341 BASE_URL = "svn://chrome-svn/chrome" |
| 229 TRUNK_URL = BASE_URL + "/trunk/src" | 342 TRUNK_URL = BASE_URL + "/trunk/src" |
| 230 BRANCH_URL = None | 343 BRANCH_URL = BASE_URL + "/branches/$branch/src" |
| 344 DEFAULT_WORKING = "working" |
| 345 SKIP_CHECK_WORKING = True |
| 346 PROMPT_FOR_AUTHOR = False |
| 347 |
| 348 global file_pattern_ |
| 349 if os.path.exists("drover.properties"): |
| 350 file = open("drover.properties") |
| 351 exec(file) |
| 352 file.close() |
| 353 if FILE_PATTERN: |
| 354 file_pattern_ = FILE_PATTERN |
| 231 | 355 |
| 232 if (len(sys.argv) == 1): | 356 if (len(sys.argv) == 1): |
| 233 print "WARNING: Please use this tool in an empty directory (or at least one" | 357 print "WARNING: Please use this tool in an empty directory (or at least one" |
| 234 print "that you don't mind clobbering." | 358 print "that you don't mind clobbering." |
| 235 print "REQUIRES: SVN 1.5+" | 359 print "REQUIRES: SVN 1.5+" |
| 236 print "NOTE: NO NEED TO CHECKOUT ANYTHING IN ADVANCE OF USING THIS TOOL." | 360 print "NOTE: NO NEED TO CHECKOUT ANYTHING IN ADVANCE OF USING THIS TOOL." |
| 237 print "\nValid parameters:" | 361 print "\nValid parameters:" |
| 238 print "\n[Merge from trunk to branch]" | 362 print "\n[Merge from trunk to branch]" |
| 239 print "<revision> --merge <branch_num>" | 363 print "<revision> --merge <branch_num>" |
| 240 print "Example " + sys.argv[0] + " 12345 --merge 187" | 364 print "Example " + sys.argv[0] + " 12345 --merge 187" |
| 241 print "\n[Merge from trunk to branch, ignoring revision history]" | 365 print "\n[Merge from trunk to branch, ignoring revision history]" |
| 242 print "<revision> --mplus <branch_num>" | 366 print "<revision> --mplus <branch_num>" |
| 243 print "Example " + sys.argv[0] + " 12345 --mplus 187" | 367 print "Example " + sys.argv[0] + " 12345 --mplus 187" |
| 244 print "\n[Revert from trunk]" | 368 print "\n[Revert from trunk]" |
| 245 print " <revision> --revert" | 369 print " <revision> --revert" |
| 246 print "Example " + sys.argv[0] + " 12345 --revert" | 370 print "Example " + sys.argv[0] + " 12345 --revert" |
| 247 print "\n[Revert from branch]" | 371 print "\n[Revert from branch]" |
| 248 print " <revision> --revert <branch_num>" | 372 print " <revision> --revert <branch_num>" |
| 249 print "Example " + sys.argv[0] + " 12345 --revert 187" | 373 print "Example " + sys.argv[0] + " 12345 --revert 187" |
| 250 sys.exit(0) | 374 sys.exit(0) |
| 251 | 375 |
| 252 revision = int(sys.argv[1]) | 376 revision = int(sys.argv[1]) |
| 253 if ((len(sys.argv) >= 4) and (sys.argv[2] in ['--revert','-r'])): | 377 if ((len(sys.argv) >= 4) and (sys.argv[2] in ['--revert','-r'])): |
| 254 BRANCH_URL = BASE_URL + "/branches/" + sys.argv[3] + "/src" | 378 url = BRANCH_URL.replace("$branch", sys.argv[3]) |
| 255 url = BRANCH_URL | |
| 256 else: | 379 else: |
| 257 url = TRUNK_URL | 380 url = TRUNK_URL |
| 258 action = "Merge" | 381 action = "Merge" |
| 382 |
| 383 working = DEFAULT_WORKING |
| 384 |
| 259 command = 'svn log ' + url + " -r "+str(revision) + " -v" | 385 command = 'svn log ' + url + " -r "+str(revision) + " -v" |
| 260 os.system(command) | 386 os.system(command) |
| 387 |
| 261 if not prompt("Is this the correct revision?"): | 388 if not prompt("Is this the correct revision?"): |
| 262 sys.exit(0) | 389 sys.exit(0) |
| 263 | 390 |
| 391 if (os.path.exists(working)): |
| 392 if not (SKIP_CHECK_WORKING or prompt("Working directory: '" + working + "' a
lready exists, clobber?")): |
| 393 sys.exit(0) |
| 394 deltree(working) |
| 395 |
| 396 os.makedirs(working) |
| 397 os.chdir(working) |
| 398 |
| 264 if (len(sys.argv) > 1): | 399 if (len(sys.argv) > 1): |
| 265 if sys.argv[2] in ['--merge','-m']: | 400 if sys.argv[2] in ['--merge','-m']: |
| 266 if (len(sys.argv) != 4): | 401 if (len(sys.argv) != 4): |
| 267 print "Please specify the branch # you want (i.e. 182) after --merge" | 402 print "Please specify the branch # you want (i.e. 182) after --merge" |
| 268 sys.exit(0) | 403 sys.exit(0) |
| 269 | 404 |
| 270 branch_url = "svn://chrome-svn/chrome/branches/" + sys.argv[3] + "/src" | 405 branch_url = BRANCH_URL.replace("$branch", sys.argv[3]) |
| 406 #Checkout everything but stuff that got added into a new dir |
| 271 checkoutRevision(url, revision, branch_url) | 407 checkoutRevision(url, revision, branch_url) |
| 408 #Merge everything that changed |
| 272 mergeRevision(url, revision) | 409 mergeRevision(url, revision) |
| 273 elif sys.argv[2] in ['--mplus','-p']: | 410 #"Export" files that were added from the source and add them to branch |
| 274 if (len(sys.argv) != 4): | 411 exportRevision(url, revision) |
| 275 print "Please specify the branch # you want (i.e. 182) after --merge" | 412 #Delete directories that were deleted (file deletes are handled in the |
| 276 sys.exit(0) | 413 #merge). |
| 277 branch_url = "svn://chrome-svn/chrome/branches/" + sys.argv[3] + "/src" | 414 deleteRevision(url, revision) |
| 278 checkoutRevision(url, revision, branch_url) | |
| 279 mergeRevision(url, revision, True) | |
| 280 elif sys.argv[2] in ['--revert','-r']: | 415 elif sys.argv[2] in ['--revert','-r']: |
| 281 if (len(sys.argv) == 4): | 416 if (len(sys.argv) == 4): |
| 282 url = "svn://chrome-svn/chrome/branches/" + sys.argv[3] + "/src" | 417 url = BRANCH_URL.replace("$branch", sys.argv[3]) |
| 283 checkoutRevision(url, revision, url) | 418 checkoutRevision(url, revision, url, True) |
| 284 revertRevision(url, revision) | 419 revertRevision(url, revision) |
| 420 revertExportRevision(url, revision) |
| 285 action = "Revert" | 421 action = "Revert" |
| 286 else: | 422 else: |
| 287 print "Unknown parameter " + sys.argv[2] | 423 print "Unknown parameter " + sys.argv[2] |
| 288 sys.exit(0) | 424 sys.exit(0) |
| 289 | 425 |
| 290 os.chdir('./src') | 426 #Check the base url so we actually find the author who made the change |
| 291 # Check the base url so we actually find the author who made the change. | 427 author = getAuthor(TRUNK_URL, revision) |
| 292 author = getAuthor(BASE_URL, revision) | 428 |
| 293 filename = str(revision)+".txt" | 429 filename = str(revision)+".txt" |
| 294 out = open(filename,"w") | 430 out = open(filename,"w") |
| 295 out.write(action +" " + str(revision) + " - ") | 431 out.write(action +" " + str(revision) + " - ") |
| 296 out.write(getRevisionLog(url, revision)) | 432 out.write(getRevisionLog(url, revision)) |
| 297 if (author): | 433 if (author): |
| 298 out.write("TBR=" + author) | 434 out.write("TBR=" + author) |
| 299 out.close() | 435 out.close() |
| 436 |
| 300 os.system('gcl change ' + str(revision) + " " + filename) | 437 os.system('gcl change ' + str(revision) + " " + filename) |
| 301 os.unlink(filename) | 438 os.unlink(filename) |
| 302 print author | 439 print author |
| 303 print revision | 440 print revision |
| 304 print "gcl upload " + str(revision) + " --send_mail --no_try --no_presubmit --
reviewers=" + author | 441 print ("gcl upload " + str(revision) + |
| 442 " --send_mail --no_try --no_presubmit --reviewers=" + author) |
| 305 print "gcl commit " + str(revision) + " --no_presubmit --force" | 443 print "gcl commit " + str(revision) + " --no_presubmit --force" |
| 306 print "gcl delete " + str(revision) | 444 print "gcl delete " + str(revision) |
| 307 | 445 |
| 308 if prompt("Would you like to upload?"): | 446 if prompt("Would you like to upload?"): |
| 447 if PROMPT_FOR_AUTHOR: |
| 448 author = text_prompt("Enter a new author or press enter to accept default"
, author) |
| 309 gclUpload(revision, author) | 449 gclUpload(revision, author) |
| 310 else: | 450 else: |
| 311 print "Deleting the changelist." | 451 print "Deleting the changelist." |
| 312 os.system("gcl delete " + str(revision)) | 452 os.system("gcl delete " + str(revision)) |
| 313 sys.exit(0) | 453 sys.exit(0) |
| 314 | 454 |
| 315 if prompt("Would you like to commit?"): | 455 if prompt("Would you like to commit?"): |
| 316 os.system("gcl commit " + str(revision) + " --no_presubmit --force") | 456 os.system("gcl commit " + str(revision) + " --no_presubmit --force") |
| 317 else: | 457 else: |
| 318 sys.exit(0) | 458 sys.exit(0) |
| 319 | 459 |
| 320 | |
| 321 if __name__ == "__main__": | 460 if __name__ == "__main__": |
| 322 sys.exit(main()) | 461 sys.exit(main()) |
| OLD | NEW |