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

Side by Side Diff: checkout.py

Issue 10821011: Add .revisions() implementation to *Checkout classes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: trap some exceptions Created 8 years, 4 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 | no next file » | 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) 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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 113
114 Args: 114 Args:
115 patches: patch.PatchSet object. 115 patches: patch.PatchSet object.
116 """ 116 """
117 raise NotImplementedError() 117 raise NotImplementedError()
118 118
119 def commit(self, commit_message, user): 119 def commit(self, commit_message, user):
120 """Commits the patch upstream, while impersonating 'user'.""" 120 """Commits the patch upstream, while impersonating 'user'."""
121 raise NotImplementedError() 121 raise NotImplementedError()
122 122
123 def revisions(self, rev1, rev2):
124 """Returns the count of revisions from rev1 to rev2, e.g. len(]rev1, rev2]).
125
126 If rev2 is None, it means 'HEAD'.
127
128 Returns None if there is no link between the two.
129 """
130 raise NotImplementedError()
131
123 132
124 class RawCheckout(CheckoutBase): 133 class RawCheckout(CheckoutBase):
125 """Used to apply a patch locally without any intent to commit it. 134 """Used to apply a patch locally without any intent to commit it.
126 135
127 To be used by the try server. 136 To be used by the try server.
128 """ 137 """
129 def prepare(self, revision): 138 def prepare(self, revision):
130 """Stubbed out.""" 139 """Stubbed out."""
131 pass 140 pass
132 141
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 except OSError, e: 184 except OSError, e:
176 raise PatchApplicationFailed(p, '%s%s' % (stdout, e)) 185 raise PatchApplicationFailed(p, '%s%s' % (stdout, e))
177 except subprocess.CalledProcessError, e: 186 except subprocess.CalledProcessError, e:
178 raise PatchApplicationFailed( 187 raise PatchApplicationFailed(
179 p, '%s%s' % (stdout, getattr(e, 'stdout', None))) 188 p, '%s%s' % (stdout, getattr(e, 'stdout', None)))
180 189
181 def commit(self, commit_message, user): 190 def commit(self, commit_message, user):
182 """Stubbed out.""" 191 """Stubbed out."""
183 raise NotImplementedError('RawCheckout can\'t commit') 192 raise NotImplementedError('RawCheckout can\'t commit')
184 193
194 def revisions(self, _rev1, _rev2):
195 return None
196
185 197
186 class SvnConfig(object): 198 class SvnConfig(object):
187 """Parses a svn configuration file.""" 199 """Parses a svn configuration file."""
188 def __init__(self, svn_config_dir=None): 200 def __init__(self, svn_config_dir=None):
189 super(SvnConfig, self).__init__() 201 super(SvnConfig, self).__init__()
190 self.svn_config_dir = svn_config_dir 202 self.svn_config_dir = svn_config_dir
191 self.default = not bool(self.svn_config_dir) 203 self.default = not bool(self.svn_config_dir)
192 if not self.svn_config_dir: 204 if not self.svn_config_dir:
193 if sys.platform == 'win32': 205 if sys.platform == 'win32':
194 self.svn_config_dir = os.path.join(os.environ['APPDATA'], 'Subversion') 206 self.svn_config_dir = os.path.join(os.environ['APPDATA'], 'Subversion')
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 return self._get_revision() 430 return self._get_revision()
419 431
420 def _get_revision(self): 432 def _get_revision(self):
421 out = self._check_output_svn(['info', '.']) 433 out = self._check_output_svn(['info', '.'])
422 revision = int(self._parse_svn_info(out, 'revision')) 434 revision = int(self._parse_svn_info(out, 'revision'))
423 if revision != self._last_seen_revision: 435 if revision != self._last_seen_revision:
424 logging.info('Updated to revision %d' % revision) 436 logging.info('Updated to revision %d' % revision)
425 self._last_seen_revision = revision 437 self._last_seen_revision = revision
426 return revision 438 return revision
427 439
440 def revisions(self, rev1, rev2):
441 """Returns the number of actual commits, not just the difference between
442 numbers.
443 """
444 rev2 = rev2 or 'HEAD'
445 # Revision range is inclusive and ordering doesn't matter, they'll appear in
446 # the order specified.
447 try:
448 out = self._check_output_svn(
449 ['log', '-q', self.svn_url, '-r', '%s:%s' % (rev1, rev2)])
450 except subprocess.CalledProcessError:
451 return None
452 # Ignore the '----' lines.
453 return len([l for l in out.splitlines() if l.startswith('r')]) - 1
454
428 455
429 class GitCheckoutBase(CheckoutBase): 456 class GitCheckoutBase(CheckoutBase):
430 """Base class for git checkout. Not to be used as-is.""" 457 """Base class for git checkout. Not to be used as-is."""
431 def __init__(self, root_dir, project_name, remote_branch, 458 def __init__(self, root_dir, project_name, remote_branch,
432 post_processors=None): 459 post_processors=None):
433 super(GitCheckoutBase, self).__init__( 460 super(GitCheckoutBase, self).__init__(
434 root_dir, project_name, post_processors) 461 root_dir, project_name, post_processors)
435 # There is no reason to not hardcode it. 462 # There is no reason to not hardcode it.
436 self.remote = 'origin' 463 self.remote = 'origin'
437 self.remote_branch = remote_branch 464 self.remote_branch = remote_branch
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 """Returns the list of branches and the active one.""" 585 """Returns the list of branches and the active one."""
559 out = self._check_output_git(['branch']).splitlines(False) 586 out = self._check_output_git(['branch']).splitlines(False)
560 branches = [l[2:] for l in out] 587 branches = [l[2:] for l in out]
561 active = None 588 active = None
562 for l in out: 589 for l in out:
563 if l.startswith('*'): 590 if l.startswith('*'):
564 active = l[2:] 591 active = l[2:]
565 break 592 break
566 return branches, active 593 return branches, active
567 594
595 def revisions(self, rev1, rev2):
596 """Returns the number of actual commits between both hash."""
597 self._fetch_remote()
598
599 rev2 = rev2 or '%s/%s' % (self.remote, self.remote_branch)
600 # Revision range is ]rev1, rev2] and ordering matters.
601 try:
602 out = self._check_output_git(
603 ['log', '--format="%H"' , '%s..%s' % (rev1, rev2)])
604 except subprocess.CalledProcessError:
605 return None
606 return len(out.splitlines())
607
608 def _fetch_remote(self):
609 """Fetches the remote without rebasing."""
610 raise NotImplementedError()
611
612
613 class GitCheckout(GitCheckoutBase):
614 """Git checkout implementation."""
615 def _fetch_remote(self):
616 # git fetch is always verbose even with -q -q so redirect its output.
617 self._check_output_git(['fetch', self.remote, self.remote_branch])
618
568 619
569 class ReadOnlyCheckout(object): 620 class ReadOnlyCheckout(object):
570 """Converts a checkout into a read-only one.""" 621 """Converts a checkout into a read-only one."""
571 def __init__(self, checkout, post_processors=None): 622 def __init__(self, checkout, post_processors=None):
572 super(ReadOnlyCheckout, self).__init__() 623 super(ReadOnlyCheckout, self).__init__()
573 self.checkout = checkout 624 self.checkout = checkout
574 self.post_processors = (post_processors or []) + ( 625 self.post_processors = (post_processors or []) + (
575 self.checkout.post_processors or []) 626 self.checkout.post_processors or [])
576 627
577 def prepare(self, revision): 628 def prepare(self, revision):
578 return self.checkout.prepare(revision) 629 return self.checkout.prepare(revision)
579 630
580 def get_settings(self, key): 631 def get_settings(self, key):
581 return self.checkout.get_settings(key) 632 return self.checkout.get_settings(key)
582 633
583 def apply_patch(self, patches, post_processors=None): 634 def apply_patch(self, patches, post_processors=None):
584 return self.checkout.apply_patch( 635 return self.checkout.apply_patch(
585 patches, post_processors or self.post_processors) 636 patches, post_processors or self.post_processors)
586 637
587 def commit(self, message, user): # pylint: disable=R0201 638 def commit(self, message, user): # pylint: disable=R0201
588 logging.info('Would have committed for %s with message: %s' % ( 639 logging.info('Would have committed for %s with message: %s' % (
589 user, message)) 640 user, message))
590 return 'FAKE' 641 return 'FAKE'
591 642
643 def revisions(self, rev1, rev2):
644 return self.checkout.revisions(rev1, rev2)
645
592 @property 646 @property
593 def project_name(self): 647 def project_name(self):
594 return self.checkout.project_name 648 return self.checkout.project_name
595 649
596 @property 650 @property
597 def project_path(self): 651 def project_path(self):
598 return self.checkout.project_path 652 return self.checkout.project_path
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698