summaryrefslogtreecommitdiffstats
path: root/WebKitTools/Scripts/webkitpy/common/checkout
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2010-11-04 12:00:17 -0700
committerJohn Reck <jreck@google.com>2010-11-09 11:35:04 -0800
commite14391e94c850b8bd03680c23b38978db68687a8 (patch)
tree3fed87e6620fecaf3edc7259ae58a11662bedcb2 /WebKitTools/Scripts/webkitpy/common/checkout
parent1bd705833a68f07850cf7e204b26f8d328d16951 (diff)
downloadexternal_webkit-e14391e94c850b8bd03680c23b38978db68687a8.zip
external_webkit-e14391e94c850b8bd03680c23b38978db68687a8.tar.gz
external_webkit-e14391e94c850b8bd03680c23b38978db68687a8.tar.bz2
Merge Webkit at r70949: Initial merge by git.
Change-Id: I77b8645c083b5d0da8dba73ed01d4014aab9848e
Diffstat (limited to 'WebKitTools/Scripts/webkitpy/common/checkout')
-rw-r--r--WebKitTools/Scripts/webkitpy/common/checkout/__init__.py2
-rw-r--r--WebKitTools/Scripts/webkitpy/common/checkout/api.py14
-rw-r--r--WebKitTools/Scripts/webkitpy/common/checkout/api_unittest.py4
-rw-r--r--WebKitTools/Scripts/webkitpy/common/checkout/scm.py47
-rw-r--r--WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py9
5 files changed, 52 insertions, 24 deletions
diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/__init__.py b/WebKitTools/Scripts/webkitpy/common/checkout/__init__.py
index ef65bee..597dcbd 100644
--- a/WebKitTools/Scripts/webkitpy/common/checkout/__init__.py
+++ b/WebKitTools/Scripts/webkitpy/common/checkout/__init__.py
@@ -1 +1,3 @@
# Required for Python to search this directory for module files
+
+from api import Checkout
diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/api.py b/WebKitTools/Scripts/webkitpy/common/checkout/api.py
index 72cad8d..dbe1e84 100644
--- a/WebKitTools/Scripts/webkitpy/common/checkout/api.py
+++ b/WebKitTools/Scripts/webkitpy/common/checkout/api.py
@@ -32,6 +32,7 @@ import StringIO
from webkitpy.common.checkout.changelog import ChangeLog
from webkitpy.common.checkout.commitinfo import CommitInfo
from webkitpy.common.checkout.scm import CommitMessage
+from webkitpy.common.memoized import memoized
from webkitpy.common.net.bugzilla import parse_bug_id
from webkitpy.common.system.executive import Executive, run_command, ScriptError
from webkitpy.common.system.deprecated_logging import log
@@ -59,6 +60,7 @@ class Checkout(object):
changed_files = self._scm.changed_files_for_revision(revision)
return [self._latest_entry_for_changelog_at_revision(path, revision) for path in changed_files if self._is_path_to_changelog(path)]
+ @memoized
def commit_info_for_revision(self, revision):
committer_email = self._scm.committer_email_for_revision(revision)
changelog_entries = self.changelog_entries_for_revision(revision)
@@ -98,8 +100,8 @@ class Checkout(object):
def modified_non_changelogs(self, git_commit, changed_files=None):
return self._modified_files_matching_predicate(git_commit, lambda path: not self._is_path_to_changelog(path), changed_files=changed_files)
- def commit_message_for_this_commit(self, git_commit):
- changelog_paths = self.modified_changelogs(git_commit)
+ def commit_message_for_this_commit(self, git_commit, changed_files=None):
+ changelog_paths = self.modified_changelogs(git_commit, changed_files)
if not len(changelog_paths):
raise ScriptError(message="Found no modified ChangeLogs, cannot create a commit message.\n"
"All changes require a ChangeLog. See:\n"
@@ -120,16 +122,16 @@ class Checkout(object):
revisions = set(sum(map(self._scm.revisions_changing_file, paths), []))
return set(map(self.commit_info_for_revision, revisions))
- def suggested_reviewers(self, git_commit):
- changed_files = self.modified_non_changelogs(git_commit)
+ def suggested_reviewers(self, git_commit, changed_files=None):
+ changed_files = self.modified_non_changelogs(git_commit, changed_files)
commit_infos = self.recent_commit_infos_for_files(changed_files)
reviewers = [commit_info.reviewer() for commit_info in commit_infos if commit_info.reviewer()]
reviewers.extend([commit_info.author() for commit_info in commit_infos if commit_info.author() and commit_info.author().can_review])
return sorted(set(reviewers))
- def bug_id_for_this_commit(self, git_commit):
+ def bug_id_for_this_commit(self, git_commit, changed_files=None):
try:
- return parse_bug_id(self.commit_message_for_this_commit(git_commit).message())
+ return parse_bug_id(self.commit_message_for_this_commit(git_commit, changed_files).message())
except ScriptError, e:
pass # We might not have ChangeLogs.
diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/api_unittest.py b/WebKitTools/Scripts/webkitpy/common/checkout/api_unittest.py
index d7bd95e..1f97abd 100644
--- a/WebKitTools/Scripts/webkitpy/common/checkout/api_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/common/checkout/api_unittest.py
@@ -114,7 +114,7 @@ class CommitMessageForThisCommitTest(unittest.TestCase):
# ChangeLog is difficult to mock at current.
def test_commit_message_for_this_commit(self):
checkout = Checkout(None)
- checkout.modified_changelogs = lambda git_commit: ["ChangeLog1", "ChangeLog2"]
+ checkout.modified_changelogs = lambda git_commit, changed_files=None: ["ChangeLog1", "ChangeLog2"]
output = OutputCapture()
expected_stderr = "Parsing ChangeLog: ChangeLog1\nParsing ChangeLog: ChangeLog2\n"
commit_message = output.assert_outputs(self, checkout.commit_message_for_this_commit,
@@ -163,7 +163,7 @@ class CheckoutTest(unittest.TestCase):
def test_bug_id_for_this_commit(self):
scm = Mock()
checkout = Checkout(scm)
- checkout.commit_message_for_this_commit = lambda git_commit: CommitMessage(ChangeLogEntry(_changelog1entry1).contents().splitlines())
+ checkout.commit_message_for_this_commit = lambda git_commit, changed_files=None: CommitMessage(ChangeLogEntry(_changelog1entry1).contents().splitlines())
self.assertEqual(checkout.bug_id_for_this_commit(git_commit=None), 36629)
def test_modified_changelogs(self):
diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py
index 4bd9ed6..9b602c3 100644
--- a/WebKitTools/Scripts/webkitpy/common/checkout/scm.py
+++ b/WebKitTools/Scripts/webkitpy/common/checkout/scm.py
@@ -36,6 +36,7 @@ import shutil
from webkitpy.common.system.executive import Executive, run_command, ScriptError
from webkitpy.common.system.deprecated_logging import error, log
+from webkitpy.common.memoized import memoized
def find_checkout_root():
@@ -319,7 +320,6 @@ class SVN(SCM):
def __init__(self, cwd):
SCM.__init__(self, cwd)
- self.cached_version = None
self._bogus_dir = None
@staticmethod
@@ -369,16 +369,20 @@ class SVN(SCM):
find_output = self.run(find_args, cwd=home_directory, error_handler=Executive.ignore_error).rstrip()
return find_output and os.path.isfile(os.path.join(home_directory, find_output))
+ @memoized
def svn_version(self):
- if not self.cached_version:
- self.cached_version = self.run(['svn', '--version', '--quiet'])
-
- return self.cached_version
+ return self.run(['svn', '--version', '--quiet'])
def working_directory_is_clean(self):
return self.run(["svn", "diff"], cwd=self.checkout_root, decode_output=False) == ""
def clean_working_directory(self):
+ # Make sure there are no locks lying around from a previously aborted svn invocation.
+ # This is slightly dangerous, as it's possible the user is running another svn process
+ # on this checkout at the same time. However, it's much more likely that we're running
+ # under windows and svn just sucks (or the user interrupted svn and it failed to clean up).
+ self.run(["svn", "cleanup"], cwd=self.checkout_root)
+
# svn revert -R is not as awesome as git reset --hard.
# It will leave added files around, causing later svn update
# calls to fail on the bots. We make this mirror git reset --hard
@@ -432,6 +436,7 @@ class SVN(SCM):
def revisions_changing_file(self, path, limit=5):
revisions = []
+ # svn log will exit(1) (and thus self.run will raise) if the path does not exist.
log_command = ['svn', 'log', '--quiet', '--limit=%s' % limit, path]
for line in self.run(log_command, cwd=self.checkout_root).splitlines():
match = re.search('^r(?P<revision>\d+) ', line)
@@ -565,6 +570,7 @@ class SVN(SCM):
dir, base = os.path.split(path)
return self.run(['svn', 'pget', pname, base], cwd=dir).encode('utf-8').rstrip("\n")
+
# All git-specific logic should go here.
class Git(SCM):
def __init__(self, cwd):
@@ -667,7 +673,8 @@ class Git(SCM):
return self._changes_files_for_commit(commit_id)
def revisions_changing_file(self, path, limit=5):
- commit_ids = self.run(["git", "log", "--pretty=format:%H", "-%s" % limit, path]).splitlines()
+ # git rev-list head --remove-empty --limit=5 -- path would be equivalent.
+ commit_ids = self.run(["git", "log", "--remove-empty", "--pretty=format:%H", "-%s" % limit, "--", path]).splitlines()
return filter(lambda revision: revision, map(self.svn_revision_from_git_commit, commit_ids))
def conflicted_files(self):
@@ -696,21 +703,29 @@ class Git(SCM):
# FIXME: This should probably use cwd=self.checkout_root
return self.run(['git', 'diff', '--binary', "--no-ext-diff", "--full-index", "-M", self.merge_base(git_commit), "--"] + changed_files, decode_output=False)
- @classmethod
- def git_commit_from_svn_revision(cls, revision):
- # FIXME: This should probably use cwd=self.checkout_root
- git_commit = run_command(['git', 'svn', 'find-rev', 'r%s' % revision]).rstrip()
- # git svn find-rev always exits 0, even when the revision is not found.
- if not git_commit:
- raise ScriptError(message='Failed to find git commit for revision %s, your checkout likely needs an update.' % revision)
- return git_commit
+ def _run_git_svn_find_rev(self, arg):
+ # git svn find-rev always exits 0, even when the revision or commit is not found.
+ return self.run(['git', 'svn', 'find-rev', arg], cwd=self.checkout_root).rstrip()
- def svn_revision_from_git_commit(self, commit_id):
+ def _string_to_int_or_none(self, string):
try:
- return int(self.run(['git', 'svn', 'find-rev', commit_id]).rstrip())
+ return int(string)
except ValueError, e:
return None
+ @memoized
+ def git_commit_from_svn_revision(self, svn_revision):
+ git_commit = self._run_git_svn_find_rev('r%s' % svn_revision)
+ if not git_commit:
+ # FIXME: Alternatively we could offer to update the checkout? Or return None?
+ raise ScriptError(message='Failed to find git commit for revision %s, your checkout likely needs an update.' % svn_revision)
+ return git_commit
+
+ @memoized
+ def svn_revision_from_git_commit(self, git_commit):
+ svn_revision = self._run_git_svn_find_rev(git_commit)
+ return self._string_to_int_or_none(svn_revision)
+
def contents_at_revision(self, path, revision):
"""Returns a byte array (str()) containing the contents
of path @ revision in the repository."""
diff --git a/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py b/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py
index 4aa5279..8af9ad5 100644
--- a/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/common/checkout/scm_unittest.py
@@ -760,6 +760,15 @@ Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
self.do_test_diff_for_file()
self.assertFalse(os.path.exists(self.bogus_dir))
+ def test_svn_lock(self):
+ svn_root_lock_path = ".svn/lock"
+ write_into_file_at_path(svn_root_lock_path, "", "utf-8")
+ # webkit-patch uses a Checkout object and runs update-webkit, just use svn update here.
+ self.assertRaises(ScriptError, run_command, ['svn', 'update'])
+ self.scm.clean_working_directory()
+ self.assertFalse(os.path.exists(svn_root_lock_path))
+ run_command(['svn', 'update']) # Should succeed and not raise.
+
class GitTest(SCMTest):