| OLD | NEW |
| 1 # coding=utf8 | 1 # coding=utf8 |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 | 6 |
| 7 Includes support for svn, git-svn and git. | 7 Includes support for svn, git-svn and git. |
| 8 """ | 8 """ |
| 9 | 9 |
| 10 from __future__ import with_statement | 10 from __future__ import with_statement |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 os.remove(filename) | 120 os.remove(filename) |
| 121 else: | 121 else: |
| 122 dirname = os.path.dirname(p.filename) | 122 dirname = os.path.dirname(p.filename) |
| 123 full_dir = os.path.join(self.project_path, dirname) | 123 full_dir = os.path.join(self.project_path, dirname) |
| 124 if dirname and not os.path.isdir(full_dir): | 124 if dirname and not os.path.isdir(full_dir): |
| 125 os.makedirs(full_dir) | 125 os.makedirs(full_dir) |
| 126 if p.is_binary: | 126 if p.is_binary: |
| 127 with open(os.path.join(filename), 'wb') as f: | 127 with open(os.path.join(filename), 'wb') as f: |
| 128 f.write(p.get()) | 128 f.write(p.get()) |
| 129 else: | 129 else: |
| 130 stdout = subprocess2.check_output( | 130 if p.diff_hunks: |
| 131 ['patch', '-p%s' % p.patchlevel], | 131 stdout = subprocess2.check_output( |
| 132 stdin=p.get(), | 132 ['patch', '-p%s' % p.patchlevel], |
| 133 cwd=self.project_path) | 133 stdin=p.get(), |
| 134 cwd=self.project_path) |
| 135 elif p.is_new: |
| 136 # There is only a header. Just create the file. |
| 137 open(os.path.join(self.project_path, p.filename), 'w').close() |
| 134 for post in post_processor: | 138 for post in post_processor: |
| 135 post(self, p) | 139 post(self, p) |
| 136 except OSError, e: | 140 except OSError, e: |
| 137 raise PatchApplicationFailed(p.filename, '%s%s' % (stdout, e)) | 141 raise PatchApplicationFailed(p.filename, '%s%s' % (stdout, e)) |
| 138 except subprocess.CalledProcessError, e: | 142 except subprocess.CalledProcessError, e: |
| 139 raise PatchApplicationFailed( | 143 raise PatchApplicationFailed( |
| 140 p.filename, '%s%s' % (stdout, getattr(e, 'stdout', None))) | 144 p.filename, '%s%s' % (stdout, getattr(e, 'stdout', None))) |
| 141 | 145 |
| 142 def commit(self, commit_message, user): | 146 def commit(self, commit_message, user): |
| 143 """Stubbed out.""" | 147 """Stubbed out.""" |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 for p in patches: | 255 for p in patches: |
| 252 try: | 256 try: |
| 253 # It is important to use credentials=False otherwise credentials could | 257 # It is important to use credentials=False otherwise credentials could |
| 254 # leak in the error message. Credentials are not necessary here for the | 258 # leak in the error message. Credentials are not necessary here for the |
| 255 # following commands anyway. | 259 # following commands anyway. |
| 256 stdout = '' | 260 stdout = '' |
| 257 if p.is_delete: | 261 if p.is_delete: |
| 258 stdout += self._check_output_svn( | 262 stdout += self._check_output_svn( |
| 259 ['delete', p.filename, '--force'], credentials=False) | 263 ['delete', p.filename, '--force'], credentials=False) |
| 260 else: | 264 else: |
| 261 new = not os.path.exists(p.filename) | |
| 262 | |
| 263 # svn add while creating directories otherwise svn add on the | 265 # svn add while creating directories otherwise svn add on the |
| 264 # contained files will silently fail. | 266 # contained files will silently fail. |
| 265 # First, find the root directory that exists. | 267 # First, find the root directory that exists. |
| 266 dirname = os.path.dirname(p.filename) | 268 dirname = os.path.dirname(p.filename) |
| 267 dirs_to_create = [] | 269 dirs_to_create = [] |
| 268 while (dirname and | 270 while (dirname and |
| 269 not os.path.isdir(os.path.join(self.project_path, dirname))): | 271 not os.path.isdir(os.path.join(self.project_path, dirname))): |
| 270 dirs_to_create.append(dirname) | 272 dirs_to_create.append(dirname) |
| 271 dirname = os.path.dirname(dirname) | 273 dirname = os.path.dirname(dirname) |
| 272 for dir_to_create in reversed(dirs_to_create): | 274 for dir_to_create in reversed(dirs_to_create): |
| 273 os.mkdir(os.path.join(self.project_path, dir_to_create)) | 275 os.mkdir(os.path.join(self.project_path, dir_to_create)) |
| 274 stdout += self._check_output_svn( | 276 stdout += self._check_output_svn( |
| 275 ['add', dir_to_create, '--force'], credentials=False) | 277 ['add', dir_to_create, '--force'], credentials=False) |
| 276 | 278 |
| 277 if p.is_binary: | 279 if p.is_binary: |
| 278 with open(os.path.join(self.project_path, p.filename), 'wb') as f: | 280 with open(os.path.join(self.project_path, p.filename), 'wb') as f: |
| 279 f.write(p.get()) | 281 f.write(p.get()) |
| 280 else: | 282 else: |
| 281 cmd = ['patch', '-p%s' % p.patchlevel, '--forward', '--force'] | 283 if p.diff_hunks: |
| 282 stdout += subprocess2.check_output( | 284 cmd = ['patch', '-p%s' % p.patchlevel, '--forward', '--force'] |
| 283 cmd, stdin=p.get(), cwd=self.project_path) | 285 stdout += subprocess2.check_output( |
| 284 if new: | 286 cmd, stdin=p.get(), cwd=self.project_path) |
| 287 elif p.is_new: |
| 288 # There is only a header. Just create the file. |
| 289 open(os.path.join(self.project_path, p.filename), 'w').close() |
| 290 if p.is_new: |
| 285 stdout += self._check_output_svn( | 291 stdout += self._check_output_svn( |
| 286 ['add', p.filename, '--force'], credentials=False) | 292 ['add', p.filename, '--force'], credentials=False) |
| 287 for prop in p.svn_properties: | 293 for prop in p.svn_properties: |
| 288 stdout += self._check_output_svn( | 294 stdout += self._check_output_svn( |
| 289 ['propset', prop[0], prop[1], p.filename], credentials=False) | 295 ['propset', prop[0], prop[1], p.filename], credentials=False) |
| 290 for prop, values in self.svn_config.auto_props.iteritems(): | 296 for prop, values in self.svn_config.auto_props.iteritems(): |
| 291 if fnmatch.fnmatch(p.filename, prop): | 297 if fnmatch.fnmatch(p.filename, prop): |
| 292 for value in values.split(';'): | 298 for value in values.split(';'): |
| 293 if '=' not in value: | 299 if '=' not in value: |
| 294 params = [value, '*'] | 300 params = [value, '*'] |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 else: | 409 else: |
| 404 dirname = os.path.dirname(p.filename) | 410 dirname = os.path.dirname(p.filename) |
| 405 full_dir = os.path.join(self.project_path, dirname) | 411 full_dir = os.path.join(self.project_path, dirname) |
| 406 if dirname and not os.path.isdir(full_dir): | 412 if dirname and not os.path.isdir(full_dir): |
| 407 os.makedirs(full_dir) | 413 os.makedirs(full_dir) |
| 408 if p.is_binary: | 414 if p.is_binary: |
| 409 with open(os.path.join(self.project_path, p.filename), 'wb') as f: | 415 with open(os.path.join(self.project_path, p.filename), 'wb') as f: |
| 410 f.write(p.get()) | 416 f.write(p.get()) |
| 411 stdout += self._check_output_git(['add', p.filename]) | 417 stdout += self._check_output_git(['add', p.filename]) |
| 412 else: | 418 else: |
| 419 # No need to do anything special with p.is_new or if not |
| 420 # p.diff_hunks. git apply manages all that already. |
| 413 stdout += self._check_output_git( | 421 stdout += self._check_output_git( |
| 414 ['apply', '--index', '-p%s' % p.patchlevel], stdin=p.get()) | 422 ['apply', '--index', '-p%s' % p.patchlevel], stdin=p.get()) |
| 415 for prop in p.svn_properties: | 423 for prop in p.svn_properties: |
| 416 # Ignore some known auto-props flags through .subversion/config, | 424 # Ignore some known auto-props flags through .subversion/config, |
| 417 # bails out on the other ones. | 425 # bails out on the other ones. |
| 418 # TODO(maruel): Read ~/.subversion/config and detect the rules that | 426 # TODO(maruel): Read ~/.subversion/config and detect the rules that |
| 419 # applies here to figure out if the property will be correctly | 427 # applies here to figure out if the property will be correctly |
| 420 # handled. | 428 # handled. |
| 421 if not prop[0] in ('svn:eol-style', 'svn:executable'): | 429 if not prop[0] in ('svn:eol-style', 'svn:executable'): |
| 422 raise patch.UnsupportedPatchFormat( | 430 raise patch.UnsupportedPatchFormat( |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 user, message)) | 667 user, message)) |
| 660 return 'FAKE' | 668 return 'FAKE' |
| 661 | 669 |
| 662 @property | 670 @property |
| 663 def project_name(self): | 671 def project_name(self): |
| 664 return self.checkout.project_name | 672 return self.checkout.project_name |
| 665 | 673 |
| 666 @property | 674 @property |
| 667 def project_path(self): | 675 def project_path(self): |
| 668 return self.checkout.project_path | 676 return self.checkout.project_path |
| OLD | NEW |