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 |