| OLD | NEW |
| 1 # Copyright 2009 Google Inc. All Rights Reserved. | 1 # Copyright 2009 Google Inc. All Rights Reserved. |
| 2 # | 2 # |
| 3 # Licensed under the Apache License, Version 2.0 (the "License"); | 3 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 # you may not use this file except in compliance with the License. | 4 # you may not use this file except in compliance with the License. |
| 5 # You may obtain a copy of the License at | 5 # You may obtain a copy of the License at |
| 6 # | 6 # |
| 7 # http://www.apache.org/licenses/LICENSE-2.0 | 7 # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 # | 8 # |
| 9 # Unless required by applicable law or agreed to in writing, software | 9 # Unless required by applicable law or agreed to in writing, software |
| 10 # distributed under the License is distributed on an "AS IS" BASIS, | 10 # distributed under the License is distributed on an "AS IS" BASIS, |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 | 243 |
| 244 rev_str = "" | 244 rev_str = "" |
| 245 if revision: | 245 if revision: |
| 246 rev_str = ' at %s' % revision | 246 rev_str = ' at %s' % revision |
| 247 | 247 |
| 248 if not os.path.exists(checkout_path): | 248 if not os.path.exists(checkout_path): |
| 249 # We need to checkout. | 249 # We need to checkout. |
| 250 command = ['checkout', url, checkout_path] | 250 command = ['checkout', url, checkout_path] |
| 251 if revision: | 251 if revision: |
| 252 command.extend(['--revision', str(revision)]) | 252 command.extend(['--revision', str(revision)]) |
| 253 RunSVNAndGetFileList(command, self._root_dir, file_list) | 253 RunSVNAndGetFileList(options, command, self._root_dir, file_list) |
| 254 return | 254 return |
| 255 | 255 |
| 256 # Get the existing scm url and the revision number of the current checkout. | 256 # Get the existing scm url and the revision number of the current checkout. |
| 257 from_info = CaptureSVNInfo(os.path.join(checkout_path, '.'), '.') | 257 from_info = CaptureSVNInfo(os.path.join(checkout_path, '.'), '.') |
| 258 if not from_info: | 258 if not from_info: |
| 259 raise gclient_utils.Error("Can't update/checkout %r if an unversioned " | 259 raise gclient_utils.Error("Can't update/checkout %r if an unversioned " |
| 260 "directory is present. Delete the directory " | 260 "directory is present. Delete the directory " |
| 261 "and try again." % | 261 "and try again." % |
| 262 checkout_path) | 262 checkout_path) |
| 263 | 263 |
| 264 if options.manually_grab_svn_rev: | 264 # Retrieve the current HEAD version because svn is slow at null updates. |
| 265 # Retrieve the current HEAD version because svn is slow at null updates. | 265 if not revision: |
| 266 if not revision: | 266 from_info_live = CaptureSVNInfo(from_info['URL'], '.') |
| 267 from_info_live = CaptureSVNInfo(from_info['URL'], '.') | 267 revision = str(from_info_live['Revision']) |
| 268 revision = str(from_info_live['Revision']) | 268 rev_str = ' at %s' % revision |
| 269 rev_str = ' at %s' % revision | 269 forced_revision = True |
| 270 | 270 |
| 271 if from_info['URL'] != components[0]: | 271 if from_info['URL'] != components[0]: |
| 272 to_info = CaptureSVNInfo(url, '.') | 272 to_info = CaptureSVNInfo(url, '.') |
| 273 if not to_info.get('Repository Root') or not to_info.get('UUID'): | 273 if not to_info.get('Repository Root') or not to_info.get('UUID'): |
| 274 # The url is invalid or the server is not accessible, it's safer to bail | 274 # The url is invalid or the server is not accessible, it's safer to bail |
| 275 # out right now. | 275 # out right now. |
| 276 raise gclient_utils.Error('This url is unreachable: %s' % url) | 276 raise gclient_utils.Error('This url is unreachable: %s' % url) |
| 277 can_switch = ((from_info['Repository Root'] != to_info['Repository Root']) | 277 can_switch = ((from_info['Repository Root'] != to_info['Repository Root']) |
| 278 and (from_info['UUID'] == to_info['UUID'])) | 278 and (from_info['UUID'] == to_info['UUID'])) |
| 279 if can_switch: | 279 if can_switch: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 301 "don't match and there is local changes " | 301 "don't match and there is local changes " |
| 302 "in %s. Delete the directory and " | 302 "in %s. Delete the directory and " |
| 303 "try again." % (url, checkout_path)) | 303 "try again." % (url, checkout_path)) |
| 304 # Ok delete it. | 304 # Ok delete it. |
| 305 print("\n_____ switching %s to a new checkout" % self.relpath) | 305 print("\n_____ switching %s to a new checkout" % self.relpath) |
| 306 gclient_utils.RemoveDirectory(checkout_path) | 306 gclient_utils.RemoveDirectory(checkout_path) |
| 307 # We need to checkout. | 307 # We need to checkout. |
| 308 command = ['checkout', url, checkout_path] | 308 command = ['checkout', url, checkout_path] |
| 309 if revision: | 309 if revision: |
| 310 command.extend(['--revision', str(revision)]) | 310 command.extend(['--revision', str(revision)]) |
| 311 RunSVNAndGetFileList(command, self._root_dir, file_list) | 311 RunSVNAndGetFileList(options, command, self._root_dir, file_list) |
| 312 return | 312 return |
| 313 | 313 |
| 314 | 314 |
| 315 # If the provided url has a revision number that matches the revision | 315 # If the provided url has a revision number that matches the revision |
| 316 # number of the existing directory, then we don't need to bother updating. | 316 # number of the existing directory, then we don't need to bother updating. |
| 317 if not options.force and str(from_info['Revision']) == revision: | 317 if not options.force and str(from_info['Revision']) == revision: |
| 318 if options.verbose or not forced_revision: | 318 if options.verbose or not forced_revision: |
| 319 print("\n_____ %s%s" % (self.relpath, rev_str)) | 319 print("\n_____ %s%s" % (self.relpath, rev_str)) |
| 320 return | 320 return |
| 321 | 321 |
| 322 command = ["update", checkout_path] | 322 command = ["update", checkout_path] |
| 323 if revision: | 323 if revision: |
| 324 command.extend(['--revision', str(revision)]) | 324 command.extend(['--revision', str(revision)]) |
| 325 RunSVNAndGetFileList(command, self._root_dir, file_list) | 325 RunSVNAndGetFileList(options, command, self._root_dir, file_list) |
| 326 | 326 |
| 327 def revert(self, options, args, file_list): | 327 def revert(self, options, args, file_list): |
| 328 """Reverts local modifications. Subversion specific. | 328 """Reverts local modifications. Subversion specific. |
| 329 | 329 |
| 330 All reverted files will be appended to file_list, even if Subversion | 330 All reverted files will be appended to file_list, even if Subversion |
| 331 doesn't know about them. | 331 doesn't know about them. |
| 332 """ | 332 """ |
| 333 path = os.path.join(self._root_dir, self.relpath) | 333 path = os.path.join(self._root_dir, self.relpath) |
| 334 if not os.path.isdir(path): | 334 if not os.path.isdir(path): |
| 335 # svn revert won't work if the directory doesn't exist. It needs to | 335 # svn revert won't work if the directory doesn't exist. It needs to |
| (...skipping 30 matching lines...) Expand all Loading... |
| 366 gclient_utils.RemoveDirectory(file_path) | 366 gclient_utils.RemoveDirectory(file_path) |
| 367 else: | 367 else: |
| 368 logging.error('no idea what is %s.\nYou just found a bug in gclient' | 368 logging.error('no idea what is %s.\nYou just found a bug in gclient' |
| 369 ', please ping maruel@chromium.org ASAP!' % file_path) | 369 ', please ping maruel@chromium.org ASAP!' % file_path) |
| 370 except EnvironmentError: | 370 except EnvironmentError: |
| 371 logging.error('Failed to remove %s.' % file_path) | 371 logging.error('Failed to remove %s.' % file_path) |
| 372 | 372 |
| 373 try: | 373 try: |
| 374 # svn revert is so broken we don't even use it. Using | 374 # svn revert is so broken we don't even use it. Using |
| 375 # "svn up --revision BASE" achieve the same effect. | 375 # "svn up --revision BASE" achieve the same effect. |
| 376 RunSVNAndGetFileList(['update', '--revision', 'BASE'], path, | 376 RunSVNAndGetFileList(options, ['update', '--revision', 'BASE'], path, |
| 377 file_list) | 377 file_list) |
| 378 except OSError, e: | 378 except OSError, e: |
| 379 # Maybe the directory disapeared meanwhile. We don't want it to throw an | 379 # Maybe the directory disapeared meanwhile. We don't want it to throw an |
| 380 # exception. | 380 # exception. |
| 381 logging.error('Failed to update:\n%s' % str(e)) | 381 logging.error('Failed to update:\n%s' % str(e)) |
| 382 | 382 |
| 383 def runhooks(self, options, args, file_list): | 383 def runhooks(self, options, args, file_list): |
| 384 self.status(options, args, file_list) | 384 self.status(options, args, file_list) |
| 385 | 385 |
| 386 def status(self, options, args, file_list): | 386 def status(self, options, args, file_list): |
| 387 """Display status information.""" | 387 """Display status information.""" |
| 388 path = os.path.join(self._root_dir, self.relpath) | 388 path = os.path.join(self._root_dir, self.relpath) |
| 389 command = ['status'] | 389 command = ['status'] |
| 390 command.extend(args) | 390 command.extend(args) |
| 391 if not os.path.isdir(path): | 391 if not os.path.isdir(path): |
| 392 # svn status won't work if the directory doesn't exist. | 392 # svn status won't work if the directory doesn't exist. |
| 393 print("\n________ couldn't run \'%s\' in \'%s\':\nThe directory " | 393 print("\n________ couldn't run \'%s\' in \'%s\':\nThe directory " |
| 394 "does not exist." | 394 "does not exist." |
| 395 % (' '.join(command), path)) | 395 % (' '.join(command), path)) |
| 396 # There's no file list to retrieve. | 396 # There's no file list to retrieve. |
| 397 else: | 397 else: |
| 398 RunSVNAndGetFileList(command, path, file_list) | 398 RunSVNAndGetFileList(options, command, path, file_list) |
| 399 | 399 |
| 400 def pack(self, options, args, file_list): | 400 def pack(self, options, args, file_list): |
| 401 """Generates a patch file which can be applied to the root of the | 401 """Generates a patch file which can be applied to the root of the |
| 402 repository.""" | 402 repository.""" |
| 403 path = os.path.join(self._root_dir, self.relpath) | 403 path = os.path.join(self._root_dir, self.relpath) |
| 404 command = ['diff'] | 404 command = ['diff'] |
| 405 command.extend(args) | 405 command.extend(args) |
| 406 # Simple class which tracks which file is being diffed and | 406 # Simple class which tracks which file is being diffed and |
| 407 # replaces instances of its file name in the original and | 407 # replaces instances of its file name in the original and |
| 408 # working copy lines of the svn diff output. | 408 # working copy lines of the svn diff output. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 stderr = None | 482 stderr = None |
| 483 if not print_error: | 483 if not print_error: |
| 484 stderr = subprocess.PIPE | 484 stderr = subprocess.PIPE |
| 485 return subprocess.Popen(c, | 485 return subprocess.Popen(c, |
| 486 cwd=in_directory, | 486 cwd=in_directory, |
| 487 shell=(sys.platform == 'win32'), | 487 shell=(sys.platform == 'win32'), |
| 488 stdout=subprocess.PIPE, | 488 stdout=subprocess.PIPE, |
| 489 stderr=stderr).communicate()[0] | 489 stderr=stderr).communicate()[0] |
| 490 | 490 |
| 491 | 491 |
| 492 def RunSVNAndGetFileList(args, in_directory, file_list): | 492 def RunSVNAndGetFileList(options, args, in_directory, file_list): |
| 493 """Runs svn checkout, update, or status, output to stdout. | 493 """Runs svn checkout, update, or status, output to stdout. |
| 494 | 494 |
| 495 The first item in args must be either "checkout", "update", or "status". | 495 The first item in args must be either "checkout", "update", or "status". |
| 496 | 496 |
| 497 svn's stdout is parsed to collect a list of files checked out or updated. | 497 svn's stdout is parsed to collect a list of files checked out or updated. |
| 498 These files are appended to file_list. svn's stdout is also printed to | 498 These files are appended to file_list. svn's stdout is also printed to |
| 499 sys.stdout as in RunSVN. | 499 sys.stdout as in RunSVN. |
| 500 | 500 |
| 501 Args: | 501 Args: |
| 502 options: command line options to gclient |
| 502 args: A sequence of command line parameters to be passed to svn. | 503 args: A sequence of command line parameters to be passed to svn. |
| 503 in_directory: The directory where svn is to be run. | 504 in_directory: The directory where svn is to be run. |
| 504 | 505 |
| 505 Raises: | 506 Raises: |
| 506 Error: An error occurred while running the svn command. | 507 Error: An error occurred while running the svn command. |
| 507 """ | 508 """ |
| 508 command = [SVN_COMMAND] | 509 command = [SVN_COMMAND] |
| 509 command.extend(args) | 510 command.extend(args) |
| 510 | 511 |
| 511 # svn update and svn checkout use the same pattern: the first three columns | 512 # svn update and svn checkout use the same pattern: the first three columns |
| (...skipping 19 matching lines...) Expand all Loading... |
| 531 | 532 |
| 532 compiled_pattern = re.compile(pattern) | 533 compiled_pattern = re.compile(pattern) |
| 533 | 534 |
| 534 def CaptureMatchingLines(line): | 535 def CaptureMatchingLines(line): |
| 535 match = compiled_pattern.search(line) | 536 match = compiled_pattern.search(line) |
| 536 if match: | 537 if match: |
| 537 file_list.append(match.group(1)) | 538 file_list.append(match.group(1)) |
| 538 | 539 |
| 539 RunSVNAndFilterOutput(args, | 540 RunSVNAndFilterOutput(args, |
| 540 in_directory, | 541 in_directory, |
| 541 True, | 542 options.verbose, |
| 542 True, | 543 True, |
| 543 CaptureMatchingLines) | 544 CaptureMatchingLines) |
| 544 | 545 |
| 545 def RunSVNAndFilterOutput(args, | 546 def RunSVNAndFilterOutput(args, |
| 546 in_directory, | 547 in_directory, |
| 547 print_messages, | 548 print_messages, |
| 548 print_stdout, | 549 print_stdout, |
| 549 filter): | 550 filter): |
| 550 """Runs svn checkout, update, status, or diff, optionally outputting | 551 """Runs svn checkout, update, status, or diff, optionally outputting |
| 551 to stdout. | 552 to stdout. |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 # Col 3 | 698 # Col 3 |
| 698 if wc_status[0].getAttribute('copied') == 'true': | 699 if wc_status[0].getAttribute('copied') == 'true': |
| 699 statuses[3] = '+' | 700 statuses[3] = '+' |
| 700 # Col 4 | 701 # Col 4 |
| 701 if wc_status[0].getAttribute('switched') == 'true': | 702 if wc_status[0].getAttribute('switched') == 'true': |
| 702 statuses[4] = 'S' | 703 statuses[4] = 'S' |
| 703 # TODO(maruel): Col 5 and 6 | 704 # TODO(maruel): Col 5 and 6 |
| 704 item = (''.join(statuses), file) | 705 item = (''.join(statuses), file) |
| 705 results.append(item) | 706 results.append(item) |
| 706 return results | 707 return results |
| OLD | NEW |