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 |