| OLD | NEW |
| 1 # coding=utf8 | 1 # coding=utf8 |
| 2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2010 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 """Manages a project checkout. | 5 """Manages a project checkout. |
| 6 |
| 7 Includes support for svn, git-svn and git. |
| 6 """ | 8 """ |
| 7 | 9 |
| 8 import logging | 10 import logging |
| 9 import os | 11 import os |
| 10 import re | 12 import re |
| 11 import subprocess | 13 import subprocess |
| 12 import tempfile | 14 import tempfile |
| 13 | 15 |
| 16 import patch |
| 14 import subprocess2 | 17 import subprocess2 |
| 15 import svn_utils | 18 import svn_utils |
| 16 | 19 |
| 17 | 20 |
| 18 def get_code_review_setting(path, key, | 21 def get_code_review_setting(path, key, |
| 19 codereview_settings_file='codereview.settings'): | 22 codereview_settings_file='codereview.settings'): |
| 20 """Parses codereview.settings and return the value for the key if present. | 23 """Parses codereview.settings and return the value for the key if present. |
| 21 | 24 |
| 22 Don't cache the values in case the file is changed.""" | 25 Don't cache the values in case the file is changed.""" |
| 23 settings = {} | 26 settings = {} |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 Commit is not fully implemented yet. Reimplementing all the commands is | 58 Commit is not fully implemented yet. Reimplementing all the commands is |
| 56 slightly complex, svn add with history needs to be done with svn | 59 slightly complex, svn add with history needs to be done with svn |
| 57 copy/rename/move and the situation quickly becomes harder when directories are | 60 copy/rename/move and the situation quickly becomes harder when directories are |
| 58 moved. | 61 moved. |
| 59 """ | 62 """ |
| 60 def __init__(self, root_dir, project_name, commit_user, commit_pwd, svn_url): | 63 def __init__(self, root_dir, project_name, commit_user, commit_pwd, svn_url): |
| 61 super(SvnCheckout, self).__init__(root_dir, project_name) | 64 super(SvnCheckout, self).__init__(root_dir, project_name) |
| 62 self.commit_user = commit_user | 65 self.commit_user = commit_user |
| 63 self.commit_pwd = commit_pwd | 66 self.commit_pwd = commit_pwd |
| 64 self.svn_url = svn_url | 67 self.svn_url = svn_url |
| 68 assert bool(self.commit_user) == bool(self.commit_pwd) |
| 69 assert bool(self.svn_url) |
| 65 | 70 |
| 66 def prepare(self): | 71 def prepare(self): |
| 67 """Creates the initial checkouts for the repo.""" | 72 """Creates the initial checkouts for the repo.""" |
| 68 # Will checkout if the directory is not present. | 73 # Will checkout if the directory is not present. |
| 69 logging.info('Checking out %s in %s' % | 74 logging.info('Checking out %s in %s' % |
| 70 (self.project_name, self.project_path)) | 75 (self.project_name, self.project_path)) |
| 71 return svn_utils.revert( | 76 return svn_utils.revert( |
| 72 self.svn_url, | 77 self.svn_url, |
| 73 self.project_path, | 78 self.project_path, |
| 74 self.commit_user, | 79 self.commit_user, |
| 75 self.commit_pwd) | 80 self.commit_pwd) |
| 76 | 81 |
| 77 def apply_patch(self, patch): | 82 def apply_patch(self, patch_data): |
| 78 """Applies a patch.""" | 83 """Applies a patch.""" |
| 79 try: | 84 try: |
| 80 svn_utils.apply_patch(self.project_path, patch) | 85 patch.apply_patch(self.project_path, patch_data) |
| 81 return True | 86 return True |
| 82 except subprocess.CalledProcessError, e: | 87 except subprocess.CalledProcessError, e: |
| 83 if e.returncode == 1: | 88 if e.returncode == 1: |
| 84 return False | 89 return False |
| 85 raise | 90 raise |
| 86 | 91 |
| 87 def commit(self, commit_message, user): | 92 def commit(self, commit_message, user): |
| 88 """Commits a patch.""" | 93 """Commits a patch.""" |
| 89 logging.info('Committing patch for %s' % user) | 94 logging.info('Committing patch for %s' % user) |
| 90 assert self.commit_user | 95 assert self.commit_user |
| (...skipping 29 matching lines...) Expand all Loading... |
| 120 self.remote_branch = remote_branch | 125 self.remote_branch = remote_branch |
| 121 self.working_branch = 'working_branch' | 126 self.working_branch = 'working_branch' |
| 122 | 127 |
| 123 def prepare(self): | 128 def prepare(self): |
| 124 """Resets the git repository in a clean state.""" | 129 """Resets the git repository in a clean state.""" |
| 125 assert os.path.isdir(self.project_path) | 130 assert os.path.isdir(self.project_path) |
| 126 self.check_call(['checkout', 'master', '--force']) | 131 self.check_call(['checkout', 'master', '--force']) |
| 127 self.check_call(['pull', self.remote, self.remote_branch]) | 132 self.check_call(['pull', self.remote, self.remote_branch]) |
| 128 self.call(['branch', '-D', self.working_branch]) | 133 self.call(['branch', '-D', self.working_branch]) |
| 129 | 134 |
| 130 def apply_patch(self, patch): | 135 def apply_patch(self, patch_data): |
| 131 """Applies a patch on 'working_branch'.""" | 136 """Applies a patch on 'working_branch'.""" |
| 132 self.check_call( | 137 self.check_call( |
| 133 ['checkout', '-b', self.working_branch, | 138 ['checkout', '-b', self.working_branch, |
| 134 '%s/%s' % (self.remote, self.remote_branch)]) | 139 '%s/%s' % (self.remote, self.remote_branch)]) |
| 135 self.check_call(['apply', '--index', '-p0'], stdin=patch) | 140 self.check_call(['apply', '--index', '-p0'], stdin=patch_data) |
| 136 self.check_call(['commit', '-m', 'Committed patch']) | 141 self.check_call(['commit', '-m', 'Committed patch']) |
| 137 | 142 |
| 138 def commit(self, commit_message, user): | 143 def commit(self, commit_message, user): |
| 139 self.check_call(['commit', '--amend', '-m', commit_message]) | 144 self.check_call(['commit', '--amend', '-m', commit_message]) |
| 140 | 145 |
| 141 def check_call(self, args, **kwargs): | 146 def check_call(self, args, **kwargs): |
| 142 kwargs.setdefault('cwd', self.project_path) | 147 kwargs.setdefault('cwd', self.project_path) |
| 143 return subprocess2.check_call(['git'] + args, **kwargs) | 148 return subprocess2.check_call(['git'] + args, **kwargs) |
| 144 | 149 |
| 145 def call(self, args, **kwargs): | 150 def call(self, args, **kwargs): |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 """Converts a checkout into a read-only one.""" | 284 """Converts a checkout into a read-only one.""" |
| 280 def __init__(self, checkout): | 285 def __init__(self, checkout): |
| 281 self.checkout = checkout | 286 self.checkout = checkout |
| 282 | 287 |
| 283 def prepare(self): | 288 def prepare(self): |
| 284 return self.checkout.prepare() | 289 return self.checkout.prepare() |
| 285 | 290 |
| 286 def get_settings(self, key): | 291 def get_settings(self, key): |
| 287 return self.checkout.get_settings(key) | 292 return self.checkout.get_settings(key) |
| 288 | 293 |
| 289 def apply_patch(self, patch): | 294 def apply_patch(self, patch_data): |
| 290 return self.checkout.apply_patch(patch) | 295 return self.checkout.apply_patch(patch_data) |
| 291 | 296 |
| 292 def commit(self, message, user): | 297 def commit(self, message, user): |
| 293 logging.info('Would have committed for %s with message: %s' % ( | 298 logging.info('Would have committed for %s with message: %s' % ( |
| 294 user, message)) | 299 user, message)) |
| 295 return 'FAKE' | 300 return 'FAKE' |
| 296 | 301 |
| 297 @property | 302 @property |
| 298 def project_name(self): | 303 def project_name(self): |
| 299 return self.checkout.project_name | 304 return self.checkout.project_name |
| 300 | 305 |
| 301 @property | 306 @property |
| 302 def project_path(self): | 307 def project_path(self): |
| 303 return self.checkout.project_path | 308 return self.checkout.project_path |
| OLD | NEW |