| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 """Client-side script to send a try job to the try server. It communicates to | 6 """Client-side script to send a try job to the try server. It communicates to |
| 7 the try server by either writting to a svn repository or by directly connecting | 7 the try server by either writting to a svn repository or by directly connecting |
| 8 to the server by HTTP. | 8 to the server by HTTP. |
| 9 """ | 9 """ |
| 10 | 10 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 | 86 |
| 87 def Escape(name): | 87 def Escape(name): |
| 88 """Escapes characters that could interfere with the file system or try job | 88 """Escapes characters that could interfere with the file system or try job |
| 89 parsing. | 89 parsing. |
| 90 """ | 90 """ |
| 91 return re.sub(r'[^\w#-]', '_', name) | 91 return re.sub(r'[^\w#-]', '_', name) |
| 92 | 92 |
| 93 | 93 |
| 94 class SCM(object): | 94 class SCM(object): |
| 95 """Simplistic base class to implement one function: ProcessOptions.""" | 95 """Simplistic base class to implement one function: ProcessOptions.""" |
| 96 def __init__(self, options, path): | 96 def __init__(self, options, path, file_list): |
| 97 items = path.split('@') | 97 items = path.split('@') |
| 98 assert len(items) <= 2 | 98 assert len(items) <= 2 |
| 99 self.checkout_root = items[0] | 99 self.checkout_root = items[0] |
| 100 items.append(None) | 100 items.append(None) |
| 101 self.diff_against = items[1] | 101 self.diff_against = items[1] |
| 102 self.options = options | 102 self.options = options |
| 103 # Lazy-load file list from the SCM unless files were specified in options. | 103 # Lazy-load file list from the SCM unless files were specified in options. |
| 104 self._files = None | 104 self._files = None |
| 105 self._file_tuples = None | 105 self._file_tuples = None |
| 106 if self.options.files: | 106 if file_list: |
| 107 self._files = self.options.files | 107 self._files = file_list |
| 108 self._file_tuples = [('M', f) for f in self.files] | 108 self._file_tuples = [('M', f) for f in self.files] |
| 109 self.options.files = None | 109 self.options.files = None |
| 110 self.codereview_settings = None | 110 self.codereview_settings = None |
| 111 self.codereview_settings_file = 'codereview.settings' | 111 self.codereview_settings_file = 'codereview.settings' |
| 112 self.gclient_root = None | 112 self.gclient_root = None |
| 113 | 113 |
| 114 def GetFileNames(self): | 114 def GetFileNames(self): |
| 115 """Return the list of files in the diff.""" | 115 """Return the list of files in the diff.""" |
| 116 return self.files | 116 return self.files |
| 117 | 117 |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 | 429 |
| 430 | 430 |
| 431 def PrintSuccess(options): | 431 def PrintSuccess(options): |
| 432 if not options.dry_run: | 432 if not options.dry_run: |
| 433 text = 'Patch \'%s\' sent to try server' % options.name | 433 text = 'Patch \'%s\' sent to try server' % options.name |
| 434 if options.bot: | 434 if options.bot: |
| 435 text += ': %s' % ', '.join(options.bot) | 435 text += ': %s' % ', '.join(options.bot) |
| 436 print(text) | 436 print(text) |
| 437 | 437 |
| 438 | 438 |
| 439 def GuessVCS(options, path): | 439 def GuessVCS(options, path, file_list): |
| 440 """Helper to guess the version control system. | 440 """Helper to guess the version control system. |
| 441 | 441 |
| 442 NOTE: Very similar to upload.GuessVCS. Doesn't look for hg since we don't | 442 NOTE: Very similar to upload.GuessVCS. Doesn't look for hg since we don't |
| 443 support it yet. | 443 support it yet. |
| 444 | 444 |
| 445 This examines the path directory, guesses which SCM we're using, and | 445 This examines the path directory, guesses which SCM we're using, and |
| 446 returns an instance of the appropriate class. Exit with an error if we can't | 446 returns an instance of the appropriate class. Exit with an error if we can't |
| 447 figure it out. | 447 figure it out. |
| 448 | 448 |
| 449 Returns: | 449 Returns: |
| 450 A SCM instance. Exits if the SCM can't be guessed. | 450 A SCM instance. Exits if the SCM can't be guessed. |
| 451 """ | 451 """ |
| 452 __pychecker__ = 'no-returnvalues' | 452 __pychecker__ = 'no-returnvalues' |
| 453 real_path = path.split('@')[0] | 453 real_path = path.split('@')[0] |
| 454 logging.info("GuessVCS(%s)" % path) | 454 logging.info("GuessVCS(%s)" % path) |
| 455 # Subversion has a .svn in all working directories. | 455 # Subversion has a .svn in all working directories. |
| 456 if os.path.isdir(os.path.join(real_path, '.svn')): | 456 if os.path.isdir(os.path.join(real_path, '.svn')): |
| 457 return SVN(options, path) | 457 return SVN(options, path, file_list) |
| 458 | 458 |
| 459 # Git has a command to test if you're in a git tree. | 459 # Git has a command to test if you're in a git tree. |
| 460 # Try running it, but don't die if we don't have git installed. | 460 # Try running it, but don't die if we don't have git installed. |
| 461 try: | 461 try: |
| 462 subprocess2.check_output( | 462 subprocess2.check_output( |
| 463 ['git', 'rev-parse', '--is-inside-work-tree'], cwd=real_path, | 463 ['git', 'rev-parse', '--is-inside-work-tree'], cwd=real_path, |
| 464 stderr=subprocess2.VOID) | 464 stderr=subprocess2.VOID) |
| 465 return GIT(options, path) | 465 return GIT(options, path, file_list) |
| 466 except subprocess2.CalledProcessError, e: | 466 except subprocess2.CalledProcessError, e: |
| 467 if e.returncode != errno.ENOENT and e.returncode != 128: | 467 if e.returncode != errno.ENOENT and e.returncode != 128: |
| 468 # ENOENT == 2 = they don't have git installed. | 468 # ENOENT == 2 = they don't have git installed. |
| 469 # 128 = git error code when not in a repo. | 469 # 128 = git error code when not in a repo. |
| 470 logging.warning('Unexpected error code: %s' % e.returncode) | 470 logging.warning('Unexpected error code: %s' % e.returncode) |
| 471 raise | 471 raise |
| 472 raise NoTryServerAccess("Could not guess version control system. " | 472 raise NoTryServerAccess("Could not guess version control system. " |
| 473 "Are you in a working copy directory?") | 473 "Are you in a working copy directory?") |
| 474 | 474 |
| 475 | 475 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 492 change, | 492 change, |
| 493 swallow_exception, | 493 swallow_exception, |
| 494 prog=None, | 494 prog=None, |
| 495 extra_epilog=None): | 495 extra_epilog=None): |
| 496 """ | 496 """ |
| 497 Args: | 497 Args: |
| 498 argv: Arguments and options. | 498 argv: Arguments and options. |
| 499 change: Change instance corresponding to the CL. | 499 change: Change instance corresponding to the CL. |
| 500 swallow_exception: Whether we raise or swallow exceptions. | 500 swallow_exception: Whether we raise or swallow exceptions. |
| 501 """ | 501 """ |
| 502 file_list = [] | |
| 503 if change: | |
| 504 file_list = [f.LocalPath() for f in change.AffectedFiles()] | |
| 505 | |
| 506 # Parse argv | 502 # Parse argv |
| 507 parser = optparse.OptionParser(usage=USAGE, | 503 parser = optparse.OptionParser(usage=USAGE, |
| 508 version=__version__, | 504 version=__version__, |
| 509 prog=prog) | 505 prog=prog) |
| 510 epilog = EPILOG % { 'prog': prog } | 506 epilog = EPILOG % { 'prog': prog } |
| 511 if extra_epilog: | 507 if extra_epilog: |
| 512 epilog += extra_epilog | 508 epilog += extra_epilog |
| 513 parser.epilog = epilog | 509 parser.epilog = epilog |
| 514 # Remove epilog formatting | 510 # Remove epilog formatting |
| 515 parser.format_epilog = lambda x: parser.epilog | 511 parser.format_epilog = lambda x: parser.epilog |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 help="Add a gtest_filter to a test. Use multiple times to " | 558 help="Add a gtest_filter to a test. Use multiple times to " |
| 563 "specify filters for different tests. (i.e. " | 559 "specify filters for different tests. (i.e. " |
| 564 "--testfilter base_unittests:ThreadTest.* " | 560 "--testfilter base_unittests:ThreadTest.* " |
| 565 "--testfilter ui_tests) If you specify any testfilters " | 561 "--testfilter ui_tests) If you specify any testfilters " |
| 566 "the test results will not be reported in rietveld and " | 562 "the test results will not be reported in rietveld and " |
| 567 "only tests with filters will run.") | 563 "only tests with filters will run.") |
| 568 | 564 |
| 569 parser.add_option_group(group) | 565 parser.add_option_group(group) |
| 570 | 566 |
| 571 group = optparse.OptionGroup(parser, "Patch to run") | 567 group = optparse.OptionGroup(parser, "Patch to run") |
| 572 group.add_option("-f", "--file", default=file_list, dest="files", | 568 group.add_option("-f", "--file", default=[], dest="files", |
| 573 metavar="FILE", action="append", | 569 metavar="FILE", action="append", |
| 574 help="Use many times to list the files to include in the " | 570 help="Use many times to list the files to include in the " |
| 575 "try, relative to the repository root") | 571 "try, relative to the repository root") |
| 576 group.add_option("--diff", | 572 group.add_option("--diff", |
| 577 help="File containing the diff to try") | 573 help="File containing the diff to try") |
| 578 group.add_option("--url", | 574 group.add_option("--url", |
| 579 help="Url where to grab a patch, e.g. " | 575 help="Url where to grab a patch, e.g. " |
| 580 "http://example.com/x.diff") | 576 "http://example.com/x.diff") |
| 581 group.add_option("-R", "--rietveld_url", default="codereview.appspot.com", | 577 group.add_option("-R", "--rietveld_url", default="codereview.appspot.com", |
| 582 metavar="URL", | 578 metavar="URL", |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 if options.issue or options.patchset: | 668 if options.issue or options.patchset: |
| 673 parser.error('Cannot use both --issue and use a review number url') | 669 parser.error('Cannot use both --issue and use a review number url') |
| 674 options.issue = int(match.group(2)) | 670 options.issue = int(match.group(2)) |
| 675 options.rietveld_url = match.group(1) | 671 options.rietveld_url = match.group(1) |
| 676 | 672 |
| 677 try: | 673 try: |
| 678 changed_files = None | 674 changed_files = None |
| 679 # Always include os.getcwd() in the checkout settings. | 675 # Always include os.getcwd() in the checkout settings. |
| 680 checkouts = [] | 676 checkouts = [] |
| 681 path = os.getcwd() | 677 path = os.getcwd() |
| 678 |
| 679 file_list = [] |
| 680 if options.files: |
| 681 file_list = options.files |
| 682 elif change: |
| 683 file_list = [f.LocalPath() for f in change.AffectedFiles()] |
| 684 |
| 682 if options.upstream_branch: | 685 if options.upstream_branch: |
| 683 path += '@' + options.upstream_branch | 686 path += '@' + options.upstream_branch |
| 684 checkouts.append(GuessVCS(options, path)) | 687 # Clear file list so that the correct list will be retrieved from the |
| 688 # upstream branch. |
| 689 file_list = [] |
| 690 checkouts.append(GuessVCS(options, path, file_list)) |
| 685 checkouts[0].AutomagicalSettings() | 691 checkouts[0].AutomagicalSettings() |
| 686 for item in options.sub_rep: | 692 for item in options.sub_rep: |
| 687 checkout = GuessVCS(options, os.path.join(checkouts[0].checkout_root, | 693 checkout = GuessVCS(options, os.path.join(checkouts[0].checkout_root, |
| 688 item)) | 694 item), file_list) |
| 689 if checkout.checkout_root in [c.checkout_root for c in checkouts]: | 695 if checkout.checkout_root in [c.checkout_root for c in checkouts]: |
| 690 parser.error('Specified the root %s two times.' % | 696 parser.error('Specified the root %s two times.' % |
| 691 checkout.checkout_root) | 697 checkout.checkout_root) |
| 692 checkouts.append(checkout) | 698 checkouts.append(checkout) |
| 693 | 699 |
| 694 can_http = options.port and options.host | 700 can_http = options.port and options.host |
| 695 can_svn = options.svn_repo | 701 can_svn = options.svn_repo |
| 696 # If there was no transport selected yet, now we must have enough data to | 702 # If there was no transport selected yet, now we must have enough data to |
| 697 # select one. | 703 # select one. |
| 698 if not options.send_patch and not (can_http or can_svn): | 704 if not options.send_patch and not (can_http or can_svn): |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 return 1 | 809 return 1 |
| 804 except (gclient_utils.Error, subprocess2.CalledProcessError), e: | 810 except (gclient_utils.Error, subprocess2.CalledProcessError), e: |
| 805 print >> sys.stderr, e | 811 print >> sys.stderr, e |
| 806 return 1 | 812 return 1 |
| 807 return 0 | 813 return 0 |
| 808 | 814 |
| 809 | 815 |
| 810 if __name__ == "__main__": | 816 if __name__ == "__main__": |
| 811 fix_encoding.fix_encoding() | 817 fix_encoding.fix_encoding() |
| 812 sys.exit(TryChange(None, None, False)) | 818 sys.exit(TryChange(None, None, False)) |
| OLD | NEW |