| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 def __init__(self, filename, status): | 52 def __init__(self, filename, status): |
| 53 super(PatchApplicationFailed, self).__init__(filename, status) | 53 super(PatchApplicationFailed, self).__init__(filename, status) |
| 54 self.filename = filename | 54 self.filename = filename |
| 55 self.status = status | 55 self.status = status |
| 56 | 56 |
| 57 | 57 |
| 58 class CheckoutBase(object): | 58 class CheckoutBase(object): |
| 59 # Set to None to have verbose output. | 59 # Set to None to have verbose output. |
| 60 VOID = subprocess2.VOID | 60 VOID = subprocess2.VOID |
| 61 | 61 |
| 62 def __init__(self, root_dir, project_name): | 62 def __init__(self, root_dir, project_name, post_processors): |
| 63 """ |
| 64 Args: |
| 65 post_processor: list of lambda(checkout, patches) to call on each of the |
| 66 modified files. |
| 67 """ |
| 63 self.root_dir = root_dir | 68 self.root_dir = root_dir |
| 64 self.project_name = project_name | 69 self.project_name = project_name |
| 65 if self.project_name is None: | 70 if self.project_name is None: |
| 66 self.project_path = self.root_dir | 71 self.project_path = self.root_dir |
| 67 else: | 72 else: |
| 68 self.project_path = os.path.join(self.root_dir, self.project_name) | 73 self.project_path = os.path.join(self.root_dir, self.project_name) |
| 69 # Only used for logging purposes. | 74 # Only used for logging purposes. |
| 70 self._last_seen_revision = None | 75 self._last_seen_revision = None |
| 76 self.post_processors = None |
| 71 assert self.root_dir | 77 assert self.root_dir |
| 72 assert self.project_path | 78 assert self.project_path |
| 73 | 79 |
| 74 def get_settings(self, key): | 80 def get_settings(self, key): |
| 75 return get_code_review_setting(self.project_path, key) | 81 return get_code_review_setting(self.project_path, key) |
| 76 | 82 |
| 77 def prepare(self): | 83 def prepare(self): |
| 78 """Checks out a clean copy of the tree and removes any local modification. | 84 """Checks out a clean copy of the tree and removes any local modification. |
| 79 | 85 |
| 80 This function shouldn't throw unless the remote repository is inaccessible, | 86 This function shouldn't throw unless the remote repository is inaccessible, |
| 81 there is no free disk space or hard issues like that. | 87 there is no free disk space or hard issues like that. |
| 82 """ | 88 """ |
| 83 raise NotImplementedError() | 89 raise NotImplementedError() |
| 84 | 90 |
| 85 def apply_patch(self, patches, post_processor=None): | 91 def apply_patch(self, patches): |
| 86 """Applies a patch and returns the list of modified files. | 92 """Applies a patch and returns the list of modified files. |
| 87 | 93 |
| 88 This function should throw patch.UnsupportedPatchFormat or | 94 This function should throw patch.UnsupportedPatchFormat or |
| 89 PatchApplicationFailed when relevant. | 95 PatchApplicationFailed when relevant. |
| 90 | 96 |
| 91 Args: | 97 Args: |
| 92 patches: patch.PatchSet object. | 98 patches: patch.PatchSet object. |
| 93 post_processor: list of lambda(checkout, patches) to call on each of the | |
| 94 modified files. | |
| 95 """ | 99 """ |
| 96 raise NotImplementedError() | 100 raise NotImplementedError() |
| 97 | 101 |
| 98 def commit(self, commit_message, user): | 102 def commit(self, commit_message, user): |
| 99 """Commits the patch upstream, while impersonating 'user'.""" | 103 """Commits the patch upstream, while impersonating 'user'.""" |
| 100 raise NotImplementedError() | 104 raise NotImplementedError() |
| 101 | 105 |
| 102 | 106 |
| 103 class RawCheckout(CheckoutBase): | 107 class RawCheckout(CheckoutBase): |
| 104 """Used to apply a patch locally without any intent to commit it. | 108 """Used to apply a patch locally without any intent to commit it. |
| 105 | 109 |
| 106 To be used by the try server. | 110 To be used by the try server. |
| 107 """ | 111 """ |
| 108 def prepare(self): | 112 def prepare(self): |
| 109 """Stubbed out.""" | 113 """Stubbed out.""" |
| 110 pass | 114 pass |
| 111 | 115 |
| 112 def apply_patch(self, patches, post_processor=None): | 116 def apply_patch(self, patches): |
| 113 """Ignores svn properties.""" | 117 """Ignores svn properties.""" |
| 114 post_processor = post_processor or [] | |
| 115 for p in patches: | 118 for p in patches: |
| 116 try: | 119 try: |
| 117 stdout = '' | 120 stdout = '' |
| 118 filename = os.path.join(self.project_path, p.filename) | 121 filename = os.path.join(self.project_path, p.filename) |
| 119 if p.is_delete: | 122 if p.is_delete: |
| 120 os.remove(filename) | 123 os.remove(filename) |
| 121 else: | 124 else: |
| 122 dirname = os.path.dirname(p.filename) | 125 dirname = os.path.dirname(p.filename) |
| 123 full_dir = os.path.join(self.project_path, dirname) | 126 full_dir = os.path.join(self.project_path, dirname) |
| 124 if dirname and not os.path.isdir(full_dir): | 127 if dirname and not os.path.isdir(full_dir): |
| 125 os.makedirs(full_dir) | 128 os.makedirs(full_dir) |
| 126 | 129 |
| 127 filepath = os.path.join(self.project_path, p.filename) | 130 filepath = os.path.join(self.project_path, p.filename) |
| 128 if p.is_binary: | 131 if p.is_binary: |
| 129 with open(filepath, 'wb') as f: | 132 with open(filepath, 'wb') as f: |
| 130 f.write(p.get()) | 133 f.write(p.get()) |
| 131 else: | 134 else: |
| 132 if p.diff_hunks: | 135 if p.diff_hunks: |
| 133 stdout = subprocess2.check_output( | 136 stdout = subprocess2.check_output( |
| 134 ['patch', '-p%s' % p.patchlevel], | 137 ['patch', '-p%s' % p.patchlevel], |
| 135 stdin=p.get(), | 138 stdin=p.get(), |
| 136 cwd=self.project_path) | 139 cwd=self.project_path) |
| 137 elif p.is_new and not os.path.exists(filepath): | 140 elif p.is_new and not os.path.exists(filepath): |
| 138 # There is only a header. Just create the file. | 141 # There is only a header. Just create the file. |
| 139 open(filepath, 'w').close() | 142 open(filepath, 'w').close() |
| 140 for post in post_processor: | 143 for post in (self.post_processors or []): |
| 141 post(self, p) | 144 post(self, p) |
| 142 except OSError, e: | 145 except OSError, e: |
| 143 raise PatchApplicationFailed(p.filename, '%s%s' % (stdout, e)) | 146 raise PatchApplicationFailed(p.filename, '%s%s' % (stdout, e)) |
| 144 except subprocess.CalledProcessError, e: | 147 except subprocess.CalledProcessError, e: |
| 145 raise PatchApplicationFailed( | 148 raise PatchApplicationFailed( |
| 146 p.filename, '%s%s' % (stdout, getattr(e, 'stdout', None))) | 149 p.filename, '%s%s' % (stdout, getattr(e, 'stdout', None))) |
| 147 | 150 |
| 148 def commit(self, commit_message, user): | 151 def commit(self, commit_message, user): |
| 149 """Stubbed out.""" | 152 """Stubbed out.""" |
| 150 raise NotImplementedError('RawCheckout can\'t commit') | 153 raise NotImplementedError('RawCheckout can\'t commit') |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 k, v = line.split(':', 1) | 229 k, v = line.split(':', 1) |
| 227 k = k.strip().lower() | 230 k = k.strip().lower() |
| 228 v = v.strip() | 231 v = v.strip() |
| 229 assert not k in values | 232 assert not k in values |
| 230 values[k] = v | 233 values[k] = v |
| 231 return values.get(key, None) | 234 return values.get(key, None) |
| 232 | 235 |
| 233 | 236 |
| 234 class SvnCheckout(CheckoutBase, SvnMixIn): | 237 class SvnCheckout(CheckoutBase, SvnMixIn): |
| 235 """Manages a subversion checkout.""" | 238 """Manages a subversion checkout.""" |
| 236 def __init__(self, root_dir, project_name, commit_user, commit_pwd, svn_url): | 239 def __init__(self, root_dir, project_name, commit_user, commit_pwd, svn_url, |
| 237 super(SvnCheckout, self).__init__(root_dir, project_name) | 240 post_processors=None): |
| 241 super(SvnCheckout, self).__init__(root_dir, project_name, post_processors) |
| 238 self.commit_user = commit_user | 242 self.commit_user = commit_user |
| 239 self.commit_pwd = commit_pwd | 243 self.commit_pwd = commit_pwd |
| 240 self.svn_url = svn_url | 244 self.svn_url = svn_url |
| 241 assert bool(self.commit_user) >= bool(self.commit_pwd) | 245 assert bool(self.commit_user) >= bool(self.commit_pwd) |
| 242 | 246 |
| 243 def prepare(self): | 247 def prepare(self): |
| 244 # Will checkout if the directory is not present. | 248 # Will checkout if the directory is not present. |
| 245 assert self.svn_url | 249 assert self.svn_url |
| 246 if not os.path.isdir(self.project_path): | 250 if not os.path.isdir(self.project_path): |
| 247 logging.info('Checking out %s in %s' % | 251 logging.info('Checking out %s in %s' % |
| 248 (self.project_name, self.project_path)) | 252 (self.project_name, self.project_path)) |
| 249 revision = self._revert() | 253 revision = self._revert() |
| 250 if revision != self._last_seen_revision: | 254 if revision != self._last_seen_revision: |
| 251 logging.info('Updated at revision %d' % revision) | 255 logging.info('Updated at revision %d' % revision) |
| 252 self._last_seen_revision = revision | 256 self._last_seen_revision = revision |
| 253 return revision | 257 return revision |
| 254 | 258 |
| 255 def apply_patch(self, patches, post_processor=None): | 259 def apply_patch(self, patches): |
| 256 post_processor = post_processor or [] | |
| 257 for p in patches: | 260 for p in patches: |
| 258 try: | 261 try: |
| 259 # It is important to use credentials=False otherwise credentials could | 262 # It is important to use credentials=False otherwise credentials could |
| 260 # leak in the error message. Credentials are not necessary here for the | 263 # leak in the error message. Credentials are not necessary here for the |
| 261 # following commands anyway. | 264 # following commands anyway. |
| 262 stdout = '' | 265 stdout = '' |
| 263 if p.is_delete: | 266 if p.is_delete: |
| 264 stdout += self._check_output_svn( | 267 stdout += self._check_output_svn( |
| 265 ['delete', p.filename, '--force'], credentials=False) | 268 ['delete', p.filename, '--force'], credentials=False) |
| 266 else: | 269 else: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 ['propset', prop[0], prop[1], p.filename], credentials=False) | 302 ['propset', prop[0], prop[1], p.filename], credentials=False) |
| 300 for prop, values in self.svn_config.auto_props.iteritems(): | 303 for prop, values in self.svn_config.auto_props.iteritems(): |
| 301 if fnmatch.fnmatch(p.filename, prop): | 304 if fnmatch.fnmatch(p.filename, prop): |
| 302 for value in values.split(';'): | 305 for value in values.split(';'): |
| 303 if '=' not in value: | 306 if '=' not in value: |
| 304 params = [value, '*'] | 307 params = [value, '*'] |
| 305 else: | 308 else: |
| 306 params = value.split('=', 1) | 309 params = value.split('=', 1) |
| 307 stdout += self._check_output_svn( | 310 stdout += self._check_output_svn( |
| 308 ['propset'] + params + [p.filename], credentials=False) | 311 ['propset'] + params + [p.filename], credentials=False) |
| 309 for post in post_processor: | 312 for post in (self.post_processors or []): |
| 310 post(self, p) | 313 post(self, p) |
| 311 except OSError, e: | 314 except OSError, e: |
| 312 raise PatchApplicationFailed(p.filename, '%s%s' % (stdout, e)) | 315 raise PatchApplicationFailed(p.filename, '%s%s' % (stdout, e)) |
| 313 except subprocess.CalledProcessError, e: | 316 except subprocess.CalledProcessError, e: |
| 314 raise PatchApplicationFailed( | 317 raise PatchApplicationFailed( |
| 315 p.filename, | 318 p.filename, |
| 316 'While running %s;\n%s%s' % ( | 319 'While running %s;\n%s%s' % ( |
| 317 ' '.join(e.cmd), stdout, getattr(e, 'stdout', ''))) | 320 ' '.join(e.cmd), stdout, getattr(e, 'stdout', ''))) |
| 318 | 321 |
| 319 def commit(self, commit_message, user): | 322 def commit(self, commit_message, user): |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 scm.SVN.Revert(self.project_path) | 365 scm.SVN.Revert(self.project_path) |
| 363 # Revive files that were deleted in scm.SVN.Revert(). | 366 # Revive files that were deleted in scm.SVN.Revert(). |
| 364 self._check_call_svn(['update', '--force'] + flags) | 367 self._check_call_svn(['update', '--force'] + flags) |
| 365 | 368 |
| 366 out = self._check_output_svn(['info', '.']) | 369 out = self._check_output_svn(['info', '.']) |
| 367 return int(self._parse_svn_info(out, 'revision')) | 370 return int(self._parse_svn_info(out, 'revision')) |
| 368 | 371 |
| 369 | 372 |
| 370 class GitCheckoutBase(CheckoutBase): | 373 class GitCheckoutBase(CheckoutBase): |
| 371 """Base class for git checkout. Not to be used as-is.""" | 374 """Base class for git checkout. Not to be used as-is.""" |
| 372 def __init__(self, root_dir, project_name, remote_branch): | 375 def __init__(self, root_dir, project_name, remote_branch, |
| 373 super(GitCheckoutBase, self).__init__(root_dir, project_name) | 376 post_processors=None): |
| 377 super(GitCheckoutBase, self).__init__( |
| 378 root_dir, project_name, post_processors) |
| 374 # There is no reason to not hardcode it. | 379 # There is no reason to not hardcode it. |
| 375 self.remote = 'origin' | 380 self.remote = 'origin' |
| 376 self.remote_branch = remote_branch | 381 self.remote_branch = remote_branch |
| 377 self.working_branch = 'working_branch' | 382 self.working_branch = 'working_branch' |
| 378 | 383 |
| 379 def prepare(self): | 384 def prepare(self): |
| 380 """Resets the git repository in a clean state. | 385 """Resets the git repository in a clean state. |
| 381 | 386 |
| 382 Checks it out if not present and deletes the working branch. | 387 Checks it out if not present and deletes the working branch. |
| 383 """ | 388 """ |
| 384 assert self.remote_branch | 389 assert self.remote_branch |
| 385 assert os.path.isdir(self.project_path) | 390 assert os.path.isdir(self.project_path) |
| 386 self._check_call_git(['reset', '--hard', '--quiet']) | 391 self._check_call_git(['reset', '--hard', '--quiet']) |
| 387 branches, active = self._branches() | 392 branches, active = self._branches() |
| 388 if active != 'master': | 393 if active != 'master': |
| 389 self._check_call_git(['checkout', 'master', '--force', '--quiet']) | 394 self._check_call_git(['checkout', 'master', '--force', '--quiet']) |
| 390 self._check_call_git(['pull', self.remote, self.remote_branch, '--quiet']) | 395 self._check_call_git(['pull', self.remote, self.remote_branch, '--quiet']) |
| 391 if self.working_branch in branches: | 396 if self.working_branch in branches: |
| 392 self._call_git(['branch', '-D', self.working_branch]) | 397 self._call_git(['branch', '-D', self.working_branch]) |
| 393 | 398 |
| 394 def apply_patch(self, patches, post_processor=None): | 399 def apply_patch(self, patches): |
| 395 """Applies a patch on 'working_branch' and switch to it. | 400 """Applies a patch on 'working_branch' and switch to it. |
| 396 | 401 |
| 397 Also commits the changes on the local branch. | 402 Also commits the changes on the local branch. |
| 398 | 403 |
| 399 Ignores svn properties and raise an exception on unexpected ones. | 404 Ignores svn properties and raise an exception on unexpected ones. |
| 400 """ | 405 """ |
| 401 post_processor = post_processor or [] | |
| 402 # It this throws, the checkout is corrupted. Maybe worth deleting it and | 406 # It this throws, the checkout is corrupted. Maybe worth deleting it and |
| 403 # trying again? | 407 # trying again? |
| 404 if self.remote_branch: | 408 if self.remote_branch: |
| 405 self._check_call_git( | 409 self._check_call_git( |
| 406 ['checkout', '-b', self.working_branch, | 410 ['checkout', '-b', self.working_branch, |
| 407 '%s/%s' % (self.remote, self.remote_branch), '--quiet']) | 411 '%s/%s' % (self.remote, self.remote_branch), '--quiet']) |
| 408 for p in patches: | 412 for p in patches: |
| 409 try: | 413 try: |
| 410 stdout = '' | 414 stdout = '' |
| 411 if p.is_delete: | 415 if p.is_delete: |
| (...skipping 16 matching lines...) Expand all Loading... |
| 428 # Ignore some known auto-props flags through .subversion/config, | 432 # Ignore some known auto-props flags through .subversion/config, |
| 429 # bails out on the other ones. | 433 # bails out on the other ones. |
| 430 # TODO(maruel): Read ~/.subversion/config and detect the rules that | 434 # TODO(maruel): Read ~/.subversion/config and detect the rules that |
| 431 # applies here to figure out if the property will be correctly | 435 # applies here to figure out if the property will be correctly |
| 432 # handled. | 436 # handled. |
| 433 if not prop[0] in ('svn:eol-style', 'svn:executable'): | 437 if not prop[0] in ('svn:eol-style', 'svn:executable'): |
| 434 raise patch.UnsupportedPatchFormat( | 438 raise patch.UnsupportedPatchFormat( |
| 435 p.filename, | 439 p.filename, |
| 436 'Cannot apply svn property %s to file %s.' % ( | 440 'Cannot apply svn property %s to file %s.' % ( |
| 437 prop[0], p.filename)) | 441 prop[0], p.filename)) |
| 438 for post in post_processor: | 442 for post in (self.post_processors or []): |
| 439 post(self, p) | 443 post(self, p) |
| 440 except OSError, e: | 444 except OSError, e: |
| 441 raise PatchApplicationFailed(p.filename, '%s%s' % (stdout, e)) | 445 raise PatchApplicationFailed(p.filename, '%s%s' % (stdout, e)) |
| 442 except subprocess.CalledProcessError, e: | 446 except subprocess.CalledProcessError, e: |
| 443 raise PatchApplicationFailed( | 447 raise PatchApplicationFailed( |
| 444 p.filename, '%s%s' % (stdout, getattr(e, 'stdout', None))) | 448 p.filename, '%s%s' % (stdout, getattr(e, 'stdout', None))) |
| 445 # Once all the patches are processed and added to the index, commit the | 449 # Once all the patches are processed and added to the index, commit the |
| 446 # index. | 450 # index. |
| 447 self._check_call_git(['commit', '-m', 'Committed patch']) | 451 self._check_call_git(['commit', '-m', 'Committed patch']) |
| 448 # TODO(maruel): Weirdly enough they don't match, need to investigate. | 452 # TODO(maruel): Weirdly enough they don't match, need to investigate. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 active = l[2:] | 489 active = l[2:] |
| 486 break | 490 break |
| 487 return branches, active | 491 return branches, active |
| 488 | 492 |
| 489 | 493 |
| 490 class GitSvnCheckoutBase(GitCheckoutBase, SvnMixIn): | 494 class GitSvnCheckoutBase(GitCheckoutBase, SvnMixIn): |
| 491 """Base class for git-svn checkout. Not to be used as-is.""" | 495 """Base class for git-svn checkout. Not to be used as-is.""" |
| 492 def __init__(self, | 496 def __init__(self, |
| 493 root_dir, project_name, remote_branch, | 497 root_dir, project_name, remote_branch, |
| 494 commit_user, commit_pwd, | 498 commit_user, commit_pwd, |
| 495 svn_url, trunk): | 499 svn_url, trunk, post_processors=None): |
| 496 """trunk is optional.""" | 500 """trunk is optional.""" |
| 497 super(GitSvnCheckoutBase, self).__init__( | 501 super(GitSvnCheckoutBase, self).__init__( |
| 498 root_dir, project_name + '.git', remote_branch) | 502 root_dir, project_name + '.git', remote_branch, post_processors) |
| 499 self.commit_user = commit_user | 503 self.commit_user = commit_user |
| 500 self.commit_pwd = commit_pwd | 504 self.commit_pwd = commit_pwd |
| 501 # svn_url in this case is the root of the svn repository. | 505 # svn_url in this case is the root of the svn repository. |
| 502 self.svn_url = svn_url | 506 self.svn_url = svn_url |
| 503 self.trunk = trunk | 507 self.trunk = trunk |
| 504 assert bool(self.commit_user) >= bool(self.commit_pwd) | 508 assert bool(self.commit_user) >= bool(self.commit_pwd) |
| 505 assert self.svn_url | 509 assert self.svn_url |
| 506 assert self.trunk | 510 assert self.trunk |
| 507 self._cache_svn_auth() | 511 self._cache_svn_auth() |
| 508 | 512 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 | 580 |
| 577 class GitSvnPremadeCheckout(GitSvnCheckoutBase): | 581 class GitSvnPremadeCheckout(GitSvnCheckoutBase): |
| 578 """Manages a git-svn clone made out from an initial git-svn seed. | 582 """Manages a git-svn clone made out from an initial git-svn seed. |
| 579 | 583 |
| 580 This class is very similar to GitSvnCheckout but is faster to bootstrap | 584 This class is very similar to GitSvnCheckout but is faster to bootstrap |
| 581 because it starts right off with an existing git-svn clone. | 585 because it starts right off with an existing git-svn clone. |
| 582 """ | 586 """ |
| 583 def __init__(self, | 587 def __init__(self, |
| 584 root_dir, project_name, remote_branch, | 588 root_dir, project_name, remote_branch, |
| 585 commit_user, commit_pwd, | 589 commit_user, commit_pwd, |
| 586 svn_url, trunk, git_url): | 590 svn_url, trunk, git_url, post_processors=None): |
| 587 super(GitSvnPremadeCheckout, self).__init__( | 591 super(GitSvnPremadeCheckout, self).__init__( |
| 588 root_dir, project_name, remote_branch, | 592 root_dir, project_name, remote_branch, |
| 589 commit_user, commit_pwd, | 593 commit_user, commit_pwd, |
| 590 svn_url, trunk) | 594 svn_url, trunk, post_processors) |
| 591 self.git_url = git_url | 595 self.git_url = git_url |
| 592 assert self.git_url | 596 assert self.git_url |
| 593 | 597 |
| 594 def prepare(self): | 598 def prepare(self): |
| 595 """Creates the initial checkout for the repo.""" | 599 """Creates the initial checkout for the repo.""" |
| 596 if not os.path.isdir(self.project_path): | 600 if not os.path.isdir(self.project_path): |
| 597 logging.info('Checking out %s in %s' % | 601 logging.info('Checking out %s in %s' % |
| 598 (self.project_name, self.project_path)) | 602 (self.project_name, self.project_path)) |
| 599 assert self.remote == 'origin' | 603 assert self.remote == 'origin' |
| 600 # self.project_path doesn't exist yet. | 604 # self.project_path doesn't exist yet. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 620 | 624 |
| 621 | 625 |
| 622 class GitSvnCheckout(GitSvnCheckoutBase): | 626 class GitSvnCheckout(GitSvnCheckoutBase): |
| 623 """Manages a git-svn clone. | 627 """Manages a git-svn clone. |
| 624 | 628 |
| 625 Using git-svn hides some of the complexity of using a svn checkout. | 629 Using git-svn hides some of the complexity of using a svn checkout. |
| 626 """ | 630 """ |
| 627 def __init__(self, | 631 def __init__(self, |
| 628 root_dir, project_name, | 632 root_dir, project_name, |
| 629 commit_user, commit_pwd, | 633 commit_user, commit_pwd, |
| 630 svn_url, trunk): | 634 svn_url, trunk, post_processors=None): |
| 631 super(GitSvnCheckout, self).__init__( | 635 super(GitSvnCheckout, self).__init__( |
| 632 root_dir, project_name, 'trunk', | 636 root_dir, project_name, 'trunk', |
| 633 commit_user, commit_pwd, | 637 commit_user, commit_pwd, |
| 634 svn_url, trunk) | 638 svn_url, trunk, post_processors) |
| 635 | 639 |
| 636 def prepare(self): | 640 def prepare(self): |
| 637 """Creates the initial checkout for the repo.""" | 641 """Creates the initial checkout for the repo.""" |
| 638 if not os.path.isdir(self.project_path): | 642 if not os.path.isdir(self.project_path): |
| 639 logging.info('Checking out %s in %s' % | 643 logging.info('Checking out %s in %s' % |
| 640 (self.project_name, self.project_path)) | 644 (self.project_name, self.project_path)) |
| 641 # TODO: Create a shallow clone. | 645 # TODO: Create a shallow clone. |
| 642 # self.project_path doesn't exist yet. | 646 # self.project_path doesn't exist yet. |
| 643 self._check_call_git_svn( | 647 self._check_call_git_svn( |
| 644 ['clone', | 648 ['clone', |
| (...skipping 11 matching lines...) Expand all Loading... |
| 656 """Converts a checkout into a read-only one.""" | 660 """Converts a checkout into a read-only one.""" |
| 657 def __init__(self, checkout): | 661 def __init__(self, checkout): |
| 658 self.checkout = checkout | 662 self.checkout = checkout |
| 659 | 663 |
| 660 def prepare(self): | 664 def prepare(self): |
| 661 return self.checkout.prepare() | 665 return self.checkout.prepare() |
| 662 | 666 |
| 663 def get_settings(self, key): | 667 def get_settings(self, key): |
| 664 return self.checkout.get_settings(key) | 668 return self.checkout.get_settings(key) |
| 665 | 669 |
| 666 def apply_patch(self, patches, post_processor=None): | 670 def apply_patch(self, patches): |
| 667 return self.checkout.apply_patch(patches, post_processor) | 671 return self.checkout.apply_patch(patches) |
| 668 | 672 |
| 669 def commit(self, message, user): # pylint: disable=R0201 | 673 def commit(self, message, user): # pylint: disable=R0201 |
| 670 logging.info('Would have committed for %s with message: %s' % ( | 674 logging.info('Would have committed for %s with message: %s' % ( |
| 671 user, message)) | 675 user, message)) |
| 672 return 'FAKE' | 676 return 'FAKE' |
| 673 | 677 |
| 674 @property | 678 @property |
| 675 def project_name(self): | 679 def project_name(self): |
| 676 return self.checkout.project_name | 680 return self.checkout.project_name |
| 677 | 681 |
| 678 @property | 682 @property |
| 679 def project_path(self): | 683 def project_path(self): |
| 680 return self.checkout.project_path | 684 return self.checkout.project_path |
| OLD | NEW |