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 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 post(self, p) | 288 post(self, p) |
289 except OSError, e: | 289 except OSError, e: |
290 raise PatchApplicationFailed(p.filename, '%s%s' % (stdout, e)) | 290 raise PatchApplicationFailed(p.filename, '%s%s' % (stdout, e)) |
291 except subprocess.CalledProcessError, e: | 291 except subprocess.CalledProcessError, e: |
292 raise PatchApplicationFailed( | 292 raise PatchApplicationFailed( |
293 p.filename, '%s%s' % (stdout, getattr(e, 'stdout', ''))) | 293 p.filename, '%s%s' % (stdout, getattr(e, 'stdout', ''))) |
294 | 294 |
295 def commit(self, commit_message, user): | 295 def commit(self, commit_message, user): |
296 logging.info('Committing patch for %s' % user) | 296 logging.info('Committing patch for %s' % user) |
297 assert self.commit_user | 297 assert self.commit_user |
| 298 assert isinstance(commit_message, unicode) |
298 handle, commit_filename = tempfile.mkstemp(text=True) | 299 handle, commit_filename = tempfile.mkstemp(text=True) |
299 try: | 300 try: |
300 os.write(handle, commit_message) | 301 # Shouldn't assume default encoding is UTF-8. But really, if you are using |
| 302 # anything else, you are living in another world. |
| 303 os.write(handle, commit_message.encode('utf-8')) |
301 os.close(handle) | 304 os.close(handle) |
302 # When committing, svn won't update the Revision metadata of the checkout, | 305 # When committing, svn won't update the Revision metadata of the checkout, |
303 # so if svn commit returns "Committed revision 3.", svn info will still | 306 # so if svn commit returns "Committed revision 3.", svn info will still |
304 # return "Revision: 2". Since running svn update right after svn commit | 307 # return "Revision: 2". Since running svn update right after svn commit |
305 # creates a race condition with other committers, this code _must_ parse | 308 # creates a race condition with other committers, this code _must_ parse |
306 # the output of svn commit and use a regexp to grab the revision number. | 309 # the output of svn commit and use a regexp to grab the revision number. |
307 # Note that "Committed revision N." is localized but subprocess2 forces | 310 # Note that "Committed revision N." is localized but subprocess2 forces |
308 # LANGUAGE=en. | 311 # LANGUAGE=en. |
309 args = ['commit', '--file', commit_filename] | 312 args = ['commit', '--file', commit_filename] |
310 # realauthor is parsed by a server-side hook. | 313 # realauthor is parsed by a server-side hook. |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 #found_files = self._check_output_git( | 423 #found_files = self._check_output_git( |
421 # ['diff', 'master', '--name-only']).splitlines(False) | 424 # ['diff', 'master', '--name-only']).splitlines(False) |
422 #assert sorted(patches.filenames) == sorted(found_files), ( | 425 #assert sorted(patches.filenames) == sorted(found_files), ( |
423 # sorted(out), sorted(found_files)) | 426 # sorted(out), sorted(found_files)) |
424 | 427 |
425 def commit(self, commit_message, user): | 428 def commit(self, commit_message, user): |
426 """Updates the commit message. | 429 """Updates the commit message. |
427 | 430 |
428 Subclass needs to dcommit or push. | 431 Subclass needs to dcommit or push. |
429 """ | 432 """ |
| 433 assert isinstance(commit_message, unicode) |
430 self._check_call_git(['commit', '--amend', '-m', commit_message]) | 434 self._check_call_git(['commit', '--amend', '-m', commit_message]) |
431 return self._check_output_git(['rev-parse', 'HEAD']).strip() | 435 return self._check_output_git(['rev-parse', 'HEAD']).strip() |
432 | 436 |
433 def _check_call_git(self, args, **kwargs): | 437 def _check_call_git(self, args, **kwargs): |
434 kwargs.setdefault('cwd', self.project_path) | 438 kwargs.setdefault('cwd', self.project_path) |
435 kwargs.setdefault('stdout', self.VOID) | 439 kwargs.setdefault('stdout', self.VOID) |
436 return subprocess2.check_call_out(['git'] + args, **kwargs) | 440 return subprocess2.check_call_out(['git'] + args, **kwargs) |
437 | 441 |
438 def _call_git(self, args, **kwargs): | 442 def _call_git(self, args, **kwargs): |
439 """Like check_call but doesn't throw on failure.""" | 443 """Like check_call but doesn't throw on failure.""" |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 user, message)) | 645 user, message)) |
642 return 'FAKE' | 646 return 'FAKE' |
643 | 647 |
644 @property | 648 @property |
645 def project_name(self): | 649 def project_name(self): |
646 return self.checkout.project_name | 650 return self.checkout.project_name |
647 | 651 |
648 @property | 652 @property |
649 def project_path(self): | 653 def project_path(self): |
650 return self.checkout.project_path | 654 return self.checkout.project_path |
OLD | NEW |