| 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 |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 def WriteFile(filename, contents): | 241 def WriteFile(filename, contents): |
| 242 """Overwrites the file with the given contents.""" | 242 """Overwrites the file with the given contents.""" |
| 243 file = open(filename, 'w') | 243 file = open(filename, 'w') |
| 244 file.write(contents) | 244 file.write(contents) |
| 245 file.close() | 245 file.close() |
| 246 | 246 |
| 247 | 247 |
| 248 class ChangeInfo(object): | 248 class ChangeInfo(object): |
| 249 """Holds information about a changelist. | 249 """Holds information about a changelist. |
| 250 | 250 |
| 251 issue: the Rietveld issue number, of "" if it hasn't been uploaded yet. | 251 name: change name. |
| 252 issue: the Rietveld issue number or 0 if it hasn't been uploaded yet. |
| 253 patchset: the Rietveld latest patchset number or 0. |
| 252 description: the description. | 254 description: the description. |
| 253 files: a list of 2 tuple containing (status, filename) of changed files, | 255 files: a list of 2 tuple containing (status, filename) of changed files, |
| 254 with paths being relative to the top repository directory. | 256 with paths being relative to the top repository directory. |
| 255 """ | 257 """ |
| 256 def __init__(self, name="", issue="", description="", files=None): | 258 |
| 259 _SEPARATOR = "\n-----\n" |
| 260 # The info files have the following format: |
| 261 # issue_id, patchset\n (, patchset is optional) |
| 262 # _SEPARATOR\n |
| 263 # filepath1\n |
| 264 # filepath2\n |
| 265 # . |
| 266 # . |
| 267 # filepathn\n |
| 268 # _SEPARATOR\n |
| 269 # description |
| 270 |
| 271 def __init__(self, name, issue, patchset, description, files): |
| 257 self.name = name | 272 self.name = name |
| 258 self.issue = issue | 273 self.issue = int(issue) |
| 274 self.patchset = int(patchset) |
| 259 self.description = description | 275 self.description = description |
| 260 if files is None: | 276 if files is None: |
| 261 files = [] | 277 files = [] |
| 262 self.files = files | 278 self.files = files |
| 263 self.patch = None | 279 self.patch = None |
| 264 | 280 |
| 265 def FileList(self): | 281 def FileList(self): |
| 266 """Returns a list of files.""" | 282 """Returns a list of files.""" |
| 267 return [file[1] for file in self.files] | 283 return [file[1] for file in self.files] |
| 268 | 284 |
| 269 def _NonDeletedFileList(self): | 285 def _NonDeletedFileList(self): |
| 270 """Returns a list of files in this change, not including deleted files.""" | 286 """Returns a list of files in this change, not including deleted files.""" |
| 271 return [file[1] for file in self.files if not file[0].startswith("D")] | 287 return [file[1] for file in self.files if not file[0].startswith("D")] |
| 272 | 288 |
| 273 def _AddedFileList(self): | 289 def _AddedFileList(self): |
| 274 """Returns a list of files added in this change.""" | 290 """Returns a list of files added in this change.""" |
| 275 return [file[1] for file in self.files if file[0].startswith("A")] | 291 return [file[1] for file in self.files if file[0].startswith("A")] |
| 276 | 292 |
| 277 def Save(self): | 293 def Save(self): |
| 278 """Writes the changelist information to disk.""" | 294 """Writes the changelist information to disk.""" |
| 279 data = SEPARATOR.join([self.issue, | 295 data = ChangeInfo._SEPARATOR.join([ |
| 280 "\n".join([f[0] + f[1] for f in self.files]), | 296 "%d, %d" % (self.issue, self.patchset), |
| 281 self.description]) | 297 "\n".join([f[0] + f[1] for f in self.files]), |
| 298 self.description]) |
| 282 WriteFile(GetChangelistInfoFile(self.name), data) | 299 WriteFile(GetChangelistInfoFile(self.name), data) |
| 283 | 300 |
| 284 def Delete(self): | 301 def Delete(self): |
| 285 """Removes the changelist information from disk.""" | 302 """Removes the changelist information from disk.""" |
| 286 os.remove(GetChangelistInfoFile(self.name)) | 303 os.remove(GetChangelistInfoFile(self.name)) |
| 287 | 304 |
| 288 def CloseIssue(self): | 305 def CloseIssue(self): |
| 289 """Closes the Rietveld issue for this changelist.""" | 306 """Closes the Rietveld issue for this changelist.""" |
| 290 data = [("description", self.description),] | 307 data = [("description", self.description),] |
| 291 ctype, body = upload.EncodeMultipartFormData(data, []) | 308 ctype, body = upload.EncodeMultipartFormData(data, []) |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 if (definition != "" and | 388 if (definition != "" and |
| 372 (line == "{" or line.startswith(" ") or line.startswith("\t"))): | 389 (line == "{" or line.startswith(" ") or line.startswith("\t"))): |
| 373 definition += line | 390 definition += line |
| 374 | 391 |
| 375 # A flush-left line starts a new possible function definition. | 392 # A flush-left line starts a new possible function definition. |
| 376 elif not line.startswith(" ") and not line.startswith("\t"): | 393 elif not line.startswith(" ") and not line.startswith("\t"): |
| 377 definition = line | 394 definition = line |
| 378 | 395 |
| 379 return False | 396 return False |
| 380 | 397 |
| 398 @staticmethod |
| 399 def Load(changename, fail_on_not_found=True, update_status=False): |
| 400 """Gets information about a changelist. |
| 381 | 401 |
| 382 SEPARATOR = "\n-----\n" | 402 Args: |
| 383 # The info files have the following format: | 403 fail_on_not_found: if True, this function will quit the program if the |
| 384 # issue_id\n | 404 changelist doesn't exist. |
| 385 # SEPARATOR\n | 405 update_status: if True, the svn status will be updated for all the files |
| 386 # filepath1\n | 406 and unchanged files will be removed. |
| 387 # filepath2\n | 407 |
| 388 # . | 408 Returns: a ChangeInfo object. |
| 389 # . | 409 """ |
| 390 # filepathn\n | 410 info_file = GetChangelistInfoFile(changename) |
| 391 # SEPARATOR\n | 411 if not os.path.exists(info_file): |
| 392 # description | 412 if fail_on_not_found: |
| 413 ErrorExit("Changelist " + changename + " not found.") |
| 414 return ChangeInfo(changename) |
| 415 split_data = ReadFile(info_file).split(ChangeInfo._SEPARATOR, 2) |
| 416 if len(split_data) != 3: |
| 417 ErrorExit("Changelist file %s is corrupt" % info_file) |
| 418 items = split_data[0].split(',') |
| 419 issue = 0 |
| 420 patchset = 0 |
| 421 if items[0]: |
| 422 issue = int(items[0]) |
| 423 if len(items) > 1: |
| 424 patchset = int(items[1]) |
| 425 files = [] |
| 426 for line in split_data[1].splitlines(): |
| 427 status = line[:7] |
| 428 file = line[7:] |
| 429 files.append((status, file)) |
| 430 description = split_data[2] |
| 431 save = False |
| 432 if update_status: |
| 433 for file in files: |
| 434 filename = os.path.join(GetRepositoryRoot(), file[1]) |
| 435 status_result = gclient.CaptureSVNStatus(filename) |
| 436 if not status_result or not status_result[0][0]: |
| 437 # File has been reverted. |
| 438 save = True |
| 439 files.remove(file) |
| 440 continue |
| 441 status = status_result[0][0] |
| 442 if status != file[0]: |
| 443 save = True |
| 444 files[files.index(file)] = (status, file[1]) |
| 445 change_info = ChangeInfo(changename, issue, patchset, description, files) |
| 446 if save: |
| 447 change_info.Save() |
| 448 return change_info |
| 393 | 449 |
| 394 | 450 |
| 395 def GetChangelistInfoFile(changename): | 451 def GetChangelistInfoFile(changename): |
| 396 """Returns the file that stores information about a changelist.""" | 452 """Returns the file that stores information about a changelist.""" |
| 397 if not changename or re.search(r'[^\w-]', changename): | 453 if not changename or re.search(r'[^\w-]', changename): |
| 398 ErrorExit("Invalid changelist name: " + changename) | 454 ErrorExit("Invalid changelist name: " + changename) |
| 399 return os.path.join(GetChangesDir(), changename) | 455 return os.path.join(GetChangesDir(), changename) |
| 400 | 456 |
| 401 | 457 |
| 402 def LoadChangelistInfoForMultiple(changenames, fail_on_not_found=True, | 458 def LoadChangelistInfoForMultiple(changenames, fail_on_not_found=True, |
| 403 update_status=False): | 459 update_status=False): |
| 404 """Loads many changes and merge their files list into one pseudo change. | 460 """Loads many changes and merge their files list into one pseudo change. |
| 405 | 461 |
| 406 This is mainly usefull to concatenate many changes into one for a 'gcl try'. | 462 This is mainly usefull to concatenate many changes into one for a 'gcl try'. |
| 407 """ | 463 """ |
| 408 changes = changenames.split(',') | 464 changes = changenames.split(',') |
| 409 aggregate_change_info = ChangeInfo(name=changenames) | 465 aggregate_change_info = ChangeInfo(changenames, 0, 0, '', None) |
| 410 for change in changes: | 466 for change in changes: |
| 411 aggregate_change_info.files += LoadChangelistInfo(change, | 467 aggregate_change_info.files += ChangeInfo.Load(change, fail_on_not_found, |
| 412 fail_on_not_found, | 468 update_status).files |
| 413 update_status).files | |
| 414 return aggregate_change_info | 469 return aggregate_change_info |
| 415 | 470 |
| 416 | 471 |
| 417 def LoadChangelistInfo(changename, fail_on_not_found=True, | |
| 418 update_status=False): | |
| 419 """Gets information about a changelist. | |
| 420 | |
| 421 Args: | |
| 422 fail_on_not_found: if True, this function will quit the program if the | |
| 423 changelist doesn't exist. | |
| 424 update_status: if True, the svn status will be updated for all the files | |
| 425 and unchanged files will be removed. | |
| 426 | |
| 427 Returns: a ChangeInfo object. | |
| 428 """ | |
| 429 info_file = GetChangelistInfoFile(changename) | |
| 430 if not os.path.exists(info_file): | |
| 431 if fail_on_not_found: | |
| 432 ErrorExit("Changelist " + changename + " not found.") | |
| 433 return ChangeInfo(changename) | |
| 434 data = ReadFile(info_file) | |
| 435 split_data = data.split(SEPARATOR, 2) | |
| 436 if len(split_data) != 3: | |
| 437 os.remove(info_file) | |
| 438 ErrorExit("Changelist file %s was corrupt and deleted" % info_file) | |
| 439 issue = split_data[0] | |
| 440 files = [] | |
| 441 for line in split_data[1].splitlines(): | |
| 442 status = line[:7] | |
| 443 file = line[7:] | |
| 444 files.append((status, file)) | |
| 445 description = split_data[2] | |
| 446 save = False | |
| 447 if update_status: | |
| 448 for file in files: | |
| 449 filename = os.path.join(GetRepositoryRoot(), file[1]) | |
| 450 status_result = gclient.CaptureSVNStatus(filename) | |
| 451 if not status_result or not status_result[0][0]: | |
| 452 # File has been reverted. | |
| 453 save = True | |
| 454 files.remove(file) | |
| 455 continue | |
| 456 status = status_result[0][0] | |
| 457 if status != file[0]: | |
| 458 save = True | |
| 459 files[files.index(file)] = (status, file[1]) | |
| 460 change_info = ChangeInfo(changename, issue, description, files) | |
| 461 if save: | |
| 462 change_info.Save() | |
| 463 return change_info | |
| 464 | |
| 465 | |
| 466 def GetCLs(): | 472 def GetCLs(): |
| 467 """Returns a list of all the changelists in this repository.""" | 473 """Returns a list of all the changelists in this repository.""" |
| 468 cls = os.listdir(GetChangesDir()) | 474 cls = os.listdir(GetChangesDir()) |
| 469 if CODEREVIEW_SETTINGS_FILE in cls: | 475 if CODEREVIEW_SETTINGS_FILE in cls: |
| 470 cls.remove(CODEREVIEW_SETTINGS_FILE) | 476 cls.remove(CODEREVIEW_SETTINGS_FILE) |
| 471 return cls | 477 return cls |
| 472 | 478 |
| 473 | 479 |
| 474 def GenerateChangeName(): | 480 def GenerateChangeName(): |
| 475 """Generate a random changelist name.""" | 481 """Generate a random changelist name.""" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 494 """ | 500 """ |
| 495 files = {} | 501 files = {} |
| 496 | 502 |
| 497 # Since the files are normalized to the root folder of the repositary, figure | 503 # Since the files are normalized to the root folder of the repositary, figure |
| 498 # out what we need to add to the paths. | 504 # out what we need to add to the paths. |
| 499 dir_prefix = os.getcwd()[len(GetRepositoryRoot()):].strip(os.sep) | 505 dir_prefix = os.getcwd()[len(GetRepositoryRoot()):].strip(os.sep) |
| 500 | 506 |
| 501 # Get a list of all files in changelists. | 507 # Get a list of all files in changelists. |
| 502 files_in_cl = {} | 508 files_in_cl = {} |
| 503 for cl in GetCLs(): | 509 for cl in GetCLs(): |
| 504 change_info = LoadChangelistInfo(cl) | 510 change_info = ChangeInfo.Load(cl) |
| 505 for status, filename in change_info.files: | 511 for status, filename in change_info.files: |
| 506 files_in_cl[filename] = change_info.name | 512 files_in_cl[filename] = change_info.name |
| 507 | 513 |
| 508 # Get all the modified files. | 514 # Get all the modified files. |
| 509 status_result = gclient.CaptureSVNStatus(None) | 515 status_result = gclient.CaptureSVNStatus(None) |
| 510 for line in status_result: | 516 for line in status_result: |
| 511 status = line[0] | 517 status = line[0] |
| 512 filename = line[1] | 518 filename = line[1] |
| 513 if status[0] == "?": | 519 if status[0] == "?": |
| 514 continue | 520 continue |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 return rpc_server.Send(request_path, payload, content_type, timeout) | 558 return rpc_server.Send(request_path, payload, content_type, timeout) |
| 553 except urllib2.URLError, e: | 559 except urllib2.URLError, e: |
| 554 if timeout is None: | 560 if timeout is None: |
| 555 ErrorExit("Error accessing url %s" % request_path) | 561 ErrorExit("Error accessing url %s" % request_path) |
| 556 else: | 562 else: |
| 557 return None | 563 return None |
| 558 | 564 |
| 559 | 565 |
| 560 def GetIssueDescription(issue): | 566 def GetIssueDescription(issue): |
| 561 """Returns the issue description from Rietveld.""" | 567 """Returns the issue description from Rietveld.""" |
| 562 return SendToRietveld("/" + issue + "/description") | 568 return SendToRietveld("/%d/description" % issue) |
| 563 | 569 |
| 564 | 570 |
| 565 def Opened(): | 571 def Opened(): |
| 566 """Prints a list of modified files in the current directory down.""" | 572 """Prints a list of modified files in the current directory down.""" |
| 567 files = GetModifiedFiles() | 573 files = GetModifiedFiles() |
| 568 cl_keys = files.keys() | 574 cl_keys = files.keys() |
| 569 cl_keys.sort() | 575 cl_keys.sort() |
| 570 for cl_name in cl_keys: | 576 for cl_name in cl_keys: |
| 571 if cl_name: | 577 if cl_name: |
| 572 note = "" | 578 note = "" |
| 573 if len(LoadChangelistInfo(cl_name).files) != len(files[cl_name]): | 579 if len(ChangeInfo.Load(cl_name).files) != len(files[cl_name]): |
| 574 note = " (Note: this changelist contains files outside this directory)" | 580 note = " (Note: this changelist contains files outside this directory)" |
| 575 print "\n--- Changelist " + cl_name + note + ":" | 581 print "\n--- Changelist " + cl_name + note + ":" |
| 576 for file in files[cl_name]: | 582 for file in files[cl_name]: |
| 577 print "".join(file) | 583 print "".join(file) |
| 578 | 584 |
| 579 | 585 |
| 580 def Help(argv=None): | 586 def Help(argv=None): |
| 581 if argv: | 587 if argv: |
| 582 if argv[0] == 'try': | 588 if argv[0] == 'try': |
| 583 TryChange(None, ['--help'], swallow_exception=False) | 589 TryChange(None, ['--help'], swallow_exception=False) |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 if change_info.issue: # Uploading a new patchset. | 760 if change_info.issue: # Uploading a new patchset. |
| 755 found_message = False | 761 found_message = False |
| 756 for arg in args: | 762 for arg in args: |
| 757 if arg.startswith("--message") or arg.startswith("-m"): | 763 if arg.startswith("--message") or arg.startswith("-m"): |
| 758 found_message = True | 764 found_message = True |
| 759 break | 765 break |
| 760 | 766 |
| 761 if not found_message: | 767 if not found_message: |
| 762 upload_arg.append("--message=''") | 768 upload_arg.append("--message=''") |
| 763 | 769 |
| 764 upload_arg.append("--issue=" + change_info.issue) | 770 upload_arg.append("--issue=%d" % change_info.issue) |
| 765 else: # First time we upload. | 771 else: # First time we upload. |
| 766 handle, desc_file = tempfile.mkstemp(text=True) | 772 handle, desc_file = tempfile.mkstemp(text=True) |
| 767 os.write(handle, change_info.description) | 773 os.write(handle, change_info.description) |
| 768 os.close(handle) | 774 os.close(handle) |
| 769 | 775 |
| 770 cc_list = GetCodeReviewSetting("CC_LIST") | 776 cc_list = GetCodeReviewSetting("CC_LIST") |
| 771 if cc_list: | 777 if cc_list: |
| 772 upload_arg.append("--cc=" + cc_list) | 778 upload_arg.append("--cc=" + cc_list) |
| 773 upload_arg.append("--description_file=" + desc_file + "") | 779 upload_arg.append("--description_file=" + desc_file + "") |
| 774 if change_info.description: | 780 if change_info.description: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 785 # shows the correct base. | 791 # shows the correct base. |
| 786 previous_cwd = os.getcwd() | 792 previous_cwd = os.getcwd() |
| 787 os.chdir(GetRepositoryRoot()) | 793 os.chdir(GetRepositoryRoot()) |
| 788 | 794 |
| 789 # If we have a lot of files with long paths, then we won't be able to fit | 795 # If we have a lot of files with long paths, then we won't be able to fit |
| 790 # the command to "svn diff". Instead, we generate the diff manually for | 796 # the command to "svn diff". Instead, we generate the diff manually for |
| 791 # each file and concatenate them before passing it to upload.py. | 797 # each file and concatenate them before passing it to upload.py. |
| 792 if change_info.patch is None: | 798 if change_info.patch is None: |
| 793 change_info.patch = GenerateDiff(change_info.FileList()) | 799 change_info.patch = GenerateDiff(change_info.FileList()) |
| 794 issue, patchset = upload.RealMain(upload_arg, change_info.patch) | 800 issue, patchset = upload.RealMain(upload_arg, change_info.patch) |
| 795 if issue and issue != change_info.issue: | 801 if issue and patchset: |
| 796 change_info.issue = issue | 802 change_info.issue = int(issue) |
| 803 change_info.patchset = int(patchset) |
| 797 change_info.Save() | 804 change_info.Save() |
| 798 | 805 |
| 799 if desc_file: | 806 if desc_file: |
| 800 os.remove(desc_file) | 807 os.remove(desc_file) |
| 801 | 808 |
| 802 # Do background work on Rietveld to lint the file so that the results are | 809 # Do background work on Rietveld to lint the file so that the results are |
| 803 # ready when the issue is viewed. | 810 # ready when the issue is viewed. |
| 804 SendToRietveld("/lint/issue%s_%s" % (issue, patchset), timeout=0.5) | 811 SendToRietveld("/lint/issue%s_%s" % (issue, patchset), timeout=0.5) |
| 805 | 812 |
| 806 # Once uploaded to Rietveld, send it to the try server. | 813 # Once uploaded to Rietveld, send it to the try server. |
| 807 if not no_try: | 814 if not no_try: |
| 808 try_on_upload = GetCodeReviewSetting('TRY_ON_UPLOAD') | 815 try_on_upload = GetCodeReviewSetting('TRY_ON_UPLOAD') |
| 809 if try_on_upload and try_on_upload.lower() == 'true': | 816 if try_on_upload and try_on_upload.lower() == 'true': |
| 810 # Use the local diff. | 817 trychange_args = [] |
| 811 args = [ | |
| 812 "--issue", change_info.issue, | |
| 813 "--patchset", patchset, | |
| 814 ] | |
| 815 if clobber: | 818 if clobber: |
| 816 args.append('--clobber') | 819 trychange_args.append('--clobber') |
| 817 TryChange(change_info, args, swallow_exception=True) | 820 TryChange(change_info, trychange_args, swallow_exception=True) |
| 818 | 821 |
| 819 os.chdir(previous_cwd) | 822 os.chdir(previous_cwd) |
| 820 | 823 |
| 821 | 824 |
| 822 def PresubmitCL(change_info): | 825 def PresubmitCL(change_info): |
| 823 """Reports what presubmit checks on the change would report.""" | 826 """Reports what presubmit checks on the change would report.""" |
| 824 if not change_info.FileList(): | 827 if not change_info.FileList(): |
| 825 print "Nothing to presubmit check, changelist is empty." | 828 print "Nothing to presubmit check, changelist is empty." |
| 826 return | 829 return |
| 827 | 830 |
| 828 print "*** Presubmit checks for UPLOAD would report: ***" | 831 print "*** Presubmit checks for UPLOAD would report: ***" |
| 829 DoPresubmitChecks(change_info, committing=False) | 832 DoPresubmitChecks(change_info, committing=False) |
| 830 | 833 |
| 831 print "\n\n*** Presubmit checks for COMMIT would report: ***" | 834 print "\n\n*** Presubmit checks for COMMIT would report: ***" |
| 832 DoPresubmitChecks(change_info, committing=True) | 835 DoPresubmitChecks(change_info, committing=True) |
| 833 | 836 |
| 834 | 837 |
| 835 def TryChange(change_info, args, swallow_exception): | 838 def TryChange(change_info, args, swallow_exception): |
| 836 """Create a diff file of change_info and send it to the try server.""" | 839 """Create a diff file of change_info and send it to the try server.""" |
| 837 try: | 840 try: |
| 838 import trychange | 841 import trychange |
| 839 except ImportError: | 842 except ImportError: |
| 840 if swallow_exception: | 843 if swallow_exception: |
| 841 return | 844 return |
| 842 ErrorExit("You need to install trychange.py to use the try server.") | 845 ErrorExit("You need to install trychange.py to use the try server.") |
| 843 | 846 |
| 844 if change_info: | 847 if change_info: |
| 845 trychange_args = ['--name', change_info.name] | 848 trychange_args = ['--name', change_info.name] |
| 849 if change_info.issue: |
| 850 trychange_args.extend(["--issue", str(change_info.issue)]) |
| 851 if change_info.patchset: |
| 852 trychange_args.extend(["--patchset", str(change_info.patchset)]) |
| 846 trychange_args.extend(args) | 853 trychange_args.extend(args) |
| 847 trychange.TryChange(trychange_args, | 854 trychange.TryChange(trychange_args, |
| 848 file_list=change_info.FileList(), | 855 file_list=change_info.FileList(), |
| 849 swallow_exception=swallow_exception, | 856 swallow_exception=swallow_exception, |
| 850 prog='gcl try') | 857 prog='gcl try') |
| 851 else: | 858 else: |
| 852 trychange.TryChange(args, | 859 trychange.TryChange(args, |
| 853 file_list=None, | 860 file_list=None, |
| 854 swallow_exception=swallow_exception, | 861 swallow_exception=swallow_exception, |
| 855 prog='gcl try') | 862 prog='gcl try') |
| (...skipping 18 matching lines...) Expand all Loading... |
| 874 # you'll get "svn: Cannot non-recursively commit a directory deletion of a | 881 # you'll get "svn: Cannot non-recursively commit a directory deletion of a |
| 875 # directory with child nodes". Yay... | 882 # directory with child nodes". Yay... |
| 876 commit_cmd = ["svn", "commit"] | 883 commit_cmd = ["svn", "commit"] |
| 877 filename = '' | 884 filename = '' |
| 878 if change_info.issue: | 885 if change_info.issue: |
| 879 # Get the latest description from Rietveld. | 886 # Get the latest description from Rietveld. |
| 880 change_info.description = GetIssueDescription(change_info.issue) | 887 change_info.description = GetIssueDescription(change_info.issue) |
| 881 | 888 |
| 882 commit_message = change_info.description.replace('\r\n', '\n') | 889 commit_message = change_info.description.replace('\r\n', '\n') |
| 883 if change_info.issue: | 890 if change_info.issue: |
| 884 commit_message += ('\nReview URL: http://%s/%s' % | 891 commit_message += ('\nReview URL: http://%s/%d' % |
| 885 (GetCodeReviewSetting("CODE_REVIEW_SERVER"), | 892 (GetCodeReviewSetting("CODE_REVIEW_SERVER"), |
| 886 change_info.issue)) | 893 change_info.issue)) |
| 887 | 894 |
| 888 handle, commit_filename = tempfile.mkstemp(text=True) | 895 handle, commit_filename = tempfile.mkstemp(text=True) |
| 889 os.write(handle, commit_message) | 896 os.write(handle, commit_message) |
| 890 os.close(handle) | 897 os.close(handle) |
| 891 | 898 |
| 892 handle, targets_filename = tempfile.mkstemp(text=True) | 899 handle, targets_filename = tempfile.mkstemp(text=True) |
| 893 os.write(handle, "\n".join(change_info.FileList())) | 900 os.write(handle, "\n".join(change_info.FileList())) |
| 894 os.close(handle) | 901 os.close(handle) |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1034 input_stream=sys.stdin, | 1041 input_stream=sys.stdin, |
| 1035 default_presubmit=root_presubmit) | 1042 default_presubmit=root_presubmit) |
| 1036 if not result: | 1043 if not result: |
| 1037 print "\nPresubmit errors, can't continue (use --no_presubmit to bypass)" | 1044 print "\nPresubmit errors, can't continue (use --no_presubmit to bypass)" |
| 1038 return result | 1045 return result |
| 1039 | 1046 |
| 1040 | 1047 |
| 1041 def Changes(): | 1048 def Changes(): |
| 1042 """Print all the changelists and their files.""" | 1049 """Print all the changelists and their files.""" |
| 1043 for cl in GetCLs(): | 1050 for cl in GetCLs(): |
| 1044 change_info = LoadChangelistInfo(cl, True, True) | 1051 change_info = ChangeInfo.Load(cl, True, True) |
| 1045 print "\n--- Changelist " + change_info.name + ":" | 1052 print "\n--- Changelist " + change_info.name + ":" |
| 1046 for file in change_info.files: | 1053 for file in change_info.files: |
| 1047 print "".join(file) | 1054 print "".join(file) |
| 1048 | 1055 |
| 1049 | 1056 |
| 1050 def main(argv=None): | 1057 def main(argv=None): |
| 1051 if argv is None: | 1058 if argv is None: |
| 1052 argv = sys.argv | 1059 argv = sys.argv |
| 1053 | 1060 |
| 1054 if len(argv) == 1: | 1061 if len(argv) == 1: |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1108 else: | 1115 else: |
| 1109 changename = argv[2] | 1116 changename = argv[2] |
| 1110 | 1117 |
| 1111 # When the command is 'try' and --patchset is used, the patch to try | 1118 # When the command is 'try' and --patchset is used, the patch to try |
| 1112 # is on the Rietveld server. 'change' creates a change so it's fine if the | 1119 # is on the Rietveld server. 'change' creates a change so it's fine if the |
| 1113 # change didn't exist. All other commands require an existing change. | 1120 # change didn't exist. All other commands require an existing change. |
| 1114 fail_on_not_found = command != "try" and command != "change" | 1121 fail_on_not_found = command != "try" and command != "change" |
| 1115 if command == "try" and changename.find(',') != -1: | 1122 if command == "try" and changename.find(',') != -1: |
| 1116 change_info = LoadChangelistInfoForMultiple(changename, True, True) | 1123 change_info = LoadChangelistInfoForMultiple(changename, True, True) |
| 1117 else: | 1124 else: |
| 1118 change_info = LoadChangelistInfo(changename, fail_on_not_found, True) | 1125 change_info = ChangeInfo.Load(changename, fail_on_not_found, True) |
| 1119 | 1126 |
| 1120 if command == "change": | 1127 if command == "change": |
| 1121 if (len(argv) == 4): | 1128 if (len(argv) == 4): |
| 1122 filename = argv[3] | 1129 filename = argv[3] |
| 1123 f = open(filename, 'rU') | 1130 f = open(filename, 'rU') |
| 1124 override_description = f.read() | 1131 override_description = f.read() |
| 1125 f.close() | 1132 f.close() |
| 1126 else: | 1133 else: |
| 1127 override_description = None | 1134 override_description = None |
| 1128 Change(change_info, override_description) | 1135 Change(change_info, override_description) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1150 # the files. This allows commands such as 'gcl diff xxx' to work. | 1157 # the files. This allows commands such as 'gcl diff xxx' to work. |
| 1151 args =["svn", command] | 1158 args =["svn", command] |
| 1152 root = GetRepositoryRoot() | 1159 root = GetRepositoryRoot() |
| 1153 args.extend([os.path.join(root, x) for x in change_info.FileList()]) | 1160 args.extend([os.path.join(root, x) for x in change_info.FileList()]) |
| 1154 RunShell(args, True) | 1161 RunShell(args, True) |
| 1155 return 0 | 1162 return 0 |
| 1156 | 1163 |
| 1157 | 1164 |
| 1158 if __name__ == "__main__": | 1165 if __name__ == "__main__": |
| 1159 sys.exit(main()) | 1166 sys.exit(main()) |
| OLD | NEW |