Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: checkout.py

Issue 7044090: Make post_processors part of the Checkout object state. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/checkout_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | tests/checkout_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698