| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2009 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 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 """Client-side script to send a try job to the try server. It communicates to | 5 """Client-side script to send a try job to the try server. It communicates to |
| 6 the try server by either writting to a svn repository or by directly connecting | 6 the try server by either writting to a svn repository or by directly connecting |
| 7 to the server by HTTP. | 7 to the server by HTTP. |
| 8 """ | 8 """ |
| 9 | 9 |
| 10 import datetime | 10 import datetime |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 def __str__(self): | 67 def __str__(self): |
| 68 return self.args[0] + '\n' + HELP_STRING | 68 return self.args[0] + '\n' + HELP_STRING |
| 69 | 69 |
| 70 | 70 |
| 71 def EscapeDot(name): | 71 def EscapeDot(name): |
| 72 return name.replace('.', '-') | 72 return name.replace('.', '-') |
| 73 | 73 |
| 74 | 74 |
| 75 class SCM(object): | 75 class SCM(object): |
| 76 """Simplistic base class to implement one function: ProcessOptions.""" | 76 """Simplistic base class to implement one function: ProcessOptions.""" |
| 77 def __init__(self, options, cwd): | 77 def __init__(self, options, path): |
| 78 self.checkout_root = cwd | 78 items = path.split('@') |
| 79 assert len(items) <= 2 |
| 80 self.checkout_root = items[0] |
| 81 items.append(None) |
| 82 self.diff_against = items[1] |
| 79 self.options = options | 83 self.options = options |
| 80 self.files = self.options.files | 84 self.files = self.options.files |
| 81 self.options.files = None | 85 self.options.files = None |
| 82 self.codereview_settings = None | 86 self.codereview_settings = None |
| 83 self.codereview_settings_file = 'codereview.settings' | 87 self.codereview_settings_file = 'codereview.settings' |
| 84 | 88 |
| 85 def GetFileNames(self): | 89 def GetFileNames(self): |
| 86 """Return the list of files in the diff.""" | 90 """Return the list of files in the diff.""" |
| 87 return self.files | 91 return self.files |
| 88 | 92 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 """ | 173 """ |
| 170 if not self.files: | 174 if not self.files: |
| 171 previous_cwd = os.getcwd() | 175 previous_cwd = os.getcwd() |
| 172 os.chdir(self.checkout_root) | 176 os.chdir(self.checkout_root) |
| 173 excluded = ['!', '?', 'X', ' ', '~'] | 177 excluded = ['!', '?', 'X', ' ', '~'] |
| 174 self.files = [ | 178 self.files = [ |
| 175 f[1] for f in scm.SVN.CaptureStatus(self.checkout_root) | 179 f[1] for f in scm.SVN.CaptureStatus(self.checkout_root) |
| 176 if f[0][0] not in excluded | 180 if f[0][0] not in excluded |
| 177 ] | 181 ] |
| 178 os.chdir(previous_cwd) | 182 os.chdir(previous_cwd) |
| 179 return scm.SVN.GenerateDiff(self.files, self.checkout_root, full_move=True) | 183 return scm.SVN.GenerateDiff(self.files, self.checkout_root, full_move=True, |
| 184 revision=self.diff_against) |
| 180 | 185 |
| 181 | 186 |
| 182 class GIT(SCM): | 187 class GIT(SCM): |
| 183 """Gathers the options and diff for a git checkout.""" | 188 """Gathers the options and diff for a git checkout.""" |
| 184 def __init__(self, *args, **kwargs): | 189 def __init__(self, *args, **kwargs): |
| 185 SCM.__init__(self, *args, **kwargs) | 190 SCM.__init__(self, *args, **kwargs) |
| 186 self.checkout_root = scm.GIT.GetCheckoutRoot(self.checkout_root) | 191 self.checkout_root = scm.GIT.GetCheckoutRoot(self.checkout_root) |
| 187 if not self.options.name: | 192 if not self.options.name: |
| 188 self.options.name = scm.GIT.GetPatchName(self.checkout_root) | 193 self.options.name = scm.GIT.GetPatchName(self.checkout_root) |
| 189 if not self.options.email: | 194 if not self.options.email: |
| 190 self.options.email = scm.GIT.GetEmail(self.checkout_root) | 195 self.options.email = scm.GIT.GetEmail(self.checkout_root) |
| 191 logging.info("GIT(%s)" % self.checkout_root) | 196 logging.info("GIT(%s)" % self.checkout_root) |
| 192 | 197 |
| 193 def ReadRootFile(self, filename): | 198 def ReadRootFile(self, filename): |
| 194 try: | 199 try: |
| 195 # A git checkout is always a full checkout. | 200 # A git checkout is always a full checkout. |
| 196 data = gclient_utils.FileRead(os.path.join(self.checkout_root, filename)) | 201 data = gclient_utils.FileRead(os.path.join(self.checkout_root, filename)) |
| 197 logging.debug('%s:\n%s' % (filename, data)) | 202 logging.debug('%s:\n%s' % (filename, data)) |
| 198 return data | 203 return data |
| 199 except (IOError, OSError): | 204 except (IOError, OSError): |
| 200 logging.debug('%s:\nNone' % filename) | 205 logging.debug('%s:\nNone' % filename) |
| 201 return None | 206 return None |
| 202 | 207 |
| 203 def GenerateDiff(self): | 208 def GenerateDiff(self): |
| 204 # For now, ignores self.files | 209 # For now, ignores self.files |
| 205 return scm.GIT.GenerateDiff(self.checkout_root, full_move=True) | 210 return scm.GIT.GenerateDiff(self.checkout_root, full_move=True, |
| 211 branch=self.diff_against) |
| 206 | 212 |
| 207 | 213 |
| 208 def _ParseSendChangeOptions(options): | 214 def _ParseSendChangeOptions(options): |
| 209 """Parse common options passed to _SendChangeHTTP and _SendChangeSVN.""" | 215 """Parse common options passed to _SendChangeHTTP and _SendChangeSVN.""" |
| 210 values = {} | 216 values = {} |
| 211 if options.email: | 217 if options.email: |
| 212 values['email'] = options.email | 218 values['email'] = options.email |
| 213 values['user'] = options.user | 219 values['user'] = options.user |
| 214 values['name'] = options.name | 220 values['name'] = options.name |
| 215 if options.bot: | 221 if options.bot: |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 support it yet. | 364 support it yet. |
| 359 | 365 |
| 360 This examines the path directory, guesses which SCM we're using, and | 366 This examines the path directory, guesses which SCM we're using, and |
| 361 returns an instance of the appropriate class. Exit with an error if we can't | 367 returns an instance of the appropriate class. Exit with an error if we can't |
| 362 figure it out. | 368 figure it out. |
| 363 | 369 |
| 364 Returns: | 370 Returns: |
| 365 A SCM instance. Exits if the SCM can't be guessed. | 371 A SCM instance. Exits if the SCM can't be guessed. |
| 366 """ | 372 """ |
| 367 __pychecker__ = 'no-returnvalues' | 373 __pychecker__ = 'no-returnvalues' |
| 374 real_path = path.split('@')[0] |
| 368 logging.info("GuessVCS(%s)" % path) | 375 logging.info("GuessVCS(%s)" % path) |
| 369 # Subversion has a .svn in all working directories. | 376 # Subversion has a .svn in all working directories. |
| 370 if os.path.isdir(os.path.join(path, '.svn')): | 377 if os.path.isdir(os.path.join(real_path, '.svn')): |
| 371 return SVN(options, path) | 378 return SVN(options, path) |
| 372 | 379 |
| 373 # Git has a command to test if you're in a git tree. | 380 # Git has a command to test if you're in a git tree. |
| 374 # Try running it, but don't die if we don't have git installed. | 381 # Try running it, but don't die if we don't have git installed. |
| 375 try: | 382 try: |
| 376 gclient_utils.CheckCall(["git", "rev-parse", "--is-inside-work-tree"], | 383 gclient_utils.CheckCall(["git", "rev-parse", "--is-inside-work-tree"], |
| 377 path) | 384 real_path) |
| 378 return GIT(options, path) | 385 return GIT(options, path) |
| 379 except gclient_utils.CheckCallError, e: | 386 except gclient_utils.CheckCallError, e: |
| 380 if e.retcode != errno.ENOENT and e.retcode != 128: | 387 if e.retcode != errno.ENOENT and e.retcode != 128: |
| 381 # ENOENT == 2 = they don't have git installed. | 388 # ENOENT == 2 = they don't have git installed. |
| 382 # 128 = git error code when not in a repo. | 389 # 128 = git error code when not in a repo. |
| 383 logging.warn(e.retcode) | 390 logging.warn(e.retcode) |
| 384 raise | 391 raise |
| 385 raise NoTryServerAccess("Could not guess version control system. " | 392 raise NoTryServerAccess("Could not guess version control system. " |
| 386 "Are you in a working copy directory?") | 393 "Are you in a working copy directory?") |
| 387 | 394 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 help="File containing the diff to try") | 464 help="File containing the diff to try") |
| 458 group.add_option("--url", | 465 group.add_option("--url", |
| 459 help="Url where to grab a patch") | 466 help="Url where to grab a patch") |
| 460 group.add_option("--root", | 467 group.add_option("--root", |
| 461 help="Root to use for the patch; base subdirectory for " | 468 help="Root to use for the patch; base subdirectory for " |
| 462 "patch created in a subdirectory") | 469 "patch created in a subdirectory") |
| 463 group.add_option("-p", "--patchlevel", type='int', metavar="LEVEL", | 470 group.add_option("-p", "--patchlevel", type='int', metavar="LEVEL", |
| 464 help="Used as -pN parameter to patch") | 471 help="Used as -pN parameter to patch") |
| 465 group.add_option("-s", "--sub_rep", action="append", default=[], | 472 group.add_option("-s", "--sub_rep", action="append", default=[], |
| 466 help="Subcheckout to use in addition. This is mainly " | 473 help="Subcheckout to use in addition. This is mainly " |
| 467 "useful for gclient-style checkouts.") | 474 "useful for gclient-style checkouts. Use @rev or " |
| 475 "@branch or @branch1..branch2 to specify the " |
| 476 "revision/branch to diff against.") |
| 468 group.add_option("--no_gclient", action="store_true", | 477 group.add_option("--no_gclient", action="store_true", |
| 469 help="Disable automatic search for gclient checkout.") | 478 help="Disable automatic search for gclient checkout.") |
| 470 parser.add_option_group(group) | 479 parser.add_option_group(group) |
| 471 | 480 |
| 472 group = optparse.OptionGroup(parser, "Access the try server by HTTP") | 481 group = optparse.OptionGroup(parser, "Access the try server by HTTP") |
| 473 group.add_option("--use_http", | 482 group.add_option("--use_http", |
| 474 action="store_const", | 483 action="store_const", |
| 475 const=_SendChangeHTTP, | 484 const=_SendChangeHTTP, |
| 476 dest="send_patch", | 485 dest="send_patch", |
| 477 help="Use HTTP to talk to the try server [default]") | 486 help="Use HTTP to talk to the try server [default]") |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 except (InvalidScript, NoTryServerAccess), e: | 611 except (InvalidScript, NoTryServerAccess), e: |
| 603 if swallow_exception: | 612 if swallow_exception: |
| 604 return 1 | 613 return 1 |
| 605 print e | 614 print e |
| 606 return 1 | 615 return 1 |
| 607 return 0 | 616 return 0 |
| 608 | 617 |
| 609 | 618 |
| 610 if __name__ == "__main__": | 619 if __name__ == "__main__": |
| 611 sys.exit(TryChange(None, [], False)) | 620 sys.exit(TryChange(None, [], False)) |
| OLD | NEW |