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