diff options
author | John Reck <jreck@google.com> | 2010-11-04 12:00:17 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2010-11-09 11:35:04 -0800 |
commit | e14391e94c850b8bd03680c23b38978db68687a8 (patch) | |
tree | 3fed87e6620fecaf3edc7259ae58a11662bedcb2 /WebKitTools/Scripts/webkitpy/common/checkout | |
parent | 1bd705833a68f07850cf7e204b26f8d328d16951 (diff) | |
download | external_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')
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): |