OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2010 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 """\ | 6 """\ |
7 Wrapper script around Rietveld's upload.py that simplifies working with groups | 7 Wrapper script around Rietveld's upload.py that simplifies working with groups |
8 of files. | 8 of files. |
9 """ | 9 """ |
10 | 10 |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 class ChangeInfo(object): | 267 class ChangeInfo(object): |
268 """Holds information about a changelist. | 268 """Holds information about a changelist. |
269 | 269 |
270 name: change name. | 270 name: change name. |
271 issue: the Rietveld issue number or 0 if it hasn't been uploaded yet. | 271 issue: the Rietveld issue number or 0 if it hasn't been uploaded yet. |
272 patchset: the Rietveld latest patchset number or 0. | 272 patchset: the Rietveld latest patchset number or 0. |
273 description: the description. | 273 description: the description. |
274 files: a list of 2 tuple containing (status, filename) of changed files, | 274 files: a list of 2 tuple containing (status, filename) of changed files, |
275 with paths being relative to the top repository directory. | 275 with paths being relative to the top repository directory. |
276 local_root: Local root directory | 276 local_root: Local root directory |
| 277 rietveld: rietveld server for this change |
277 """ | 278 """ |
278 | 279 # Kept for unit test support. This is for the old format, it's deprecated. |
279 _SEPARATOR = "\n-----\n" | 280 _SEPARATOR = "\n-----\n" |
280 # The info files have the following format: | |
281 # issue_id, patchset\n (, patchset is optional) | |
282 # _SEPARATOR\n | |
283 # filepath1\n | |
284 # filepath2\n | |
285 # . | |
286 # . | |
287 # filepathn\n | |
288 # _SEPARATOR\n | |
289 # description | |
290 | 281 |
291 def __init__(self, name, issue, patchset, description, files, local_root, | 282 def __init__(self, name, issue, patchset, description, files, local_root, |
292 needs_upload=False): | 283 rietveld, needs_upload=False): |
293 self.name = name | 284 self.name = name |
294 self.issue = int(issue) | 285 self.issue = int(issue) |
295 self.patchset = int(patchset) | 286 self.patchset = int(patchset) |
296 self.description = description | 287 self.description = description |
297 if files is None: | 288 if files is None: |
298 files = [] | 289 files = [] |
299 self._files = files | 290 self._files = files |
300 self.patch = None | 291 self.patch = None |
301 self._local_root = local_root | 292 self._local_root = local_root |
302 self.needs_upload = needs_upload | 293 self.needs_upload = needs_upload |
| 294 self.rietveld = rietveld |
| 295 if not self.rietveld: |
| 296 # Set the default value. |
| 297 self.rietveld = GetCodeReviewSetting('CODE_REVIEW_SERVER') |
303 | 298 |
304 def NeedsUpload(self): | 299 def NeedsUpload(self): |
305 return self.needs_upload | 300 return self.needs_upload |
306 | 301 |
307 def GetFileNames(self): | 302 def GetFileNames(self): |
308 """Returns the list of file names included in this change.""" | 303 """Returns the list of file names included in this change.""" |
309 return [f[1] for f in self._files] | 304 return [f[1] for f in self._files] |
310 | 305 |
311 def GetFiles(self): | 306 def GetFiles(self): |
312 """Returns the list of files included in this change with their status.""" | 307 """Returns the list of files included in this change with their status.""" |
(...skipping 17 matching lines...) Expand all Loading... |
330 return [f[1] for f in self.GetFiles() if f[0].startswith("A")] | 325 return [f[1] for f in self.GetFiles() if f[0].startswith("A")] |
331 | 326 |
332 def Save(self): | 327 def Save(self): |
333 """Writes the changelist information to disk.""" | 328 """Writes the changelist information to disk.""" |
334 data = json.dumps({ | 329 data = json.dumps({ |
335 'issue': self.issue, | 330 'issue': self.issue, |
336 'patchset': self.patchset, | 331 'patchset': self.patchset, |
337 'needs_upload': self.NeedsUpload(), | 332 'needs_upload': self.NeedsUpload(), |
338 'files': self.GetFiles(), | 333 'files': self.GetFiles(), |
339 'description': self.description, | 334 'description': self.description, |
| 335 'rietveld': self.rietveld, |
340 }, sort_keys=True, indent=2) | 336 }, sort_keys=True, indent=2) |
341 gclient_utils.FileWrite(GetChangelistInfoFile(self.name), data) | 337 gclient_utils.FileWrite(GetChangelistInfoFile(self.name), data) |
342 | 338 |
343 def Delete(self): | 339 def Delete(self): |
344 """Removes the changelist information from disk.""" | 340 """Removes the changelist information from disk.""" |
345 os.remove(GetChangelistInfoFile(self.name)) | 341 os.remove(GetChangelistInfoFile(self.name)) |
346 | 342 |
347 def CloseIssue(self): | 343 def CloseIssue(self): |
348 """Closes the Rietveld issue for this changelist.""" | 344 """Closes the Rietveld issue for this changelist.""" |
349 data = [("description", self.description),] | 345 data = [("description", self.description),] |
350 ctype, body = upload.EncodeMultipartFormData(data, []) | 346 ctype, body = upload.EncodeMultipartFormData(data, []) |
351 SendToRietveld("/%d/close" % self.issue, body, ctype) | 347 self.SendToRietveld('/%d/close' % self.issue, body, ctype) |
352 | 348 |
353 def UpdateRietveldDescription(self): | 349 def UpdateRietveldDescription(self): |
354 """Sets the description for an issue on Rietveld.""" | 350 """Sets the description for an issue on Rietveld.""" |
355 data = [("description", self.description),] | 351 data = [("description", self.description),] |
356 ctype, body = upload.EncodeMultipartFormData(data, []) | 352 ctype, body = upload.EncodeMultipartFormData(data, []) |
357 SendToRietveld("/%d/description" % self.issue, body, ctype) | 353 self.SendToRietveld('/%d/description' % self.issue, body, ctype) |
| 354 |
| 355 def GetIssueDescription(self): |
| 356 """Returns the issue description from Rietveld.""" |
| 357 return self.SendToRietveld('/%d/description' % self.issue) |
| 358 |
| 359 def PrimeLint(self): |
| 360 """Do background work on Rietveld to lint the file so that the results are |
| 361 ready when the issue is viewed.""" |
| 362 if self.issue and self.patchset: |
| 363 self.SendToRietveld('/lint/issue%s_%s' % (self.issue, self.patchset), |
| 364 timeout=1) |
| 365 |
| 366 def SendToRietveld(self, request_path, payload=None, |
| 367 content_type="application/octet-stream", timeout=None): |
| 368 """Send a POST/GET to Rietveld. Returns the response body.""" |
| 369 if not self.rietveld: |
| 370 ErrorExit(CODEREVIEW_SETTINGS_FILE_NOT_FOUND) |
| 371 def GetUserCredentials(): |
| 372 """Prompts the user for a username and password.""" |
| 373 email = upload.GetEmail('Email (login for uploading to %s)' % |
| 374 self.rietveld) |
| 375 password = getpass.getpass('Password for %s: ' % email) |
| 376 return email, password |
| 377 rpc_server = upload.HttpRpcServer(self.rietveld, |
| 378 GetUserCredentials, |
| 379 save_cookies=True) |
| 380 try: |
| 381 return rpc_server.Send(request_path, payload, content_type, timeout) |
| 382 except urllib2.URLError: |
| 383 if timeout is None: |
| 384 ErrorExit('Error accessing url %s' % request_path) |
| 385 else: |
| 386 return None |
358 | 387 |
359 def MissingTests(self): | 388 def MissingTests(self): |
360 """Returns True if the change looks like it needs unit tests but has none. | 389 """Returns True if the change looks like it needs unit tests but has none. |
361 | 390 |
362 A change needs unit tests if it contains any new source files or methods. | 391 A change needs unit tests if it contains any new source files or methods. |
363 """ | 392 """ |
364 SOURCE_SUFFIXES = [".cc", ".cpp", ".c", ".m", ".mm"] | 393 SOURCE_SUFFIXES = [".cc", ".cpp", ".c", ".m", ".mm"] |
365 # Ignore third_party entirely. | 394 # Ignore third_party entirely. |
366 files = [f for f in self._NonDeletedFileList() | 395 files = [f for f in self._NonDeletedFileList() |
367 if f.find("third_party") == -1] | 396 if f.find("third_party") == -1] |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 changelist doesn't exist. | 475 changelist doesn't exist. |
447 update_status: if True, the svn status will be updated for all the files | 476 update_status: if True, the svn status will be updated for all the files |
448 and unchanged files will be removed. | 477 and unchanged files will be removed. |
449 | 478 |
450 Returns: a ChangeInfo object. | 479 Returns: a ChangeInfo object. |
451 """ | 480 """ |
452 info_file = GetChangelistInfoFile(changename) | 481 info_file = GetChangelistInfoFile(changename) |
453 if not os.path.exists(info_file): | 482 if not os.path.exists(info_file): |
454 if fail_on_not_found: | 483 if fail_on_not_found: |
455 ErrorExit("Changelist " + changename + " not found.") | 484 ErrorExit("Changelist " + changename + " not found.") |
456 return ChangeInfo(changename, 0, 0, '', None, local_root, | 485 return ChangeInfo(changename, 0, 0, '', None, local_root, rietveld=None, |
457 needs_upload=False) | 486 needs_upload=False) |
458 content = gclient_utils.FileRead(info_file, 'r') | 487 content = gclient_utils.FileRead(info_file, 'r') |
459 save = False | 488 save = False |
460 try: | 489 try: |
461 values = ChangeInfo._LoadNewFormat(content) | 490 values = ChangeInfo._LoadNewFormat(content) |
462 except ValueError: | 491 except ValueError: |
463 try: | 492 try: |
464 values = ChangeInfo._LoadOldFormat(content) | 493 values = ChangeInfo._LoadOldFormat(content) |
465 save = True | 494 save = True |
466 except ValueError: | 495 except ValueError: |
(...skipping 10 matching lines...) Expand all Loading... |
477 # File has been reverted. | 506 # File has been reverted. |
478 save = True | 507 save = True |
479 files.remove(item) | 508 files.remove(item) |
480 continue | 509 continue |
481 status = status_result[0][0] | 510 status = status_result[0][0] |
482 if status != item[0]: | 511 if status != item[0]: |
483 save = True | 512 save = True |
484 files[files.index(item)] = (status, item[1]) | 513 files[files.index(item)] = (status, item[1]) |
485 change_info = ChangeInfo(changename, values['issue'], values['patchset'], | 514 change_info = ChangeInfo(changename, values['issue'], values['patchset'], |
486 values['description'], files, | 515 values['description'], files, |
487 local_root, values['needs_upload']) | 516 local_root, values.get('rietveld'), |
| 517 values['needs_upload']) |
488 if save: | 518 if save: |
489 change_info.Save() | 519 change_info.Save() |
490 return change_info | 520 return change_info |
491 | 521 |
492 @staticmethod | 522 @staticmethod |
493 def _LoadOldFormat(content): | 523 def _LoadOldFormat(content): |
| 524 # The info files have the following format: |
| 525 # issue_id, patchset\n (, patchset is optional) |
| 526 # _SEPARATOR\n |
| 527 # filepath1\n |
| 528 # filepath2\n |
| 529 # . |
| 530 # . |
| 531 # filepathn\n |
| 532 # _SEPARATOR\n |
| 533 # description |
494 split_data = content.split(ChangeInfo._SEPARATOR, 2) | 534 split_data = content.split(ChangeInfo._SEPARATOR, 2) |
495 if len(split_data) != 3: | 535 if len(split_data) != 3: |
496 raise ValueError('Bad change format') | 536 raise ValueError('Bad change format') |
497 values = { | 537 values = { |
498 'issue': 0, | 538 'issue': 0, |
499 'patchset': 0, | 539 'patchset': 0, |
500 'needs_upload': False, | 540 'needs_upload': False, |
501 'files': [], | 541 'files': [], |
502 } | 542 } |
503 items = split_data[0].split(', ') | 543 items = split_data[0].split(', ') |
(...skipping 23 matching lines...) Expand all Loading... |
527 | 567 |
528 | 568 |
529 def LoadChangelistInfoForMultiple(changenames, local_root, fail_on_not_found, | 569 def LoadChangelistInfoForMultiple(changenames, local_root, fail_on_not_found, |
530 update_status): | 570 update_status): |
531 """Loads many changes and merge their files list into one pseudo change. | 571 """Loads many changes and merge their files list into one pseudo change. |
532 | 572 |
533 This is mainly usefull to concatenate many changes into one for a 'gcl try'. | 573 This is mainly usefull to concatenate many changes into one for a 'gcl try'. |
534 """ | 574 """ |
535 changes = changenames.split(',') | 575 changes = changenames.split(',') |
536 aggregate_change_info = ChangeInfo(changenames, 0, 0, '', None, local_root, | 576 aggregate_change_info = ChangeInfo(changenames, 0, 0, '', None, local_root, |
537 needs_upload=False) | 577 rietveld=None, needs_upload=False) |
538 for change in changes: | 578 for change in changes: |
539 aggregate_change_info._files += ChangeInfo.Load(change, | 579 aggregate_change_info._files += ChangeInfo.Load(change, |
540 local_root, | 580 local_root, |
541 fail_on_not_found, | 581 fail_on_not_found, |
542 update_status).GetFiles() | 582 update_status).GetFiles() |
543 return aggregate_change_info | 583 return aggregate_change_info |
544 | 584 |
545 | 585 |
546 def GetCLs(): | 586 def GetCLs(): |
547 """Returns a list of all the changelists in this repository.""" | 587 """Returns a list of all the changelists in this repository.""" |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 | 648 |
609 See docstring of GetModifiedFiles for information about path of files and | 649 See docstring of GetModifiedFiles for information about path of files and |
610 which directories are scanned. | 650 which directories are scanned. |
611 """ | 651 """ |
612 modified_files = GetModifiedFiles() | 652 modified_files = GetModifiedFiles() |
613 if "" not in modified_files: | 653 if "" not in modified_files: |
614 return [] | 654 return [] |
615 return modified_files[""] | 655 return modified_files[""] |
616 | 656 |
617 | 657 |
618 def SendToRietveld(request_path, payload=None, | |
619 content_type="application/octet-stream", timeout=None): | |
620 """Send a POST/GET to Rietveld. Returns the response body.""" | |
621 server = GetCodeReviewSetting("CODE_REVIEW_SERVER") | |
622 if not server: | |
623 ErrorExit(CODEREVIEW_SETTINGS_FILE_NOT_FOUND) | |
624 def GetUserCredentials(): | |
625 """Prompts the user for a username and password.""" | |
626 email = upload.GetEmail("Email (login for uploading to %s)" % server) | |
627 password = getpass.getpass("Password for %s: " % email) | |
628 return email, password | |
629 rpc_server = upload.HttpRpcServer(server, | |
630 GetUserCredentials, | |
631 save_cookies=True) | |
632 try: | |
633 return rpc_server.Send(request_path, payload, content_type, timeout) | |
634 except urllib2.URLError: | |
635 if timeout is None: | |
636 ErrorExit("Error accessing url %s" % request_path) | |
637 else: | |
638 return None | |
639 | |
640 | |
641 def GetIssueDescription(issue): | |
642 """Returns the issue description from Rietveld.""" | |
643 return SendToRietveld("/%d/description" % issue) | |
644 | |
645 | |
646 def ListFiles(show_unknown_files): | 658 def ListFiles(show_unknown_files): |
647 files = GetModifiedFiles() | 659 files = GetModifiedFiles() |
648 cl_keys = files.keys() | 660 cl_keys = files.keys() |
649 cl_keys.sort() | 661 cl_keys.sort() |
650 for cl_name in cl_keys: | 662 for cl_name in cl_keys: |
651 if not cl_name: | 663 if not cl_name: |
652 continue | 664 continue |
653 note = "" | 665 note = "" |
654 change_info = ChangeInfo.Load(cl_name, GetRepositoryRoot(), | 666 change_info = ChangeInfo.Load(cl_name, GetRepositoryRoot(), |
655 fail_on_not_found=True, update_status=False) | 667 fail_on_not_found=True, update_status=False) |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 if not OptionallyDoPresubmitChecks(change_info, False, args): | 788 if not OptionallyDoPresubmitChecks(change_info, False, args): |
777 return 1 | 789 return 1 |
778 no_watchlists = (FilterFlag(args, "--no_watchlists") or | 790 no_watchlists = (FilterFlag(args, "--no_watchlists") or |
779 FilterFlag(args, "--no-watchlists")) | 791 FilterFlag(args, "--no-watchlists")) |
780 | 792 |
781 # Map --send-mail to --send_mail | 793 # Map --send-mail to --send_mail |
782 if FilterFlag(args, "--send-mail"): | 794 if FilterFlag(args, "--send-mail"): |
783 args.append("--send_mail") | 795 args.append("--send_mail") |
784 | 796 |
785 upload_arg = ["upload.py", "-y"] | 797 upload_arg = ["upload.py", "-y"] |
786 server = GetCodeReviewSetting("CODE_REVIEW_SERVER") | 798 upload_arg.append("--server=%s" % change_info.rietveld) |
787 if not server: | |
788 ErrorExit(CODEREVIEW_SETTINGS_FILE_NOT_FOUND) | |
789 upload_arg.append("--server=%s" % server) | |
790 upload_arg.extend(args) | 799 upload_arg.extend(args) |
791 | 800 |
792 desc_file = "" | 801 desc_file = "" |
793 if change_info.issue: # Uploading a new patchset. | 802 if change_info.issue: # Uploading a new patchset. |
794 found_message = False | 803 found_message = False |
795 for arg in args: | 804 for arg in args: |
796 if arg.startswith("--message") or arg.startswith("-m"): | 805 if arg.startswith("--message") or arg.startswith("-m"): |
797 found_message = True | 806 found_message = True |
798 break | 807 break |
799 | 808 |
(...skipping 30 matching lines...) Expand all Loading... |
830 subject = subject + "..." | 839 subject = subject + "..." |
831 upload_arg.append("--message=" + subject) | 840 upload_arg.append("--message=" + subject) |
832 | 841 |
833 if GetCodeReviewSetting("PRIVATE") == "True": | 842 if GetCodeReviewSetting("PRIVATE") == "True": |
834 upload_arg.append("--private") | 843 upload_arg.append("--private") |
835 | 844 |
836 # Change the current working directory before calling upload.py so that it | 845 # Change the current working directory before calling upload.py so that it |
837 # shows the correct base. | 846 # shows the correct base. |
838 previous_cwd = os.getcwd() | 847 previous_cwd = os.getcwd() |
839 os.chdir(change_info.GetLocalRoot()) | 848 os.chdir(change_info.GetLocalRoot()) |
840 | |
841 # If we have a lot of files with long paths, then we won't be able to fit | 849 # If we have a lot of files with long paths, then we won't be able to fit |
842 # the command to "svn diff". Instead, we generate the diff manually for | 850 # the command to "svn diff". Instead, we generate the diff manually for |
843 # each file and concatenate them before passing it to upload.py. | 851 # each file and concatenate them before passing it to upload.py. |
844 if change_info.patch is None: | 852 if change_info.patch is None: |
845 change_info.patch = GenerateDiff(change_info.GetFileNames()) | 853 change_info.patch = GenerateDiff(change_info.GetFileNames()) |
846 issue, patchset = upload.RealMain(upload_arg, change_info.patch) | 854 issue, patchset = upload.RealMain(upload_arg, change_info.patch) |
847 if issue and patchset: | 855 if issue and patchset: |
848 change_info.issue = int(issue) | 856 change_info.issue = int(issue) |
849 change_info.patchset = int(patchset) | 857 change_info.patchset = int(patchset) |
850 change_info.Save() | 858 change_info.Save() |
851 | 859 |
852 if desc_file: | 860 if desc_file: |
853 os.remove(desc_file) | 861 os.remove(desc_file) |
854 | 862 change_info.PrimeLint() |
855 # Do background work on Rietveld to lint the file so that the results are | |
856 # ready when the issue is viewed. | |
857 SendToRietveld("/lint/issue%s_%s" % (issue, patchset), timeout=0.5) | |
858 | |
859 # Move back before considering try, so GetCodeReviewSettings is | |
860 # consistent. | |
861 os.chdir(previous_cwd) | 863 os.chdir(previous_cwd) |
862 | |
863 print "*** Upload does not submit a try; use gcl try to submit a try. ***" | 864 print "*** Upload does not submit a try; use gcl try to submit a try. ***" |
864 | |
865 return 0 | 865 return 0 |
866 | 866 |
867 | 867 |
868 @need_change | 868 @need_change |
869 def CMDpresubmit(change_info): | 869 def CMDpresubmit(change_info): |
870 """Runs presubmit checks on the change. | 870 """Runs presubmit checks on the change. |
871 | 871 |
872 The actual presubmit code is implemented in presubmit_support.py and looks | 872 The actual presubmit code is implemented in presubmit_support.py and looks |
873 for PRESUBMIT.py files.""" | 873 for PRESUBMIT.py files.""" |
874 if not change_info.GetFiles(): | 874 if not change_info.GetFiles(): |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
926 # We face a problem with svn here: Let's say change 'bleh' modifies | 926 # We face a problem with svn here: Let's say change 'bleh' modifies |
927 # svn:ignore on dir1\. but another unrelated change 'pouet' modifies | 927 # svn:ignore on dir1\. but another unrelated change 'pouet' modifies |
928 # dir1\foo.cc. When the user `gcl commit bleh`, foo.cc is *also committed*. | 928 # dir1\foo.cc. When the user `gcl commit bleh`, foo.cc is *also committed*. |
929 # The only fix is to use --non-recursive but that has its issues too: | 929 # The only fix is to use --non-recursive but that has its issues too: |
930 # Let's say if dir1 is deleted, --non-recursive must *not* be used otherwise | 930 # Let's say if dir1 is deleted, --non-recursive must *not* be used otherwise |
931 # you'll get "svn: Cannot non-recursively commit a directory deletion of a | 931 # you'll get "svn: Cannot non-recursively commit a directory deletion of a |
932 # directory with child nodes". Yay... | 932 # directory with child nodes". Yay... |
933 commit_cmd = ["svn", "commit"] | 933 commit_cmd = ["svn", "commit"] |
934 if change_info.issue: | 934 if change_info.issue: |
935 # Get the latest description from Rietveld. | 935 # Get the latest description from Rietveld. |
936 change_info.description = GetIssueDescription(change_info.issue) | 936 change_info.description = change_info.GetIssueDescription() |
937 | 937 |
938 commit_message = change_info.description.replace('\r\n', '\n') | 938 commit_message = change_info.description.replace('\r\n', '\n') |
939 if change_info.issue: | 939 if change_info.issue: |
940 server = GetCodeReviewSetting("CODE_REVIEW_SERVER") | 940 server = change_info.rietveld |
941 if not server: | |
942 ErrorExit(CODEREVIEW_SETTINGS_FILE_NOT_FOUND) | |
943 if not server.startswith("http://") and not server.startswith("https://"): | 941 if not server.startswith("http://") and not server.startswith("https://"): |
944 server = "http://" + server | 942 server = "http://" + server |
945 commit_message += ('\nReview URL: %s/%d' % (server, change_info.issue)) | 943 commit_message += ('\nReview URL: %s/%d' % (server, change_info.issue)) |
946 | 944 |
947 handle, commit_filename = tempfile.mkstemp(text=True) | 945 handle, commit_filename = tempfile.mkstemp(text=True) |
948 os.write(handle, commit_message) | 946 os.write(handle, commit_message) |
949 os.close(handle) | 947 os.close(handle) |
950 | 948 |
951 handle, targets_filename = tempfile.mkstemp(text=True) | 949 handle, targets_filename = tempfile.mkstemp(text=True) |
952 os.write(handle, "\n".join(change_info.GetFileNames())) | 950 os.write(handle, "\n".join(change_info.GetFileNames())) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 if not os.path.isfile(args[1]): | 997 if not os.path.isfile(args[1]): |
1000 ErrorExit('The change "%s" doesn\'t exist.' % args[1]) | 998 ErrorExit('The change "%s" doesn\'t exist.' % args[1]) |
1001 f = open(args[1], 'rU') | 999 f = open(args[1], 'rU') |
1002 override_description = f.read() | 1000 override_description = f.read() |
1003 f.close() | 1001 f.close() |
1004 else: | 1002 else: |
1005 override_description = None | 1003 override_description = None |
1006 | 1004 |
1007 if change_info.issue and not change_info.NeedsUpload(): | 1005 if change_info.issue and not change_info.NeedsUpload(): |
1008 try: | 1006 try: |
1009 description = GetIssueDescription(change_info.issue) | 1007 description = change_info.GetIssueDescription() |
1010 except urllib2.HTTPError, err: | 1008 except urllib2.HTTPError, err: |
1011 if err.code == 404: | 1009 if err.code == 404: |
1012 # The user deleted the issue in Rietveld, so forget the old issue id. | 1010 # The user deleted the issue in Rietveld, so forget the old issue id. |
1013 description = change_info.description | 1011 description = change_info.description |
1014 change_info.issue = 0 | 1012 change_info.issue = 0 |
1015 change_info.Save() | 1013 change_info.Save() |
1016 else: | 1014 else: |
1017 ErrorExit("Error getting the description from Rietveld: " + err) | 1015 ErrorExit("Error getting the description from Rietveld: " + err) |
1018 else: | 1016 else: |
1019 if override_description: | 1017 if override_description: |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1107 Checks all the files in the changelist for possible style violations. | 1105 Checks all the files in the changelist for possible style violations. |
1108 """ | 1106 """ |
1109 try: | 1107 try: |
1110 import cpplint | 1108 import cpplint |
1111 except ImportError: | 1109 except ImportError: |
1112 ErrorExit("You need to install cpplint.py to lint C++ files.") | 1110 ErrorExit("You need to install cpplint.py to lint C++ files.") |
1113 # Change the current working directory before calling lint so that it | 1111 # Change the current working directory before calling lint so that it |
1114 # shows the correct base. | 1112 # shows the correct base. |
1115 previous_cwd = os.getcwd() | 1113 previous_cwd = os.getcwd() |
1116 os.chdir(change_info.GetLocalRoot()) | 1114 os.chdir(change_info.GetLocalRoot()) |
1117 | |
1118 # Process cpplints arguments if any. | 1115 # Process cpplints arguments if any. |
1119 filenames = cpplint.ParseArguments(args + change_info.GetFileNames()) | 1116 filenames = cpplint.ParseArguments(args + change_info.GetFileNames()) |
1120 | 1117 |
1121 white_list = GetCodeReviewSetting("LINT_REGEX") | 1118 white_list = GetCodeReviewSetting("LINT_REGEX") |
1122 if not white_list: | 1119 if not white_list: |
1123 white_list = DEFAULT_LINT_REGEX | 1120 white_list = DEFAULT_LINT_REGEX |
1124 white_regex = re.compile(white_list) | 1121 white_regex = re.compile(white_list) |
1125 black_list = GetCodeReviewSetting("LINT_IGNORE_REGEX") | 1122 black_list = GetCodeReviewSetting("LINT_IGNORE_REGEX") |
1126 if not black_list: | 1123 if not black_list: |
1127 black_list = DEFAULT_LINT_IGNORE_REGEX | 1124 black_list = DEFAULT_LINT_IGNORE_REGEX |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1374 if e.code != 500: | 1371 if e.code != 500: |
1375 raise | 1372 raise |
1376 print >> sys.stderr, ( | 1373 print >> sys.stderr, ( |
1377 'AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' | 1374 'AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' |
1378 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e)) | 1375 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e)) |
1379 return 1 | 1376 return 1 |
1380 | 1377 |
1381 | 1378 |
1382 if __name__ == "__main__": | 1379 if __name__ == "__main__": |
1383 sys.exit(main(sys.argv[1:])) | 1380 sys.exit(main(sys.argv[1:])) |
OLD | NEW |