summaryrefslogtreecommitdiff
path: root/Tools/Scripts/webkitpy/tool/steps
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/Scripts/webkitpy/tool/steps')
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/__init__.py5
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/addsvnmimetypeforpng_unittest.py2
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/applywatchlist_unittest.py2
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/build.py2
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/checkstyle.py2
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectory.py12
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectory_unittest.py30
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectorywithlocalcommits.py34
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/closebugforlanddiff_unittest.py2
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/commit.py16
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/commit_unittest.py2
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/discardlocalchanges.py (renamed from Tools/Scripts/webkitpy/tool/steps/preparechangelogfordepsroll.py)28
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/discardlocalchanges_unittest.py97
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/haslanded.py120
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/haslanded_unittest.py299
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/options.py2
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/preparechangelog.py60
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/preparechangelog_unittest.py94
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/preparechangelogforrevert.py2
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/preparechangelogforrevert_unittest.py24
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/runtests.py48
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/runtests_unittest.py23
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/steps_unittest.py9
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/suggestreviewers.py7
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/suggestreviewers_unittest.py2
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/update.py2
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/update_unittest.py26
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/updatechangelogswithreview_unittest.py2
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/updatechromiumdeps.py77
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/validatechangelogs.py15
-rw-r--r--Tools/Scripts/webkitpy/tool/steps/validatechangelogs_unittest.py15
31 files changed, 831 insertions, 230 deletions
diff --git a/Tools/Scripts/webkitpy/tool/steps/__init__.py b/Tools/Scripts/webkitpy/tool/steps/__init__.py
index 56429e8fe..655f7d50a 100644
--- a/Tools/Scripts/webkitpy/tool/steps/__init__.py
+++ b/Tools/Scripts/webkitpy/tool/steps/__init__.py
@@ -35,23 +35,23 @@ from webkitpy.tool.steps.attachtobug import AttachToBug
from webkitpy.tool.steps.build import Build
from webkitpy.tool.steps.checkstyle import CheckStyle
from webkitpy.tool.steps.cleanworkingdirectory import CleanWorkingDirectory
-from webkitpy.tool.steps.cleanworkingdirectorywithlocalcommits import CleanWorkingDirectoryWithLocalCommits
from webkitpy.tool.steps.closebug import CloseBug
from webkitpy.tool.steps.closebugforlanddiff import CloseBugForLandDiff
from webkitpy.tool.steps.closepatch import ClosePatch
from webkitpy.tool.steps.commit import Commit
from webkitpy.tool.steps.confirmdiff import ConfirmDiff
from webkitpy.tool.steps.createbug import CreateBug
+from webkitpy.tool.steps.discardlocalchanges import DiscardLocalChanges
from webkitpy.tool.steps.editchangelog import EditChangeLog
from webkitpy.tool.steps.ensurebugisopenandassigned import EnsureBugIsOpenAndAssigned
from webkitpy.tool.steps.ensurelocalcommitifneeded import EnsureLocalCommitIfNeeded
+from webkitpy.tool.steps.haslanded import HasLanded
from webkitpy.tool.steps.obsoletepatches import ObsoletePatches
from webkitpy.tool.steps.options import Options
from webkitpy.tool.steps.postdiff import PostDiff
from webkitpy.tool.steps.postdiffforcommit import PostDiffForCommit
from webkitpy.tool.steps.postdiffforrevert import PostDiffForRevert
from webkitpy.tool.steps.preparechangelog import PrepareChangeLog
-from webkitpy.tool.steps.preparechangelogfordepsroll import PrepareChangeLogForDEPSRoll
from webkitpy.tool.steps.preparechangelogforrevert import PrepareChangeLogForRevert
from webkitpy.tool.steps.promptforbugortitle import PromptForBugOrTitle
from webkitpy.tool.steps.reopenbugafterrollout import ReopenBugAfterRollout
@@ -60,6 +60,5 @@ from webkitpy.tool.steps.runtests import RunTests
from webkitpy.tool.steps.suggestreviewers import SuggestReviewers
from webkitpy.tool.steps.update import Update
from webkitpy.tool.steps.updatechangelogswithreviewer import UpdateChangeLogsWithReviewer
-from webkitpy.tool.steps.updatechromiumdeps import UpdateChromiumDEPS
from webkitpy.tool.steps.validatechangelogs import ValidateChangeLogs
from webkitpy.tool.steps.validatereviewer import ValidateReviewer
diff --git a/Tools/Scripts/webkitpy/tool/steps/addsvnmimetypeforpng_unittest.py b/Tools/Scripts/webkitpy/tool/steps/addsvnmimetypeforpng_unittest.py
index 9fab6f438..12be0bee2 100644
--- a/Tools/Scripts/webkitpy/tool/steps/addsvnmimetypeforpng_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/steps/addsvnmimetypeforpng_unittest.py
@@ -21,7 +21,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import unittest
+import unittest2 as unittest
from webkitpy.tool.steps.addsvnmimetypeforpng import AddSvnMimetypeForPng
from webkitpy.common.system.filesystem_mock import MockFileSystem
diff --git a/Tools/Scripts/webkitpy/tool/steps/applywatchlist_unittest.py b/Tools/Scripts/webkitpy/tool/steps/applywatchlist_unittest.py
index a978f4164..a740c3d3c 100644
--- a/Tools/Scripts/webkitpy/tool/steps/applywatchlist_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/steps/applywatchlist_unittest.py
@@ -26,7 +26,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import unittest
+import unittest2 as unittest
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.tool.mocktool import MockOptions, MockTool
diff --git a/Tools/Scripts/webkitpy/tool/steps/build.py b/Tools/Scripts/webkitpy/tool/steps/build.py
index a2a627229..b02830ca2 100644
--- a/Tools/Scripts/webkitpy/tool/steps/build.py
+++ b/Tools/Scripts/webkitpy/tool/steps/build.py
@@ -48,7 +48,7 @@ class Build(AbstractStep):
environment.disable_gcc_smartquotes()
env = environment.to_dictionary()
- build_webkit_command = self._tool.port().build_webkit_command(build_style=build_style)
+ build_webkit_command = self._tool.deprecated_port().build_webkit_command(build_style=build_style)
self._tool.executive.run_and_throw_if_fail(build_webkit_command, self._options.quiet,
cwd=self._tool.scm().checkout_root, env=env)
diff --git a/Tools/Scripts/webkitpy/tool/steps/checkstyle.py b/Tools/Scripts/webkitpy/tool/steps/checkstyle.py
index 0cb15f4c1..cec8a8132 100644
--- a/Tools/Scripts/webkitpy/tool/steps/checkstyle.py
+++ b/Tools/Scripts/webkitpy/tool/steps/checkstyle.py
@@ -57,7 +57,7 @@ class CheckStyle(AbstractStep):
args.append(self._options.check_style_filter)
try:
- self._tool.executive.run_and_throw_if_fail(self._tool.port().check_webkit_style_command() + args, cwd=self._tool.scm().checkout_root)
+ self._tool.executive.run_and_throw_if_fail(self._tool.deprecated_port().check_webkit_style_command() + args, cwd=self._tool.scm().checkout_root)
except ScriptError, e:
if self._options.non_interactive:
# We need to re-raise the exception here to have the
diff --git a/Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectory.py b/Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectory.py
index 191352440..a4cbe82c5 100644
--- a/Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectory.py
+++ b/Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectory.py
@@ -28,12 +28,10 @@
from webkitpy.tool.steps.abstractstep import AbstractStep
from webkitpy.tool.steps.options import Options
+from webkitpy.common.system.executive import ScriptError
class CleanWorkingDirectory(AbstractStep):
- def __init__(self, tool, options, allow_local_commits=False):
- AbstractStep.__init__(self, tool, options)
- self._allow_local_commits = allow_local_commits
@classmethod
def options(cls):
@@ -45,6 +43,8 @@ class CleanWorkingDirectory(AbstractStep):
def run(self, state):
if not self._options.clean:
return
- if not self._allow_local_commits:
- self._tool.scm().ensure_no_local_commits(self._options.force_clean)
- self._tool.scm().ensure_clean_working_directory(force_clean=self._options.force_clean)
+
+ if self._tool.scm().has_working_directory_changes() and not self._options.force_clean:
+ raise ScriptError("Working directory has changes, pass --force-clean to continue.")
+
+ self._tool.scm().discard_working_directory_changes()
diff --git a/Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectory_unittest.py b/Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectory_unittest.py
index 15a8850a5..7e31a9bd8 100644
--- a/Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectory_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectory_unittest.py
@@ -26,27 +26,43 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import unittest
+import unittest2 as unittest
from webkitpy.thirdparty.mock import Mock
from webkitpy.tool.mocktool import MockOptions, MockTool
from webkitpy.tool.steps.cleanworkingdirectory import CleanWorkingDirectory
+from webkitpy.common.system.executive import ScriptError
class CleanWorkingDirectoryTest(unittest.TestCase):
- def test_run(self):
+ def test_run_working_directory_changes_no_force(self):
tool = MockTool()
tool._scm = Mock()
- tool._scm.checkout_root = '/mock-checkout'
step = CleanWorkingDirectory(tool, MockOptions(clean=True, force_clean=False))
+ tool._scm.has_working_directory_changes = lambda: True
+ self.assertRaises(ScriptError, step.run, {})
+ self.assertEqual(tool._scm.discard_working_directory_changes.call_count, 0)
+
+ def test_run_working_directory_changes_force(self):
+ tool = MockTool()
+ tool._scm = Mock()
+ step = CleanWorkingDirectory(tool, MockOptions(clean=True, force_clean=True))
+ tool._scm.has_working_directory_changes = lambda: True
+ step.run({})
+ self.assertEqual(tool._scm.discard_working_directory_changes.call_count, 1)
+
+ def test_run_no_local_changes(self):
+ tool = MockTool()
+ tool._scm = Mock()
+ step = CleanWorkingDirectory(tool, MockOptions(clean=True, force_clean=False))
+ tool._scm.has_working_directory_changes = lambda: False
+ tool._scm.has_local_commits = lambda: False
step.run({})
- self.assertEqual(tool._scm.ensure_no_local_commits.call_count, 1)
- self.assertEqual(tool._scm.ensure_clean_working_directory.call_count, 1)
+ self.assertEqual(tool._scm.discard_working_directory_changes.call_count, 1)
def test_no_clean(self):
tool = MockTool()
tool._scm = Mock()
step = CleanWorkingDirectory(tool, MockOptions(clean=False))
step.run({})
- self.assertEqual(tool._scm.ensure_no_local_commits.call_count, 0)
- self.assertEqual(tool._scm.ensure_clean_working_directory.call_count, 0)
+ self.assertEqual(tool._scm.discard_working_directory_changes.call_count, 0)
diff --git a/Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectorywithlocalcommits.py b/Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectorywithlocalcommits.py
deleted file mode 100644
index f06f94ef4..000000000
--- a/Tools/Scripts/webkitpy/tool/steps/cleanworkingdirectorywithlocalcommits.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2010 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-from webkitpy.tool.steps.cleanworkingdirectory import CleanWorkingDirectory
-
-class CleanWorkingDirectoryWithLocalCommits(CleanWorkingDirectory):
- def __init__(self, tool, options):
- # FIXME: This a bit of a hack. Consider doing this more cleanly.
- CleanWorkingDirectory.__init__(self, tool, options, allow_local_commits=True)
diff --git a/Tools/Scripts/webkitpy/tool/steps/closebugforlanddiff_unittest.py b/Tools/Scripts/webkitpy/tool/steps/closebugforlanddiff_unittest.py
index 6969c4e9a..b042d4258 100644
--- a/Tools/Scripts/webkitpy/tool/steps/closebugforlanddiff_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/steps/closebugforlanddiff_unittest.py
@@ -26,7 +26,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import unittest
+import unittest2 as unittest
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.tool.mocktool import MockOptions, MockTool
diff --git a/Tools/Scripts/webkitpy/tool/steps/commit.py b/Tools/Scripts/webkitpy/tool/steps/commit.py
index 2bffa4c2a..1d5109a00 100644
--- a/Tools/Scripts/webkitpy/tool/steps/commit.py
+++ b/Tools/Scripts/webkitpy/tool/steps/commit.py
@@ -40,20 +40,17 @@ _log = logging.getLogger(__name__)
class Commit(AbstractStep):
- # FIXME: This option exists only to make sure we don't break scripts which include --ignore-builders
- # You can safely delete this option any time after 11/01/11.
@classmethod
def options(cls):
return AbstractStep.options() + [
- Options.check_builders,
Options.non_interactive,
]
def _commit_warning(self, error):
- working_directory_message = "" if error.working_directory_is_clean else " and working copy changes"
- return ('There are %s local commits%s. Everything will be committed as a single commit. '
+ return ('There are %s local commits (and possibly changes in the working directory. '
+ 'Everything will be committed as a single commit. '
'To avoid this prompt, set "git config webkit-patch.commit-should-always-squash true".' % (
- error.num_local_commits, working_directory_message))
+ error.num_local_commits))
def _check_test_expectations(self, changed_files):
test_expectations_files = [filename for filename in changed_files if filename.endswith('TestExpectations')]
@@ -63,7 +60,7 @@ class Commit(AbstractStep):
args = ["--diff-files"]
args.extend(test_expectations_files)
try:
- self._tool.executive.run_and_throw_if_fail(self._tool.port().check_webkit_style_command() + args, cwd=self._tool.scm().checkout_root)
+ self._tool.executive.run_and_throw_if_fail(self._tool.deprecated_port().check_webkit_style_command() + args, cwd=self._tool.scm().checkout_root)
except ScriptError, e:
if self._options.non_interactive:
raise
@@ -76,12 +73,11 @@ class Commit(AbstractStep):
raise Exception("Attempted to commit with a commit message shorter than 10 characters. Either your patch is missing a ChangeLog or webkit-patch may have a bug.")
self._check_test_expectations(self._changed_files(state))
-
self._state = state
username = None
password = None
- force_squash = False
+ force_squash = self._options.non_interactive
num_tries = 0
while num_tries < 3:
@@ -95,7 +91,7 @@ class Commit(AbstractStep):
self._state["commit_text"] = commit_text
break;
except AmbiguousCommitError, e:
- if self._options.non_interactive or self._tool.user.confirm(self._commit_warning(e)):
+ if self._tool.user.confirm(self._commit_warning(e)):
force_squash = True
else:
# This will correctly interrupt the rest of the commit process.
diff --git a/Tools/Scripts/webkitpy/tool/steps/commit_unittest.py b/Tools/Scripts/webkitpy/tool/steps/commit_unittest.py
index 936e3ebab..c6b76b428 100644
--- a/Tools/Scripts/webkitpy/tool/steps/commit_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/steps/commit_unittest.py
@@ -26,7 +26,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import unittest
+import unittest2 as unittest
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.common.system.executive import ScriptError
diff --git a/Tools/Scripts/webkitpy/tool/steps/preparechangelogfordepsroll.py b/Tools/Scripts/webkitpy/tool/steps/discardlocalchanges.py
index 4bbd383ae..8a84cc702 100644
--- a/Tools/Scripts/webkitpy/tool/steps/preparechangelogfordepsroll.py
+++ b/Tools/Scripts/webkitpy/tool/steps/discardlocalchanges.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2011 Google Inc. All rights reserved.
+# Copyright (C) 2010 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
@@ -26,13 +26,27 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-from webkitpy.common.checkout.changelog import ChangeLog
from webkitpy.tool.steps.abstractstep import AbstractStep
+from webkitpy.tool.steps.options import Options
+from webkitpy.common.system.executive import ScriptError
-class PrepareChangeLogForDEPSRoll(AbstractStep):
+class DiscardLocalChanges(AbstractStep):
+
+ @classmethod
+ def options(cls):
+ return AbstractStep.options() + [
+ Options.clean,
+ Options.force_clean,
+ ]
+
def run(self, state):
- self._tool.executive.run_and_throw_if_fail(self._tool.port().prepare_changelog_command())
- changelog_paths = self._tool.checkout().modified_changelogs(git_commit=None)
- for changelog_path in changelog_paths:
- ChangeLog(changelog_path).update_with_unreviewed_message("Unreviewed. Rolled DEPS.\n\n")
+ if not self._options.clean:
+ return
+
+ if not self._options.force_clean:
+ if self._tool.scm().has_working_directory_changes():
+ raise ScriptError("Working directory has changes, pass --force-clean to continue.")
+ if self._tool.scm().has_local_commits():
+ raise ScriptError("Repository has local commits, pass --force-clean to continue.")
+ self._tool.scm().discard_local_changes()
diff --git a/Tools/Scripts/webkitpy/tool/steps/discardlocalchanges_unittest.py b/Tools/Scripts/webkitpy/tool/steps/discardlocalchanges_unittest.py
new file mode 100644
index 000000000..d38fc926c
--- /dev/null
+++ b/Tools/Scripts/webkitpy/tool/steps/discardlocalchanges_unittest.py
@@ -0,0 +1,97 @@
+# Copyright (C) 2010 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import unittest2 as unittest
+
+from webkitpy.thirdparty.mock import Mock
+from webkitpy.tool.mocktool import MockOptions, MockTool
+from webkitpy.tool.steps.discardlocalchanges import DiscardLocalChanges
+from webkitpy.common.system.executive import ScriptError
+
+
+class DiscardLocalChangesTest(unittest.TestCase):
+ def test_skip_on_clean(self):
+ tool = MockTool()
+ tool._scm = Mock()
+ step = DiscardLocalChanges(tool, MockOptions(clean=False))
+ step.run({})
+ self.assertEqual(tool._scm.discard_local_changes.call_count, 0)
+
+ def test_working_changes_exist_with_force(self):
+ tool = MockTool()
+ tool._scm = Mock()
+ tool._scm.has_working_directory_changes = lambda: True
+ tool._scm.has_local_commits = lambda: False
+ step = DiscardLocalChanges(tool, MockOptions(clean=True, force_clean=True))
+ step.run({})
+ self.assertEqual(tool._scm.discard_local_changes.call_count, 1)
+
+ def test_local_commits_exist_with_force(self):
+ tool = MockTool()
+ tool._scm = Mock()
+ tool._scm.has_working_directory_changes = lambda: False
+ tool._scm.has_local_commits = lambda: True
+ step = DiscardLocalChanges(tool, MockOptions(clean=True, force_clean=True))
+ step.run({})
+ self.assertEqual(tool._scm.discard_local_changes.call_count, 1)
+
+ def test_local_commits_and_working_changes_exist_with_force(self):
+ tool = MockTool()
+ tool._scm = Mock()
+ tool._scm.has_working_directory_changes = lambda: True
+ tool._scm.has_local_commits = lambda: True
+ step = DiscardLocalChanges(tool, MockOptions(clean=True, force_clean=True))
+ step.run({})
+ self.assertEqual(tool._scm.discard_local_changes.call_count, 1)
+
+ def test_no_changes_exist_with_force(self):
+ tool = MockTool()
+ tool._scm = Mock()
+ tool._scm.has_working_directory_changes = lambda: False
+ tool._scm.has_local_commits = lambda: False
+ step = DiscardLocalChanges(tool, MockOptions(clean=True, force_clean=True))
+ step.run({})
+ self.assertEqual(tool._scm.discard_local_changes.call_count, 1)
+
+ def test_error_working_changes_exist_without_force(self):
+ tool = MockTool()
+ tool._scm = Mock()
+ tool._scm.has_working_directory_changes = lambda: True
+ tool._scm.has_local_commits = lambda: False
+ step = DiscardLocalChanges(tool, MockOptions(clean=True, force_clean=False))
+ self.assertRaises(ScriptError, step.run, {})
+ self.assertEqual(tool._scm.discard_local_changes.call_count, 0)
+
+ def test_error_local_commits_exist_without_force(self):
+ tool = MockTool()
+ tool._scm = Mock()
+ tool._scm.has_working_directory_changes = lambda: False
+ tool._scm.has_local_commits = lambda: True
+ step = DiscardLocalChanges(tool, MockOptions(clean=True, force_clean=False))
+ self.assertRaises(ScriptError, step.run, {})
+ self.assertEqual(tool._scm.discard_local_changes.call_count, 0)
diff --git a/Tools/Scripts/webkitpy/tool/steps/haslanded.py b/Tools/Scripts/webkitpy/tool/steps/haslanded.py
new file mode 100644
index 000000000..b0692b32b
--- /dev/null
+++ b/Tools/Scripts/webkitpy/tool/steps/haslanded.py
@@ -0,0 +1,120 @@
+# Copyright (C) 2010 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import cStringIO as StringIO
+import logging
+import sys
+import re
+import tempfile
+
+from webkitpy.tool.steps.abstractstep import AbstractStep
+from webkitpy.common.system.executive import Executive, ScriptError
+from webkitpy.common.checkout import diff_parser
+
+from webkitpy.tool.steps import confirmdiff
+
+_log = logging.getLogger(__name__)
+
+
+class HasLanded(confirmdiff.ConfirmDiff):
+
+ @classmethod
+ def convert_to_svn(cls, diff):
+ lines = StringIO.StringIO(diff).readlines()
+ convert = diff_parser.get_diff_converter(lines)
+ return "".join(convert(x) for x in lines)
+
+ @classmethod
+ def strip_change_log(cls, diff):
+ output = []
+ skipping = False
+ for line in StringIO.StringIO(diff).readlines():
+ indexline = re.match("^Index: ([^\\n]*/)?([^/\\n]*)$", line)
+ if skipping and indexline:
+ skipping = False
+ if indexline and indexline.group(2) == "ChangeLog":
+ skipping = True
+ if not skipping:
+ output.append(line)
+ return "".join(output)
+
+ @classmethod
+ def diff_diff(cls, diff1, diff2, diff1_suffix, diff2_suffix, executive=None):
+ # Now this is where it gets complicated, we need to compare our diff to the diff at landed_revision.
+ diff1_patch = tempfile.NamedTemporaryFile(suffix=diff1_suffix + '.patch')
+ diff1_patch.write(diff1)
+ diff1_patch.flush()
+
+ # Check if there are any differences in the patch that don't happen
+ diff2_patch = tempfile.NamedTemporaryFile(suffix=diff2_suffix + '.patch')
+ diff2_patch.write(diff2)
+ diff2_patch.flush()
+
+ # Diff the two diff's together...
+ if not executive:
+ executive = Executive()
+
+ try:
+ return executive.run_command(
+ ["interdiff", diff1_patch.name, diff2_patch.name], decode_output=False)
+ except ScriptError, e:
+ _log.warning("Unable to find interdiff util (part of GNU difftools package) which is required.")
+ raise
+
+ def run(self, state):
+ # Check if there are changes first
+ if not self._tool.scm().local_changes_exist():
+ _log.warn("No local changes found, exiting.")
+ return True
+
+ # Check if there is a SVN revision in the bug from the commit queue
+ landed_revision = self.cached_lookup(state, "bug").commit_revision()
+ if not landed_revision:
+ raise ScriptError("Unable to find landed message in associated bug.")
+
+ # Now this is there it gets complicated, we need to compare our diff to the diff at landed_revision.
+ landed_diff_bin = self._tool.scm().diff_for_revision(landed_revision)
+ landed_diff_trimmed = self.strip_change_log(self.convert_to_svn(landed_diff_bin))
+
+ # Check if there are any differences in the patch that don't happen
+ local_diff_bin = self._tool.scm().create_patch()
+ local_diff_trimmed = self.strip_change_log(self.convert_to_svn(local_diff_bin))
+
+ # Diff the two diff's together...
+ diff_diff = self.diff_diff(landed_diff_trimmed, local_diff_trimmed,
+ '-landed', '-local',
+ executive=self._tool.executive)
+
+ with self._show_pretty_diff(diff_diff) as pretty_diff_file:
+ if not pretty_diff_file:
+ self._tool.user.page(diff_diff)
+
+ if self._tool.user.confirm("May I discard local changes?"):
+ # Discard changes if the user confirmed we should
+ _log.warn("Discarding changes as requested.")
+ self._tool.scm().discard_local_changes()
diff --git a/Tools/Scripts/webkitpy/tool/steps/haslanded_unittest.py b/Tools/Scripts/webkitpy/tool/steps/haslanded_unittest.py
new file mode 100644
index 000000000..3a67029a8
--- /dev/null
+++ b/Tools/Scripts/webkitpy/tool/steps/haslanded_unittest.py
@@ -0,0 +1,299 @@
+# Copyright (C) 2009 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import unittest2 as unittest
+import subprocess
+
+from webkitpy.tool.steps.haslanded import HasLanded
+
+
+class HasLandedTest(unittest.TestCase):
+ maxDiff = None
+
+ @unittest.skipUnless(subprocess.call('which interdiff', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0, "requires interdiff")
+ def test_run(self):
+ # These patches require trailing whitespace to remain valid patches.
+ diff1 = """\
+Index: a.py
+===================================================================
+--- a.py
++++ a.py
+@@ -1,3 +1,5 @@
+ A
+ B
+ C
++D
++E
+Index: b.py
+===================================================================
+--- b.py 2013-01-21 15:20:59.693887185 +1100
++++ b.py 2013-01-21 15:22:24.382555711 +1100
+@@ -1,3 +1,5 @@
+ 1
+ 2
+ 3
++4
++5
+"""
+
+ diff1_add_line = """\
+Index: a.py
+===================================================================
+--- a.py
++++ a.py
+@@ -1,3 +1,6 @@
+ A
+ B
+ C
++D
++E
++F
+Index: b.py
+===================================================================
+--- b.py
++++ b.py
+@@ -1,3 +1,5 @@
+ 1
+ 2
+ 3
++4
++5
+"""
+
+ diff1_remove_line = """\
+Index: a.py
+===================================================================
+--- a.py
++++ a.py
+@@ -1,3 +1,4 @@
+ A
+ B
+ C
++D
+Index: b.py
+===================================================================
+--- b.py
++++ b.py
+@@ -1,3 +1,5 @@
+ 1
+ 2
+ 3
++4
++5
+"""
+
+ diff1_add_file = diff1 + """\
+Index: c.py
+===================================================================
+--- c.py
++++ c.py
+@@ -1,3 +1,5 @@
+ 1
+ 2
+ 3
++4
++5
+"""
+
+ diff1_remove_file = """\
+Index: a.py
+===================================================================
+--- a.py
++++ a.py
+@@ -1,3 +1,5 @@
+ A
+ B
+ C
++D
++E
+"""
+ self.assertMultiLineEqual(
+ HasLanded.diff_diff(diff1, diff1_add_line, '', 'add-line'),
+ """\
+diff -u a.py a.py
+--- a.py
++++ a.py
+@@ -5,0 +6 @@
++F
+""")
+
+ self.assertMultiLineEqual(
+ HasLanded.diff_diff(diff1, diff1_remove_line, '', 'remove-line'),
+ """\
+diff -u a.py a.py
+--- a.py
++++ a.py
+@@ -5 +4,0 @@
+-E
+""")
+ self.assertMultiLineEqual(
+ HasLanded.diff_diff(diff1, diff1_add_file, '', 'add-file'),
+ """\
+only in patch2:
+unchanged:
+--- c.py
++++ c.py
+@@ -1,3 +1,5 @@
+ 1
+ 2
+ 3
++4
++5
+""")
+ self.assertMultiLineEqual(
+ HasLanded.diff_diff(diff1, diff1_remove_file, '', 'remove-file'),
+ """\
+reverted:
+--- b.py 2013-01-21 15:22:24.382555711 +1100
++++ b.py 2013-01-21 15:20:59.693887185 +1100
+@@ -1,5 +1,3 @@
+ 1
+ 2
+ 3
+-4
+-5
+""")
+
+ def test_convert_to_svn_and_strip_change_log(self):
+ # These patches require trailing whitespace to remain valid patches.
+ testbefore1 = HasLanded.convert_to_svn("""\
+diff --git a/Tools/ChangeLog b/Tools/ChangeLog
+index 219ba72..0390b73 100644
+--- a/Tools/ChangeLog
++++ b/Tools/ChangeLog
+@@ -1,3 +1,32 @@
++2013-01-17 Tim 'mithro' Ansell <mithro@mithis.com>
++
++ Adding "has-landed" command to webkit-patch which allows a person to
++ Reviewed by NOBODY (OOPS!).
++
+ 2013-01-20 Tim 'mithro' Ansell <mithro@mithis.com>
+
+ Extend diff_parser to support the --full-index output.
+diff --git a/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py b/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
+index 4bf8ec6..3a128cb 100644
+--- a/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
++++ b/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
+@@ -28,6 +28,8 @@
++import re
++
+ from .attachment import Attachment
+
+""")
+ testafter1 = HasLanded.convert_to_svn("""\
+diff --git a/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py b/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
+index 4bf8ec6..3a128cb 100644
+--- a/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
++++ b/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
+@@ -28,6 +28,8 @@
++import re
++
+ from .attachment import Attachment
+
+diff --git a/Tools/ChangeLog b/Tools/ChangeLog
+index 219ba72..0390b73 100644
+--- a/Tools/ChangeLog
++++ b/Tools/ChangeLog
+@@ -1,3 +1,32 @@
++2013-01-17 Tim 'mithro' Ansell <mithro@mithis.com>
++
++ Adding "has-landed" command to webkit-patch which allows a person to
++ Reviewed by NOBODY (OOPS!).
++
+ 2013-01-20 Tim 'mithro' Ansell <mithro@mithis.com>
+
+ Extend diff_parser to support the --full-index output.
+""")
+ testexpected1 = """\
+Index: Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
+===================================================================
+--- Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
++++ Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
+@@ -28,6 +28,8 @@
++import re
++
+ from .attachment import Attachment
+
+"""
+ testmiddle1 = HasLanded.convert_to_svn("""\
+diff --git a/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py b/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
+index 4bf8ec6..3a128cb 100644
+--- a/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
++++ b/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
+@@ -28,6 +28,8 @@
++import re
++
+ from .attachment import Attachment
+
+diff --git a/ChangeLog b/ChangeLog
+index 219ba72..0390b73 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,32 @@
++2013-01-17 Tim 'mithro' Ansell <mithro@mithis.com>
++
++ Adding "has-landed" command to webkit-patch which allows a person to
++ Reviewed by NOBODY (OOPS!).
++
+ 2013-01-20 Tim 'mithro' Ansell <mithro@mithis.com>
+
+ Extend diff_parser to support the --full-index output.
+diff --git a/Tools/Scripts/webkitpy/common/other.py b/Tools/Scripts/webkitpy/common/other.py
+index 4bf8ec6..3a128cb 100644
+--- a/Tools/Scripts/webkitpy/common/other.py
++++ b/Tools/Scripts/webkitpy/common/other.py
+@@ -28,6 +28,8 @@
++import re
++
+ from .attachment import Attachment
+
+""")
+ testexpected2 = """\
+Index: Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
+===================================================================
+--- Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
++++ Tools/Scripts/webkitpy/common/net/bugzilla/bug.py
+@@ -28,6 +28,8 @@
++import re
++
+ from .attachment import Attachment
+
+Index: Tools/Scripts/webkitpy/common/other.py
+===================================================================
+--- Tools/Scripts/webkitpy/common/other.py
++++ Tools/Scripts/webkitpy/common/other.py
+@@ -28,6 +28,8 @@
++import re
++
+ from .attachment import Attachment
+
+"""
+
+ self.assertMultiLineEqual(testexpected1, HasLanded.strip_change_log(testbefore1))
+ self.assertMultiLineEqual(testexpected1, HasLanded.strip_change_log(testafter1))
+ self.assertMultiLineEqual(testexpected2, HasLanded.strip_change_log(testmiddle1))
diff --git a/Tools/Scripts/webkitpy/tool/steps/options.py b/Tools/Scripts/webkitpy/tool/steps/options.py
index c29e59d9c..7eda61459 100644
--- a/Tools/Scripts/webkitpy/tool/steps/options.py
+++ b/Tools/Scripts/webkitpy/tool/steps/options.py
@@ -33,7 +33,6 @@ class Options(object):
build = make_option("--build", action="store_true", dest="build", default=False, help="Build and run run-webkit-tests before committing.")
build_style = make_option("--build-style", action="store", dest="build_style", default=None, help="Whether to build debug, release, or both.")
cc = make_option("--cc", action="store", type="string", dest="cc", help="Comma-separated list of email addresses to carbon-copy.")
- check_builders = make_option("--ignore-builders", action="store_false", dest="check_builders", default=True, help="DEPRECATED: Will be removed any time after 11/01/11.")
check_style = make_option("--ignore-style", action="store_false", dest="check_style", default=True, help="Don't check to see if the patch has proper style before uploading.")
check_style_filter = make_option("--check-style-filter", action="store", type="string", dest="check_style_filter", default=None, help="Filter style-checker rules (see check-webkit-style --help).")
clean = make_option("--no-clean", action="store_false", dest="clean", default=True, help="Don't check if the working directory is clean before applying patches")
@@ -57,4 +56,5 @@ class Options(object):
suggest_reviewers = make_option("--suggest-reviewers", action="store_true", default=False, help="Offer to CC appropriate reviewers.")
test = make_option("--test", action="store_true", dest="test", default=False, help="Run run-webkit-tests before committing.")
update = make_option("--no-update", action="store_false", dest="update", default=True, help="Don't update the working directory.")
+ update_changelogs = make_option("--update-changelogs", action="store_true", dest="update_changelogs", default=False, help="Update existing ChangeLog entries with new date, bug description, and touched files/functions.")
changelog_count = make_option("--changelog-count", action="store", type="int", dest="changelog_count", help="Number of changelogs to parse.")
diff --git a/Tools/Scripts/webkitpy/tool/steps/preparechangelog.py b/Tools/Scripts/webkitpy/tool/steps/preparechangelog.py
index 4d80ab61f..716ab826d 100644
--- a/Tools/Scripts/webkitpy/tool/steps/preparechangelog.py
+++ b/Tools/Scripts/webkitpy/tool/steps/preparechangelog.py
@@ -27,6 +27,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import logging
+import re
import sys
from webkitpy.common.checkout.changelog import ChangeLog
@@ -44,6 +45,7 @@ class PrepareChangeLog(AbstractStep):
Options.quiet,
Options.email,
Options.git_commit,
+ Options.update_changelogs,
]
def _ensure_bug_url(self, state):
@@ -52,17 +54,60 @@ class PrepareChangeLog(AbstractStep):
bug_id = state.get("bug_id")
changelogs = self.cached_lookup(state, "changelogs")
for changelog_path in changelogs:
- changelog = ChangeLog(changelog_path)
+ changelog = ChangeLog(changelog_path, self._tool.filesystem)
if not changelog.latest_entry().bug_id():
changelog.set_short_description_and_bug_url(
self.cached_lookup(state, "bug_title"),
self._tool.bugs.bug_url_for_bug_id(bug_id))
+ def _resolve_existing_entry(self, changelog_path):
+ # When this is called, the top entry in the ChangeLog was just created
+ # by prepare-ChangeLog, as an clean updated version of the one below it.
+ with self._tool.filesystem.open_text_file_for_reading(changelog_path) as changelog_file:
+ entries_gen = ChangeLog.parse_entries_from_file(changelog_file)
+ entries = zip(entries_gen, range(2))
+
+ if not len(entries):
+ raise Exception("Expected to find at least two ChangeLog entries in %s but found none." % changelog_path)
+ if len(entries) == 1:
+ # If we get here, it probably means we've just rolled over to a
+ # new CL file, so we don't have anything to resolve.
+ return
+
+ (new_entry, _), (old_entry, _) = entries
+ final_entry = self._merge_entries(old_entry, new_entry)
+
+ changelog = ChangeLog(changelog_path, self._tool.filesystem)
+ changelog.delete_entries(2)
+ changelog.prepend_text(final_entry)
+
+ def _merge_entries(self, old_entry, new_entry):
+ final_entry = old_entry.contents()
+
+ final_entry = final_entry.replace(old_entry.date(), new_entry.date(), 1)
+
+ new_bug_desc = new_entry.bug_description()
+ old_bug_desc = old_entry.bug_description()
+ if new_bug_desc and old_bug_desc and new_bug_desc != old_bug_desc:
+ final_entry = final_entry.replace(old_bug_desc, new_bug_desc)
+
+ new_touched = new_entry.touched_functions()
+ old_touched = old_entry.touched_functions()
+ if new_touched != old_touched:
+ if old_entry.is_touched_files_text_clean():
+ final_entry = final_entry.replace(old_entry.touched_files_text(), new_entry.touched_files_text())
+ else:
+ final_entry += "\n" + new_entry.touched_files_text()
+
+ return final_entry + "\n"
+
def run(self, state):
if self.cached_lookup(state, "changelogs"):
self._ensure_bug_url(state)
- return
- args = self._tool.port().prepare_changelog_command()
+ if not self._options.update_changelogs:
+ return
+
+ args = self._tool.deprecated_port().prepare_changelog_command()
if state.get("bug_id"):
args.append("--bug=%s" % state["bug_id"])
args.append("--description=%s" % self.cached_lookup(state, 'bug_title'))
@@ -75,8 +120,15 @@ class PrepareChangeLog(AbstractStep):
args.extend(self._changed_files(state))
try:
- self._tool.executive.run_and_throw_if_fail(args, self._options.quiet, cwd=self._tool.scm().checkout_root)
+ output = self._tool.executive.run_and_throw_if_fail(args, self._options.quiet, cwd=self._tool.scm().checkout_root)
except ScriptError, e:
_log.error("Unable to prepare ChangeLogs.")
sys.exit(1)
+
+ # These are the ChangeLog entries added by prepare-Changelog
+ changelogs = re.findall(r'Editing the (\S*/ChangeLog) file.', output)
+ changelogs = set(self._tool.filesystem.join(self._tool.scm().checkout_root, f) for f in changelogs)
+ for changelog in changelogs & set(self.cached_lookup(state, "changelogs")):
+ self._resolve_existing_entry(changelog)
+
self.did_modify_checkout(state)
diff --git a/Tools/Scripts/webkitpy/tool/steps/preparechangelog_unittest.py b/Tools/Scripts/webkitpy/tool/steps/preparechangelog_unittest.py
index fc31d1fa9..803f072a3 100644
--- a/Tools/Scripts/webkitpy/tool/steps/preparechangelog_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/steps/preparechangelog_unittest.py
@@ -26,32 +26,108 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import os
-import unittest
+import unittest2 as unittest
# Do not import changelog_unittest.ChangeLogTest directly as that will cause it to be run again.
from webkitpy.common.checkout import changelog_unittest
+from webkitpy.common.system.filesystem_mock import MockFileSystem
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.tool.mocktool import MockOptions, MockTool
from webkitpy.tool.steps.preparechangelog import PrepareChangeLog
-
class PrepareChangeLogTest(changelog_unittest.ChangeLogTest):
+ def test_resolve_existing_entry(self):
+ step = PrepareChangeLog(MockTool(), MockOptions())
+
+ headers = ["2013-01-18 Timothy Loh <timloh@chromium.com>\n\n",
+ "2013-01-20 Timothy Loh <timloh@chromium.com>\n\n",
+ u"2009-08-17 Tor Arne Vestb\xf8 <vestbo@webkit.org>\n\n",
+ u"2009-08-18 Tor Arne Vestb\xf8 <vestbo@webkit.org>\n\n",
+ "2013-01-18 Eric Seidel <eric@webkit.org>\n\n",
+ "2013-01-20 Eric Seidel <eric@webkit.org>\n\n",
+ ]
+
+ bug_descs = [" prepare-Changelog should support updating the list of changed files\n",
+ " webkit-patch upload should support updating the list of changed files\n"]
+
+ bug_url = " https://bugs.webkit.org/show_bug.cgi?id=74358\n\n"
+
+ descriptions = ["", " A description of the changes.\n\n",
+ " A description.\n\n With some\n line breaks\n\n"]
+
+ changes = [
+""" * Scripts/webkitpy/tool/steps/preparechangelog.py:
+ (PrepareChangeLog):
+ (PrepareChangeLog.run):\n\n""",
+""" * Scripts/webkitpy/tool/steps/preparechangelog.py:
+ (PrepareChangeLog._resolve_existing_entry):
+ (PrepareChangeLog):
+ (PrepareChangeLog.run):\n\n""",
+""" * Scripts/webkitpy/tool/steps/preparechangelog.py:
+ (PrepareChangeLog): Some annotations
+ (PrepareChangeLog.run):
+ More annotations\n\n""",
+""" * Scripts/webkitpy/tool/steps/preparechangelog.py:
+ (PrepareChangeLog): Some annotations
+ (PrepareChangeLog.run):
+ More annotations
+
+ * Scripts/webkitpy/tool/steps/preparechangelog.py:
+ (PrepareChangeLog._resolve_existing_entry):
+ (PrepareChangeLog):
+ (PrepareChangeLog.run):\n\n""",
+ ]
+
+ def make_entry(indices):
+ a, b, c, d = indices
+ return headers[a] + bug_descs[b] + bug_url + descriptions[c] + changes[d]
+
+ test_cases = [((0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)),
+ ((0, 0, 0, 0), (0, 0, 1, 0), (0, 0, 1, 0)),
+ ((1, 0, 0, 0), (0, 0, 2, 0), (1, 0, 2, 0)),
+ ((0, 1, 0, 0), (0, 0, 1, 0), (0, 1, 1, 0)),
+ ((0, 0, 0, 1), (0, 0, 0, 0), (0, 0, 0, 1)),
+ ((0, 0, 0, 0), (0, 0, 1, 1), (0, 0, 1, 0)),
+ ((0, 0, 0, 0), (0, 0, 2, 2), (0, 0, 2, 2)),
+ ((0, 0, 0, 1), (0, 0, 1, 2), (0, 0, 1, 3)),
+ ((1, 1, 0, 1), (0, 0, 0, 2), (1, 1, 0, 3)),
+ ((3, 0, 0, 0), (2, 0, 1, 0), (3, 0, 1, 0)),
+ ((4, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)),
+ ((5, 0, 0, 0), (0, 0, 0, 0), (1, 0, 0, 0)),
+ ((0, 0, 0, 0), (4, 0, 0, 0), (4, 0, 0, 0)),
+ ((1, 0, 0, 0), (4, 0, 0, 0), (5, 0, 0, 0)),
+ ]
+
+ for new, old, final in test_cases:
+ new_entry = make_entry(new)
+ old_entry = make_entry(old)
+ start_file = new_entry + old_entry + self._rolled_over_footer
+
+ final_entry = make_entry(final)
+ end_file = final_entry + self._rolled_over_footer
+
+ path = "ChangeLog"
+ step._tool.filesystem = MockFileSystem()
+ step._tool.filesystem.write_text_file(path, start_file)
+ step._resolve_existing_entry(path)
+ actual_output = step._tool.filesystem.read_text_file(path)
+ self.assertEquals(actual_output, end_file)
+
def test_ensure_bug_url(self):
- # FIXME: This should use a MockFileSystem instead of a real FileSystem.
capture = OutputCapture()
step = PrepareChangeLog(MockTool(), MockOptions())
changelog_contents = u"%s\n%s" % (self._new_entry_boilerplate, self._example_changelog)
- changelog_path = self._write_tmp_file_with_contents(changelog_contents.encode("utf-8"))
+ changelog_path = "ChangeLog"
state = {
"bug_title": "Example title",
"bug_id": 1234,
"changelogs": [changelog_path],
}
- capture.assert_outputs(self, step.run, [state])
- actual_contents = self._read_file_contents(changelog_path, "utf-8")
+ step._tool.filesystem = MockFileSystem()
+ step._tool.filesystem.write_text_file(changelog_path, changelog_contents)
+ capture.assert_outputs(self, step._ensure_bug_url, [state])
+ actual_contents = step._tool.filesystem.read_text_file(changelog_path)
expected_message = "Example title\n http://example.com/1234"
expected_contents = changelog_contents.replace("Need a short description (OOPS!).\n Need the bug URL (OOPS!).", expected_message)
- os.remove(changelog_path)
- self.assertEqual(actual_contents.splitlines(), expected_contents.splitlines())
+ self.assertEqual(actual_contents, expected_contents)
diff --git a/Tools/Scripts/webkitpy/tool/steps/preparechangelogforrevert.py b/Tools/Scripts/webkitpy/tool/steps/preparechangelogforrevert.py
index 95a99c320..82e7b0252 100644
--- a/Tools/Scripts/webkitpy/tool/steps/preparechangelogforrevert.py
+++ b/Tools/Scripts/webkitpy/tool/steps/preparechangelogforrevert.py
@@ -48,7 +48,7 @@ class PrepareChangeLogForRevert(AbstractStep):
def run(self, state):
# This could move to prepare-ChangeLog by adding a --revert= option.
- self._tool.executive.run_and_throw_if_fail(self._tool.port().prepare_changelog_command(), cwd=self._tool.scm().checkout_root)
+ self._tool.executive.run_and_throw_if_fail(self._tool.deprecated_port().prepare_changelog_command(), cwd=self._tool.scm().checkout_root)
changelog_paths = self._tool.checkout().modified_changelogs(git_commit=None)
bug_url = self._tool.bugs.bug_url_for_bug_id(state["bug_id"]) if state["bug_id"] else None
message = self._message_for_revert(state["revision_list"], state["reason"], bug_url)
diff --git a/Tools/Scripts/webkitpy/tool/steps/preparechangelogforrevert_unittest.py b/Tools/Scripts/webkitpy/tool/steps/preparechangelogforrevert_unittest.py
index b82cb4aa2..3ec6e9a60 100644
--- a/Tools/Scripts/webkitpy/tool/steps/preparechangelogforrevert_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/steps/preparechangelogforrevert_unittest.py
@@ -26,27 +26,17 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import codecs
-import os
-import tempfile
-import unittest
+import unittest2 as unittest
# Do not import changelog_unittest.ChangeLogTest directly as that will cause it to be run again.
from webkitpy.common.checkout import changelog_unittest
from webkitpy.common.checkout.changelog import ChangeLog
+from webkitpy.common.system.filesystem_mock import MockFileSystem
from webkitpy.tool.steps.preparechangelogforrevert import *
class UpdateChangeLogsForRevertTest(unittest.TestCase):
- @staticmethod
- def _write_tmp_file_with_contents(byte_array):
- assert(isinstance(byte_array, str))
- (file_descriptor, file_path) = tempfile.mkstemp() # NamedTemporaryFile always deletes the file on close in python < 2.6
- with os.fdopen(file_descriptor, "w") as file:
- file.write(byte_array)
- return file_path
-
_revert_entry_with_bug_url = '''2009-08-19 Eric Seidel <eric@webkit.org>
Unreviewed, rolling out r12345.
@@ -110,13 +100,13 @@ class UpdateChangeLogsForRevertTest(unittest.TestCase):
def _assert_message_for_revert_output(self, args, expected_entry):
changelog_contents = u"%s\n%s" % (changelog_unittest.ChangeLogTest._new_entry_boilerplate, changelog_unittest.ChangeLogTest._example_changelog)
- changelog_path = self._write_tmp_file_with_contents(changelog_contents.encode("utf-8"))
- changelog = ChangeLog(changelog_path)
+ changelog_path = "ChangeLog"
+ fs = MockFileSystem({changelog_path: changelog_contents.encode("utf-8")})
+ changelog = ChangeLog(changelog_path, fs)
changelog.update_with_unreviewed_message(PrepareChangeLogForRevert._message_for_revert(*args))
actual_entry = changelog.latest_entry()
- os.remove(changelog_path)
- self.assertEqual(actual_entry.contents(), expected_entry)
- self.assertEqual(actual_entry.reviewer_text(), None)
+ self.assertMultiLineEqual(actual_entry.contents(), expected_entry)
+ self.assertIsNone(actual_entry.reviewer_text())
# These checks could be removed to allow this to work on other entries:
self.assertEqual(actual_entry.author_name(), "Eric Seidel")
self.assertEqual(actual_entry.author_email(), "eric@webkit.org")
diff --git a/Tools/Scripts/webkitpy/tool/steps/runtests.py b/Tools/Scripts/webkitpy/tool/steps/runtests.py
index 6dc90f92c..a45628b2d 100644
--- a/Tools/Scripts/webkitpy/tool/steps/runtests.py
+++ b/Tools/Scripts/webkitpy/tool/steps/runtests.py
@@ -1,9 +1,9 @@
# Copyright (C) 2010 Google Inc. All rights reserved.
-#
+#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
-#
+#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
@@ -13,7 +13,7 @@
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
-#
+#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -27,7 +27,9 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import logging
-
+import os
+import platform
+import sys
from webkitpy.tool.steps.abstractstep import AbstractStep
from webkitpy.tool.steps.options import Options
from webkitpy.common.system.executive import ScriptError
@@ -41,6 +43,7 @@ class RunTests(AbstractStep):
@classmethod
def options(cls):
return AbstractStep.options() + [
+ Options.build_style,
Options.test,
Options.non_interactive,
Options.quiet,
@@ -53,44 +56,59 @@ class RunTests(AbstractStep):
if not self._options.non_interactive:
# FIXME: We should teach the commit-queue and the EWS how to run these tests.
- python_unittests_command = self._tool.port().run_python_unittests_command()
+ python_unittests_command = self._tool.deprecated_port().run_python_unittests_command()
if python_unittests_command:
_log.info("Running Python unit tests")
self._tool.executive.run_and_throw_if_fail(python_unittests_command, cwd=self._tool.scm().checkout_root)
- perl_unittests_command = self._tool.port().run_perl_unittests_command()
+ perl_unittests_command = self._tool.deprecated_port().run_perl_unittests_command()
if perl_unittests_command:
_log.info("Running Perl unit tests")
self._tool.executive.run_and_throw_if_fail(perl_unittests_command, cwd=self._tool.scm().checkout_root)
- javascriptcore_tests_command = self._tool.port().run_javascriptcore_tests_command()
+ javascriptcore_tests_command = self._tool.deprecated_port().run_javascriptcore_tests_command()
if javascriptcore_tests_command:
_log.info("Running JavaScriptCore tests")
self._tool.executive.run_and_throw_if_fail(javascriptcore_tests_command, quiet=True, cwd=self._tool.scm().checkout_root)
- webkit_unit_tests_command = self._tool.port().run_webkit_unit_tests_command()
+ bindings_tests_command = self._tool.deprecated_port().run_bindings_tests_command()
+ if bindings_tests_command:
+ _log.info("Running bindings generation tests")
+ args = bindings_tests_command
+ try:
+ self._tool.executive.run_and_throw_if_fail(args, cwd=self._tool.scm().checkout_root)
+ except ScriptError, e:
+ _log.info("Error running run-bindings-tests: %s" % e.message_with_output())
+
+ webkit_unit_tests_command = self._tool.deprecated_port().run_webkit_unit_tests_command()
if webkit_unit_tests_command:
_log.info("Running WebKit unit tests")
args = webkit_unit_tests_command
- if self._options.non_interactive:
- args.append("--gtest_output=xml:%s/webkit_unit_tests_output.xml" % self._tool.port().results_directory)
try:
self._tool.executive.run_and_throw_if_fail(args, cwd=self._tool.scm().checkout_root)
except ScriptError, e:
_log.info("Error running webkit_unit_tests: %s" % e.message_with_output())
+
_log.info("Running run-webkit-tests")
- args = self._tool.port().run_webkit_tests_command()
+ args = self._tool.deprecated_port().run_webkit_tests_command()
if self._options.non_interactive:
args.extend([
"--no-new-test-results",
- "--no-launch-safari",
- "--skip-failing-tests",
+ "--no-show-results",
"--exit-after-n-failures=%s" % self.NON_INTERACTIVE_FAILURE_LIMIT_COUNT,
- "--results-directory=%s" % self._tool.port().results_directory,
- "--quiet",
])
+ # old-run-webkit-tests does not support --skip-failing-tests
+ # Using --quiet one Windows fails when we try to use /dev/null, disabling for now until we find a fix
+ if sys.platform != "cygwin":
+ args.append("--quiet")
+ args.append("--skip-failing-tests")
+ else:
+ args.append("--no-build");
+
if self._options.quiet:
args.append("--quiet")
+
self._tool.executive.run_and_throw_if_fail(args, cwd=self._tool.scm().checkout_root)
+
diff --git a/Tools/Scripts/webkitpy/tool/steps/runtests_unittest.py b/Tools/Scripts/webkitpy/tool/steps/runtests_unittest.py
index 78a867b36..ef8920e9b 100644
--- a/Tools/Scripts/webkitpy/tool/steps/runtests_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/steps/runtests_unittest.py
@@ -26,7 +26,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import unittest
+import platform
+import sys
+import unittest2 as unittest
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.tool.mocktool import MockOptions, MockTool
@@ -38,9 +40,22 @@ class RunTestsTest(unittest.TestCase):
tool._deprecated_port.run_python_unittests_command = lambda: None
tool._deprecated_port.run_perl_unittests_command = lambda: None
step = RunTests(tool, MockOptions(test=True, non_interactive=True, quiet=False))
- expected_logs = """Running WebKit unit tests
-MOCK run_and_throw_if_fail: ['mock-run-webkit-unit-tests', '--gtest_output=xml:/mock-results/webkit_unit_tests_output.xml'], cwd=/mock-checkout
+
+ if sys.platform != "cygwin":
+ expected_logs = """Running bindings generation tests
+MOCK run_and_throw_if_fail: ['mock-run-bindings-tests'], cwd=/mock-checkout
+Running WebKit unit tests
+MOCK run_and_throw_if_fail: ['mock-run-webkit-unit-tests'], cwd=/mock-checkout
+Running run-webkit-tests
+MOCK run_and_throw_if_fail: ['mock-run-webkit-tests', '--no-new-test-results', '--no-show-results', '--exit-after-n-failures=30', '--quiet', '--skip-failing-tests'], cwd=/mock-checkout
+"""
+ else:
+ expected_logs = """Running bindings generation tests
+MOCK run_and_throw_if_fail: ['mock-run-bindings-tests'], cwd=/mock-checkout
+Running WebKit unit tests
+MOCK run_and_throw_if_fail: ['mock-run-webkit-unit-tests'], cwd=/mock-checkout
Running run-webkit-tests
-MOCK run_and_throw_if_fail: ['mock-run-webkit-tests', '--no-new-test-results', '--no-launch-safari', '--skip-failing-tests', '--exit-after-n-failures=30', '--results-directory=/mock-results', '--quiet'], cwd=/mock-checkout
+MOCK run_and_throw_if_fail: ['mock-run-webkit-tests', '--no-new-test-results', '--no-show-results', '--exit-after-n-failures=30', '--no-build'], cwd=/mock-checkout
"""
+
OutputCapture().assert_outputs(self, step.run, [{}], expected_logs=expected_logs)
diff --git a/Tools/Scripts/webkitpy/tool/steps/steps_unittest.py b/Tools/Scripts/webkitpy/tool/steps/steps_unittest.py
index c4ea47b4d..7172ba7f5 100644
--- a/Tools/Scripts/webkitpy/tool/steps/steps_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/steps/steps_unittest.py
@@ -26,7 +26,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import unittest
+import unittest2 as unittest
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.common.config.ports import DeprecatedPort
@@ -99,10 +99,9 @@ class StepsTest(unittest.TestCase):
mock_options = self._step_options()
mock_options.non_interactive = False
step = steps.RunTests(MockTool(log_executive=True), mock_options)
- # FIXME: We shouldn't use a real port-object here, but there is too much to mock at the moment.
- mock_port = DeprecatedPort()
tool = MockTool(log_executive=True)
- tool.port = lambda: mock_port
+ # FIXME: We shouldn't use a real port-object here, but there is too much to mock at the moment.
+ tool._deprecated_port = DeprecatedPort()
step = steps.RunTests(tool, mock_options)
expected_logs = """Running Python unit tests
MOCK run_and_throw_if_fail: ['Tools/Scripts/test-webkitpy'], cwd=/mock-checkout
@@ -110,6 +109,8 @@ Running Perl unit tests
MOCK run_and_throw_if_fail: ['Tools/Scripts/test-webkitperl'], cwd=/mock-checkout
Running JavaScriptCore tests
MOCK run_and_throw_if_fail: ['Tools/Scripts/run-javascriptcore-tests'], cwd=/mock-checkout
+Running bindings generation tests
+MOCK run_and_throw_if_fail: ['Tools/Scripts/run-bindings-tests'], cwd=/mock-checkout
Running run-webkit-tests
MOCK run_and_throw_if_fail: ['Tools/Scripts/run-webkit-tests', '--quiet'], cwd=/mock-checkout
"""
diff --git a/Tools/Scripts/webkitpy/tool/steps/suggestreviewers.py b/Tools/Scripts/webkitpy/tool/steps/suggestreviewers.py
index 76bef35ac..40a24829b 100644
--- a/Tools/Scripts/webkitpy/tool/steps/suggestreviewers.py
+++ b/Tools/Scripts/webkitpy/tool/steps/suggestreviewers.py
@@ -42,9 +42,12 @@ class SuggestReviewers(AbstractStep):
if not self._options.suggest_reviewers:
return
- reviewers = self._tool.checkout().suggested_reviewers(self._options.git_commit, self._changed_files(state))
+ reviewers = self._tool.checkout().suggested_reviewers(self._options.git_commit, self._changed_files(state))[:5]
print "The following reviewers have recently modified files in your patch:"
- print "\n".join([reviewer.full_name for reviewer in reviewers])
+ print ", ".join([reviewer.full_name for reviewer in reviewers])
+
+ if not state.get('bug_id'):
+ return
if not self._tool.user.confirm("Would you like to CC them?"):
return
reviewer_emails = [reviewer.bugzilla_email() for reviewer in reviewers]
diff --git a/Tools/Scripts/webkitpy/tool/steps/suggestreviewers_unittest.py b/Tools/Scripts/webkitpy/tool/steps/suggestreviewers_unittest.py
index 42254c86b..fc096f118 100644
--- a/Tools/Scripts/webkitpy/tool/steps/suggestreviewers_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/steps/suggestreviewers_unittest.py
@@ -26,7 +26,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import unittest
+import unittest2 as unittest
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.tool.mocktool import MockOptions, MockTool
diff --git a/Tools/Scripts/webkitpy/tool/steps/update.py b/Tools/Scripts/webkitpy/tool/steps/update.py
index 0737ebcd0..f70354078 100644
--- a/Tools/Scripts/webkitpy/tool/steps/update.py
+++ b/Tools/Scripts/webkitpy/tool/steps/update.py
@@ -50,5 +50,5 @@ class Update(AbstractStep):
self._tool.executive.run_and_throw_if_fail(self._update_command(), quiet=self._options.quiet, cwd=self._tool.scm().checkout_root)
def _update_command(self):
- update_command = self._tool.port().update_webkit_command(self._options.non_interactive)
+ update_command = self._tool.deprecated_port().update_webkit_command(self._options.non_interactive)
return update_command
diff --git a/Tools/Scripts/webkitpy/tool/steps/update_unittest.py b/Tools/Scripts/webkitpy/tool/steps/update_unittest.py
index c1a934db5..49d6b4098 100644
--- a/Tools/Scripts/webkitpy/tool/steps/update_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/steps/update_unittest.py
@@ -26,9 +26,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import unittest
+import unittest2 as unittest
-from webkitpy.common.config.ports import ChromiumPort, ChromiumAndroidPort, ChromiumXVFBPort
+from webkitpy.common.config.ports import MacPort, MacWK2Port
from webkitpy.tool.mocktool import MockOptions, MockTool
from webkitpy.tool.steps.update import Update
@@ -41,14 +41,11 @@ class UpdateTest(unittest.TestCase):
step = Update(tool, options)
self.assertEqual(["mock-update-webkit"], step._update_command())
- tool._deprecated_port = ChromiumPort()
- self.assertEqual(["Tools/Scripts/update-webkit", "--chromium", "--force-update"], step._update_command())
+ tool._deprecated_port = MacPort()
+ self.assertEqual(["Tools/Scripts/update-webkit"], step._update_command())
- tool._deprecated_port = ChromiumXVFBPort()
- self.assertEqual(["Tools/Scripts/update-webkit", "--chromium", "--force-update"], step._update_command())
-
- tool._deprecated_port = ChromiumAndroidPort()
- self.assertEqual(["Tools/Scripts/update-webkit", "--chromium", "--force-update", "--chromium-android"], step._update_command())
+ tool._deprecated_port = MacWK2Port()
+ self.assertEqual(["Tools/Scripts/update-webkit"], step._update_command())
def test_update_command_interactive(self):
tool = MockTool()
@@ -56,11 +53,8 @@ class UpdateTest(unittest.TestCase):
step = Update(tool, options)
self.assertEqual(["mock-update-webkit"], step._update_command())
- tool._deprecated_port = ChromiumPort()
- self.assertEqual(["Tools/Scripts/update-webkit", "--chromium"], step._update_command())
-
- tool._deprecated_port = ChromiumXVFBPort()
- self.assertEqual(["Tools/Scripts/update-webkit", "--chromium"], step._update_command())
+ tool._deprecated_port = MacPort()
+ self.assertEqual(["Tools/Scripts/update-webkit"], step._update_command())
- tool._deprecated_port = ChromiumAndroidPort()
- self.assertEqual(["Tools/Scripts/update-webkit", "--chromium", "--chromium-android"], step._update_command())
+ tool._deprecated_port = MacWK2Port()
+ self.assertEqual(["Tools/Scripts/update-webkit"], step._update_command())
diff --git a/Tools/Scripts/webkitpy/tool/steps/updatechangelogswithreview_unittest.py b/Tools/Scripts/webkitpy/tool/steps/updatechangelogswithreview_unittest.py
index 3182cf3ab..d433e3f21 100644
--- a/Tools/Scripts/webkitpy/tool/steps/updatechangelogswithreview_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/steps/updatechangelogswithreview_unittest.py
@@ -26,7 +26,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import unittest
+import unittest2 as unittest
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.tool.mocktool import MockOptions, MockTool
diff --git a/Tools/Scripts/webkitpy/tool/steps/updatechromiumdeps.py b/Tools/Scripts/webkitpy/tool/steps/updatechromiumdeps.py
deleted file mode 100644
index 23d861bfc..000000000
--- a/Tools/Scripts/webkitpy/tool/steps/updatechromiumdeps.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright (C) 2011 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import logging
-import sys
-import urllib2
-
-from webkitpy.tool.steps.abstractstep import AbstractStep
-from webkitpy.tool.steps.options import Options
-from webkitpy.common.config import urls
-
-_log = logging.getLogger(__name__)
-
-
-class UpdateChromiumDEPS(AbstractStep):
- @classmethod
- def options(cls):
- return AbstractStep.options() + [
- Options.non_interactive,
- ]
-
- # Notice that this method throws lots of exciting exceptions!
- def _fetch_last_known_good_revision(self):
- return int(urllib2.urlopen(urls.chromium_lkgr_url).read())
-
- def _validate_revisions(self, current_chromium_revision, new_chromium_revision):
- if new_chromium_revision < current_chromium_revision:
- message = "Current Chromium DEPS revision %s is newer than %s." % (current_chromium_revision, new_chromium_revision)
- if self._options.non_interactive:
- _log.error(message)
- sys.exit(1)
- _log.info(message)
- new_chromium_revision = self._tool.user.prompt("Enter new chromium revision (enter nothing to cancel):\n")
- try:
- new_chromium_revision = int(new_chromium_revision)
- except ValueError, TypeError:
- new_chromium_revision = None
- if not new_chromium_revision:
- _log.error("Unable to update Chromium DEPS")
- sys.exit(1)
-
- def run(self, state):
- # Note that state["chromium_revision"] must be defined, but can be None.
- new_chromium_revision = state["chromium_revision"]
- if not new_chromium_revision:
- new_chromium_revision = self._fetch_last_known_good_revision()
-
- deps = self._tool.checkout().chromium_deps()
- current_chromium_revision = deps.read_variable("chromium_rev")
- self._validate_revisions(current_chromium_revision, new_chromium_revision)
- _log.info("Updating Chromium DEPS to %s" % new_chromium_revision)
- deps.write_variable("chromium_rev", new_chromium_revision)
diff --git a/Tools/Scripts/webkitpy/tool/steps/validatechangelogs.py b/Tools/Scripts/webkitpy/tool/steps/validatechangelogs.py
index 061baa5ec..e77e5c01e 100644
--- a/Tools/Scripts/webkitpy/tool/steps/validatechangelogs.py
+++ b/Tools/Scripts/webkitpy/tool/steps/validatechangelogs.py
@@ -29,6 +29,7 @@
import logging
import sys
+from optparse import make_option
from webkitpy.tool.steps.abstractstep import AbstractStep
from webkitpy.tool.steps.options import Options
from webkitpy.common.checkout.diff_parser import DiffParser
@@ -42,12 +43,11 @@ class ValidateChangeLogs(AbstractStep):
@classmethod
def options(cls):
return AbstractStep.options() + [
+ make_option("--check-oops", action="store_true", default=False, help="Check there are no OOPS left in change log"),
Options.non_interactive,
]
def _check_changelog_diff(self, diff_file):
- if not self._tool.checkout().is_path_to_changelog(diff_file.filename):
- return True
# Each line is a tuple, the first value is the deleted line number
# Date, reviewer, bug title, bug url, and empty lines could all be
# identical in the most recent entries. If the diff starts any
@@ -64,6 +64,12 @@ class ValidateChangeLogs(AbstractStep):
return True
return False
+ def _changelog_contains_oops(self, diff_file):
+ for diff_line in diff_file.lines:
+ if 'OOPS!' in diff_line[2]:
+ return True
+ return False
+
def run(self, state):
changed_files = self.cached_lookup(state, "changed_files")
for filename in changed_files:
@@ -76,6 +82,11 @@ class ValidateChangeLogs(AbstractStep):
diff = self._tool.scm().diff_for_file(filename)
parsed_diff = DiffParser(diff.splitlines())
for filename, diff_file in parsed_diff.files.items():
+ if not self._tool.checkout().is_path_to_changelog(diff_file.filename):
+ continue
if not self._check_changelog_diff(diff_file):
_log.error("ChangeLog entry in %s is not at the top of the file." % diff_file.filename)
sys.exit(1)
+ if self._options.check_oops and self._changelog_contains_oops(diff_file):
+ _log.error("ChangeLog entry in %s contains OOPS!." % diff_file.filename)
+ sys.exit(1)
diff --git a/Tools/Scripts/webkitpy/tool/steps/validatechangelogs_unittest.py b/Tools/Scripts/webkitpy/tool/steps/validatechangelogs_unittest.py
index c3b723ed1..50ecc4646 100644
--- a/Tools/Scripts/webkitpy/tool/steps/validatechangelogs_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/steps/validatechangelogs_unittest.py
@@ -26,7 +26,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import unittest
+import unittest2 as unittest
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.thirdparty.mock import Mock
@@ -38,7 +38,6 @@ class ValidateChangeLogsTest(unittest.TestCase):
def _assert_start_line_produces_output(self, start_line, should_fail=False, non_interactive=False):
tool = MockTool()
- tool._checkout.is_path_to_changelog = lambda path: True
step = ValidateChangeLogs(tool, MockOptions(git_commit=None, non_interactive=non_interactive))
diff_file = Mock()
diff_file.filename = "mock/ChangeLog"
@@ -56,3 +55,15 @@ class ValidateChangeLogsTest(unittest.TestCase):
self._assert_start_line_produces_output(1, non_interactive=False)
self._assert_start_line_produces_output(8, non_interactive=True, should_fail=True)
+
+ def test_changelog_contains_oops(self):
+ tool = MockTool()
+ tool._checkout.is_path_to_changelog = lambda path: True
+ step = ValidateChangeLogs(tool, MockOptions(git_commit=None, non_interactive=True, check_oops=True))
+ diff_file = Mock()
+ diff_file.filename = "mock/ChangeLog"
+ diff_file.lines = [(1, 1, "foo"), (2, 2, "bar OOPS! bar"), (3, 3, "foo")]
+ self.assertTrue(OutputCapture().assert_outputs(self, step._changelog_contains_oops, [diff_file], expected_logs=''))
+
+ diff_file.lines = [(1, 1, "foo"), (2, 2, "bar OOPS bar"), (3, 3, "foo")]
+ self.assertFalse(OutputCapture().assert_outputs(self, step._changelog_contains_oops, [diff_file], expected_logs=''))