OLD | NEW |
1 # coding=utf8 | 1 # coding=utf8 |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 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 import ConfigParser | 10 import ConfigParser |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 """Checks out a clean copy of the tree and removes any local modification. | 124 """Checks out a clean copy of the tree and removes any local modification. |
125 | 125 |
126 This function shouldn't throw unless the remote repository is inaccessible, | 126 This function shouldn't throw unless the remote repository is inaccessible, |
127 there is no free disk space or hard issues like that. | 127 there is no free disk space or hard issues like that. |
128 | 128 |
129 Args: | 129 Args: |
130 revision: The revision it should sync to, SCM specific. | 130 revision: The revision it should sync to, SCM specific. |
131 """ | 131 """ |
132 raise NotImplementedError() | 132 raise NotImplementedError() |
133 | 133 |
134 def apply_patch(self, patches, post_processors=None, verbose=False): | 134 def apply_patch(self, patches, post_processors=None, verbose=False, |
| 135 name=None, email=None): |
135 """Applies a patch and returns the list of modified files. | 136 """Applies a patch and returns the list of modified files. |
136 | 137 |
137 This function should throw patch.UnsupportedPatchFormat or | 138 This function should throw patch.UnsupportedPatchFormat or |
138 PatchApplicationFailed when relevant. | 139 PatchApplicationFailed when relevant. |
139 | 140 |
140 Args: | 141 Args: |
141 patches: patch.PatchSet object. | 142 patches: patch.PatchSet object. |
142 """ | 143 """ |
143 raise NotImplementedError() | 144 raise NotImplementedError() |
144 | 145 |
(...skipping 13 matching lines...) Expand all Loading... |
158 | 159 |
159 class RawCheckout(CheckoutBase): | 160 class RawCheckout(CheckoutBase): |
160 """Used to apply a patch locally without any intent to commit it. | 161 """Used to apply a patch locally without any intent to commit it. |
161 | 162 |
162 To be used by the try server. | 163 To be used by the try server. |
163 """ | 164 """ |
164 def prepare(self, revision): | 165 def prepare(self, revision): |
165 """Stubbed out.""" | 166 """Stubbed out.""" |
166 pass | 167 pass |
167 | 168 |
168 def apply_patch(self, patches, post_processors=None, verbose=False): | 169 def apply_patch(self, patches, post_processors=None, verbose=False, |
| 170 name=None, email=None): |
169 """Ignores svn properties.""" | 171 """Ignores svn properties.""" |
170 post_processors = post_processors or self.post_processors or [] | 172 post_processors = post_processors or self.post_processors or [] |
171 for p in patches: | 173 for p in patches: |
172 stdout = [] | 174 stdout = [] |
173 try: | 175 try: |
174 filepath = os.path.join(self.project_path, p.filename) | 176 filepath = os.path.join(self.project_path, p.filename) |
175 if p.is_delete: | 177 if p.is_delete: |
176 os.remove(filepath) | 178 os.remove(filepath) |
177 stdout.append('Deleted.') | 179 stdout.append('Deleted.') |
178 else: | 180 else: |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 assert bool(self.commit_user) >= bool(self.commit_pwd) | 344 assert bool(self.commit_user) >= bool(self.commit_pwd) |
343 | 345 |
344 def prepare(self, revision): | 346 def prepare(self, revision): |
345 # Will checkout if the directory is not present. | 347 # Will checkout if the directory is not present. |
346 assert self.svn_url | 348 assert self.svn_url |
347 if not os.path.isdir(self.project_path): | 349 if not os.path.isdir(self.project_path): |
348 logging.info('Checking out %s in %s' % | 350 logging.info('Checking out %s in %s' % |
349 (self.project_name, self.project_path)) | 351 (self.project_name, self.project_path)) |
350 return self._revert(revision) | 352 return self._revert(revision) |
351 | 353 |
352 def apply_patch(self, patches, post_processors=None, verbose=False): | 354 def apply_patch(self, patches, post_processors=None, verbose=False, |
| 355 name=None, email=None): |
353 post_processors = post_processors or self.post_processors or [] | 356 post_processors = post_processors or self.post_processors or [] |
354 for p in patches: | 357 for p in patches: |
355 stdout = [] | 358 stdout = [] |
356 try: | 359 try: |
357 filepath = os.path.join(self.project_path, p.filename) | 360 filepath = os.path.join(self.project_path, p.filename) |
358 # It is important to use credentials=False otherwise credentials could | 361 # It is important to use credentials=False otherwise credentials could |
359 # leak in the error message. Credentials are not necessary here for the | 362 # leak in the error message. Credentials are not necessary here for the |
360 # following commands anyway. | 363 # following commands anyway. |
361 if p.is_delete: | 364 if p.is_delete: |
362 stdout.append(self._check_output_svn( | 365 stdout.append(self._check_output_svn( |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 self.remote, self.remote_branch) | 624 self.remote, self.remote_branch) |
622 self._check_call_git( | 625 self._check_call_git( |
623 ['pull', self.remote, | 626 ['pull', self.remote, |
624 '%s:%s' % (self.remote_branch, remote_tracked_path), | 627 '%s:%s' % (self.remote_branch, remote_tracked_path), |
625 '--quiet']) | 628 '--quiet']) |
626 | 629 |
627 def _get_head_commit_hash(self): | 630 def _get_head_commit_hash(self): |
628 """Gets the current revision (in unicode) from the local branch.""" | 631 """Gets the current revision (in unicode) from the local branch.""" |
629 return unicode(self._check_output_git(['rev-parse', 'HEAD']).strip()) | 632 return unicode(self._check_output_git(['rev-parse', 'HEAD']).strip()) |
630 | 633 |
631 def apply_patch(self, patches, post_processors=None, verbose=False): | 634 def apply_patch(self, patches, post_processors=None, verbose=False, |
| 635 name=None, email=None): |
632 """Applies a patch on 'working_branch' and switches to it. | 636 """Applies a patch on 'working_branch' and switches to it. |
633 | 637 |
634 Also commits the changes on the local branch. | 638 Also commits the changes on the local branch. |
635 | 639 |
636 Ignores svn properties and raise an exception on unexpected ones. | 640 Ignores svn properties and raise an exception on unexpected ones. |
637 """ | 641 """ |
638 post_processors = post_processors or self.post_processors or [] | 642 post_processors = post_processors or self.post_processors or [] |
639 # It this throws, the checkout is corrupted. Maybe worth deleting it and | 643 # It this throws, the checkout is corrupted. Maybe worth deleting it and |
640 # trying again? | 644 # trying again? |
641 if self.remote_branch: | 645 if self.remote_branch: |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 except subprocess.CalledProcessError, e: | 705 except subprocess.CalledProcessError, e: |
702 raise PatchApplicationFailed( | 706 raise PatchApplicationFailed( |
703 p, | 707 p, |
704 'While running %s;\n%s%s' % ( | 708 'While running %s;\n%s%s' % ( |
705 ' '.join(e.cmd), | 709 ' '.join(e.cmd), |
706 align_stdout(stdout), | 710 align_stdout(stdout), |
707 align_stdout([getattr(e, 'stdout', '')]))) | 711 align_stdout([getattr(e, 'stdout', '')]))) |
708 # Once all the patches are processed and added to the index, commit the | 712 # Once all the patches are processed and added to the index, commit the |
709 # index. | 713 # index. |
710 cmd = ['commit', '-m', 'Committed patch'] | 714 cmd = ['commit', '-m', 'Committed patch'] |
| 715 if name and email: |
| 716 author = '%s <%s>' % (name, email) |
| 717 cmd.extend(['--author', author]) |
711 if verbose: | 718 if verbose: |
712 cmd.append('--verbose') | 719 cmd.append('--verbose') |
713 self._check_call_git(cmd) | 720 self._check_call_git(cmd) |
714 if self.base_ref: | 721 if self.base_ref: |
715 base_ref = self.base_ref | 722 base_ref = self.base_ref |
716 else: | 723 else: |
717 base_ref = '%s/%s' % (self.remote, | 724 base_ref = '%s/%s' % (self.remote, |
718 self.remote_branch or self.master_branch) | 725 self.remote_branch or self.master_branch) |
719 found_files = self._check_output_git( | 726 found_files = self._check_output_git( |
720 ['diff', base_ref, | 727 ['diff', base_ref, |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 self.checkout = checkout | 818 self.checkout = checkout |
812 self.post_processors = (post_processors or []) + ( | 819 self.post_processors = (post_processors or []) + ( |
813 self.checkout.post_processors or []) | 820 self.checkout.post_processors or []) |
814 | 821 |
815 def prepare(self, revision): | 822 def prepare(self, revision): |
816 return self.checkout.prepare(revision) | 823 return self.checkout.prepare(revision) |
817 | 824 |
818 def get_settings(self, key): | 825 def get_settings(self, key): |
819 return self.checkout.get_settings(key) | 826 return self.checkout.get_settings(key) |
820 | 827 |
821 def apply_patch(self, patches, post_processors=None, verbose=False): | 828 def apply_patch(self, patches, post_processors=None, verbose=False, |
| 829 name=None, email=None): |
822 return self.checkout.apply_patch( | 830 return self.checkout.apply_patch( |
823 patches, post_processors or self.post_processors, verbose) | 831 patches, post_processors or self.post_processors, verbose) |
824 | 832 |
825 def commit(self, message, user): # pylint: disable=R0201 | 833 def commit(self, message, user): # pylint: disable=R0201 |
826 logging.info('Would have committed for %s with message: %s' % ( | 834 logging.info('Would have committed for %s with message: %s' % ( |
827 user, message)) | 835 user, message)) |
828 return 'FAKE' | 836 return 'FAKE' |
829 | 837 |
830 def revisions(self, rev1, rev2): | 838 def revisions(self, rev1, rev2): |
831 return self.checkout.revisions(rev1, rev2) | 839 return self.checkout.revisions(rev1, rev2) |
832 | 840 |
833 @property | 841 @property |
834 def project_name(self): | 842 def project_name(self): |
835 return self.checkout.project_name | 843 return self.checkout.project_name |
836 | 844 |
837 @property | 845 @property |
838 def project_path(self): | 846 def project_path(self): |
839 return self.checkout.project_path | 847 return self.checkout.project_path |
OLD | NEW |