| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 """Utility functions to call subversion, apply and revert patches.""" | |
| 5 | |
| 6 import logging | |
| 7 import os | |
| 8 | |
| 9 import find_depot_tools # pylint: disable=W0611 | |
| 10 import gclient_utils | |
| 11 import scm | |
| 12 | |
| 13 import subprocess2 | |
| 14 | |
| 15 | |
| 16 def svn(args, **kwargs): | |
| 17 """Runs svn and throws an exception if the command failed.""" | |
| 18 return subprocess2.check_call( | |
| 19 ['svn'] + args + ['--no-auth-cache', '--non-interactive'], **kwargs) | |
| 20 | |
| 21 | |
| 22 def capture_svn(args, **kwargs): | |
| 23 """Runs svn and throws an exception if the command failed. Returns the output. | |
| 24 """ | |
| 25 cmd = ['svn'] + args + ['--no-auth-cache', '--non-interactive'] | |
| 26 return subprocess2.check_capture(cmd, **kwargs) | |
| 27 | |
| 28 | |
| 29 def parse_svn_info(output, key): | |
| 30 """Returns value for key from svn info output. | |
| 31 | |
| 32 Case insensitive. | |
| 33 """ | |
| 34 values = {} | |
| 35 for line in output.splitlines(False): | |
| 36 if not line: | |
| 37 continue | |
| 38 k, v = line.split(':', 1) | |
| 39 k = k.strip().lower() | |
| 40 v = v.strip() | |
| 41 assert not k in values | |
| 42 values[k] = v | |
| 43 return values.get(key, None) | |
| 44 | |
| 45 | |
| 46 def revert(url, directory, user, pwd): | |
| 47 """Reverts local modifications or checks out if the directory is not present. | |
| 48 """ | |
| 49 assert url | |
| 50 assert bool(user) == bool(pwd) | |
| 51 flags = ['--ignore-externals'] | |
| 52 if user: | |
| 53 flags.extend(['--username', user, '--password', pwd]) | |
| 54 | |
| 55 if not os.path.isdir(directory): | |
| 56 logging.info('Directory %s is not present, checking it out.' % directory) | |
| 57 svn(['checkout', url, directory] + flags) | |
| 58 else: | |
| 59 for file_status in scm.SVN.CaptureStatus(directory): | |
| 60 file_path = os.path.join(directory, file_status[1]) | |
| 61 if file_status[0][0] == 'X': | |
| 62 # Ignore externals. | |
| 63 logging.info('Ignoring external %s' % file_path) | |
| 64 continue | |
| 65 | |
| 66 logging.info('%s%s' % (file_status[0], file_status[1])) | |
| 67 | |
| 68 if file_status[0].isspace(): | |
| 69 raise EnvironmentError( | |
| 70 'No idea what is the status of %s.\n' | |
| 71 'You just found a bug in gclient, please ping ' | |
| 72 'maruel@chromium.org ASAP!' % file_path) | |
| 73 | |
| 74 # svn revert is really stupid. It fails on inconsistent line-endings, | |
| 75 # on switched directories, etc. So take no chance and delete everything! | |
| 76 try: | |
| 77 if not os.path.exists(file_path): | |
| 78 pass | |
| 79 elif os.path.isfile(file_path) or os.path.islink(file_path): | |
| 80 logging.info('os.remove(%s)' % file_path) | |
| 81 os.remove(file_path) | |
| 82 elif os.path.isdir(file_path): | |
| 83 logging.info('gclient_utils.RemoveDirectory(%s)' % file_path) | |
| 84 gclient_utils.RemoveDirectory(file_path) | |
| 85 else: | |
| 86 logging.error('no idea what is %s.\nYou just found a bug in gclient' | |
| 87 ', please ping maruel@chromium.org ASAP!' % file_path) | |
| 88 except EnvironmentError: | |
| 89 logging.error('Failed to remove %s.' % file_path) | |
| 90 | |
| 91 # Revive files that were deleted above. | |
| 92 svn(['update', '--force'] + flags, cwd=directory) | |
| 93 | |
| 94 out = subprocess2.check_capture(['svn', 'info', '.'], cwd=directory) | |
| 95 return int(parse_svn_info(out, 'revision')) | |
| 96 | |
| 97 | |
| 98 def update_committer(url, revision, committer, password, new_author, cwd): | |
| 99 """Changes the author of a commit a posteriori. | |
| 100 | |
| 101 This is necessary since the actual commit is done with a "commit-bot" | |
| 102 credential but the original patch author needs to be assigned authorship | |
| 103 of the revision. | |
| 104 """ | |
| 105 svn(['propset', '--revprop', 'svn:author', | |
| 106 '-r', revision, | |
| 107 new_author, | |
| 108 '--username', committer, | |
| 109 '--password', password, | |
| 110 url], | |
| 111 cwd=cwd) | |
| OLD | NEW |