Diff
Modified: trunk/Tools/ChangeLog (140673 => 140674)
--- trunk/Tools/ChangeLog 2013-01-24 11:48:09 UTC (rev 140673)
+++ trunk/Tools/ChangeLog 2013-01-24 12:19:37 UTC (rev 140674)
@@ -1,3 +1,50 @@
+2013-01-24 Tim 'mithro' Ansell <[email protected]>
+
+ Adding "has-landed" command to webkit-patch which compares a
+ committed patch to the changes which exist locally (ignoring the
+ ChangeLog file).
+
+ https://bugs.webkit.org/show_bug.cgi?id=106402
+
+ Reviewed by Eric Seidel.
+
+ * Scripts/webkitpy/common/checkout/diff_parser.py:
+ (git_diff_to_svn_diff):
+ * Scripts/webkitpy/common/net/bugzilla/bug.py:
+ (Bug.commit_revision):
+ * Scripts/webkitpy/common/net/bugzilla/bug_unittest.py:
+ (BugTest.test_is_in_comments):
+ (BugTest):
+ (BugTest.test_commit_revision):
+ * Scripts/webkitpy/tool/commands/upload.py:
+ (HasLanded):
+ * Scripts/webkitpy/tool/steps/__init__.py:
+ * Scripts/webkitpy/tool/steps/haslanded.py: Added.
+ (HasLanded):
+ (HasLanded.convert_to_svn):
+ (HasLanded.strip_change_log):
+ (run):
+
+ * Scripts/webkitpy/common/net/bugzilla/bug.py:
+ (Bug.commit_revision):
+ * Scripts/webkitpy/common/net/bugzilla/bug_unittest.py:
+ (BugTest.test_is_in_comments):
+ (BugTest):
+ (BugTest.test_commit_revision):
+ * Scripts/webkitpy/tool/commands/upload.py:
+ (HasLanded):
+ * Scripts/webkitpy/tool/steps/__init__.py:
+ * Scripts/webkitpy/tool/steps/haslanded.py: Added.
+ (HasLanded):
+ (HasLanded.convert_to_svn):
+ (HasLanded.strip_change_log):
+ (HasLanded.diff_diff):
+ (HasLanded.run):
+ * Scripts/webkitpy/tool/steps/haslanded_unittest.py: Added.
+ (HasLandedTest):
+ (HasLandedTest.test_run):
+ (test_convert_to_svn_and_strip_change_log):
+
2013-01-24 Dan Carney <[email protected]>
[chromium] move most WebViewHost printf calls to WebTestProxy
Modified: trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py (140673 => 140674)
--- trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py 2013-01-24 11:48:09 UTC (rev 140673)
+++ trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bug.py 2013-01-24 12:19:37 UTC (rev 140674)
@@ -28,6 +28,8 @@
# (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 re
+
from .attachment import Attachment
@@ -123,3 +125,12 @@
return True
return False
+ def commit_revision(self):
+ # Sort the comments in reverse order as we want the latest committed revision.
+ r = re.compile("Committed r(?P<svn_revision>\d+)")
+ for comment in sorted(self.comments(), reverse=True):
+ rev = r.search(comment['text'])
+ if rev:
+ return int(rev.group('svn_revision'))
+
+ return None
Modified: trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bug_unittest.py (140673 => 140674)
--- trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bug_unittest.py 2013-01-24 11:48:09 UTC (rev 140673)
+++ trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bug_unittest.py 2013-01-24 12:19:37 UTC (rev 140674)
@@ -45,3 +45,39 @@
bugzilla=None)
self.assertTrue(bug.is_in_comments("Message3."))
self.assertFalse(bug.is_in_comments("Message."))
+
+ def test_commit_revision(self):
+ bug = Bug({"comments": []}, bugzilla=None)
+ self.assertEqual(bug.commit_revision(), None)
+
+ bug = Bug({"comments": [
+ {"text": "Comment 1"},
+ {"text": "Comment 2"},
+ ]}, bugzilla=None)
+ self.assertEqual(bug.commit_revision(), None)
+
+ bug = Bug({"comments": [
+ {"text": "Committed r138776: <http://trac.webkit.org/changeset/138776>"},
+ ]}, bugzilla=None)
+ self.assertEqual(bug.commit_revision(), 138776)
+
+ bug = Bug({"comments": [
+ {"text": "(From update of attachment 181269) Clearing flags on attachment: 181269 Committed r138776: <http://trac.webkit.org/changeset/138776>"},
+ ]}, bugzilla=None)
+ self.assertEqual(bug.commit_revision(), 138776)
+
+ bug = Bug({"comments": [
+ {"text": "Comment before"},
+ {"text": "(From update of attachment 181269) Clearing flags on attachment: 181269 Committed r138776: <http://trac.webkit.org/changeset/138776>"},
+ {"text": "Comment after"},
+ ]}, bugzilla=None)
+ self.assertEqual(bug.commit_revision(), 138776)
+
+ bug = Bug({"comments": [
+ {"text": "Comment before"},
+ {"text": "(From update of attachment 181269) Clearing flags on attachment: 181269 Committed r138776: <http://trac.webkit.org/changeset/138776>"},
+ {"text": "Comment Middle"},
+ {"text": "(From update of attachment 181280) Clearing flags on attachment: 181280 Committed r138976: <http://trac.webkit.org/changeset/138976>"},
+ {"text": "Comment After"},
+ ]}, bugzilla=None)
+ self.assertEqual(bug.commit_revision(), 138976)
Modified: trunk/Tools/Scripts/webkitpy/tool/commands/upload.py (140673 => 140674)
--- trunk/Tools/Scripts/webkitpy/tool/commands/upload.py 2013-01-24 11:48:09 UTC (rev 140673)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/upload.py 2013-01-24 12:19:37 UTC (rev 140674)
@@ -241,6 +241,15 @@
]
+class HasLanded(AbstractPatchUploadingCommand):
+ name = "has-landed"
+ help_text = "Check that the current code was successfully landed and no changes remain."
+ argument_names = "[BUGID]"
+ steps = [
+ steps.HasLanded,
+ ]
+
+
class Prepare(AbstractSequencedCommand):
name = "prepare"
help_text = "Creates a bug (or prompts for an existing bug) and prepares the ChangeLogs"
Modified: trunk/Tools/Scripts/webkitpy/tool/steps/__init__.py (140673 => 140674)
--- trunk/Tools/Scripts/webkitpy/tool/steps/__init__.py 2013-01-24 11:48:09 UTC (rev 140673)
+++ trunk/Tools/Scripts/webkitpy/tool/steps/__init__.py 2013-01-24 12:19:37 UTC (rev 140674)
@@ -45,6 +45,7 @@
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
Added: trunk/Tools/Scripts/webkitpy/tool/steps/haslanded.py (0 => 140674)
--- trunk/Tools/Scripts/webkitpy/tool/steps/haslanded.py (rev 0)
+++ trunk/Tools/Scripts/webkitpy/tool/steps/haslanded.py 2013-01-24 12:19:37 UTC (rev 140674)
@@ -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[0])
+ 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()
Added: trunk/Tools/Scripts/webkitpy/tool/steps/haslanded_unittest.py (0 => 140674)
--- trunk/Tools/Scripts/webkitpy/tool/steps/haslanded_unittest.py (rev 0)
+++ trunk/Tools/Scripts/webkitpy/tool/steps/haslanded_unittest.py 2013-01-24 12:19:37 UTC (rev 140674)
@@ -0,0 +1,297 @@
+# 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
+
+from webkitpy.tool.steps.haslanded import HasLanded
+
+
+class HasLandedTest(unittest.TestCase):
+ maxDiff = None
+
+ 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 <[email protected]>
++
++ Adding "has-landed" command to webkit-patch which allows a person to
++ Reviewed by NOBODY (OOPS!).
++
+ 2013-01-20 Tim 'mithro' Ansell <[email protected]>
+
+ 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 <[email protected]>
++
++ Adding "has-landed" command to webkit-patch which allows a person to
++ Reviewed by NOBODY (OOPS!).
++
+ 2013-01-20 Tim 'mithro' Ansell <[email protected]>
+
+ 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 <[email protected]>
++
++ Adding "has-landed" command to webkit-patch which allows a person to
++ Reviewed by NOBODY (OOPS!).
++
+ 2013-01-20 Tim 'mithro' Ansell <[email protected]>
+
+ 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))