[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.17-1283-gcf603cf
abarth at webkit.org
abarth at webkit.org
Tue Jan 5 23:58:16 UTC 2010
The following commit has been merged in the webkit-1.1 branch:
commit 97deaa269a49f5c3675893b7273b5fb897f35ec2
Author: abarth at webkit.org <abarth at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Dec 22 06:46:57 2009 +0000
2009-12-21 Adam Barth <abarth at webkit.org>
Reviewed by Eric Seidel.
[bzt] Automate the process of calling prepare-ChangeLog
https://bugs.webkit.org/show_bug.cgi?id=32816
This patch automates the process of creating a bug and patch and
uploading it to bugzilla. The first cut just calls
prepare-ChangeLog.
This patch required some refactoring of upload.py to the Step
model, but that's worth doing anyway.
* Scripts/bugzilla-tool:
* Scripts/modules/buildsteps.py:
* Scripts/modules/commands/download.py:
* Scripts/modules/commands/upload.py:
* Scripts/modules/commands/upload_unittest.py:
* Scripts/modules/mock_bugzillatool.py:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index 39a2f51..78ba8d3 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,24 @@
+2009-12-21 Adam Barth <abarth at webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ [bzt] Automate the process of calling prepare-ChangeLog
+ https://bugs.webkit.org/show_bug.cgi?id=32816
+
+ This patch automates the process of creating a bug and patch and
+ uploading it to bugzilla. The first cut just calls
+ prepare-ChangeLog.
+
+ This patch required some refactoring of upload.py to the Step
+ model, but that's worth doing anyway.
+
+ * Scripts/bugzilla-tool:
+ * Scripts/modules/buildsteps.py:
+ * Scripts/modules/commands/download.py:
+ * Scripts/modules/commands/upload.py:
+ * Scripts/modules/commands/upload_unittest.py:
+ * Scripts/modules/mock_bugzillatool.py:
+
2009-12-21 Darin Adler <darin at apple.com>
* Scripts/do-webcore-rename: Did a rename, so checking in the
diff --git a/WebKitTools/Scripts/bugzilla-tool b/WebKitTools/Scripts/bugzilla-tool
index 2a6ae90..d3323ed 100755
--- a/WebKitTools/Scripts/bugzilla-tool
+++ b/WebKitTools/Scripts/bugzilla-tool
@@ -43,6 +43,8 @@ from modules.executive import Executive
from modules.logging import log
from modules.multicommandtool import MultiCommandTool
from modules.scm import detect_scm_system
+from modules.user import User
+
class BugzillaTool(MultiCommandTool):
def __init__(self):
@@ -53,6 +55,7 @@ class BugzillaTool(MultiCommandTool):
self.bugs = Bugzilla()
self.buildbot = BuildBot()
self.executive = Executive()
+ self.user = User()
self._scm = None
self.status_bot = StatusBot()
diff --git a/WebKitTools/Scripts/modules/buildsteps.py b/WebKitTools/Scripts/modules/buildsteps.py
index 0effc48..f8a35d1 100644
--- a/WebKitTools/Scripts/modules/buildsteps.py
+++ b/WebKitTools/Scripts/modules/buildsteps.py
@@ -27,6 +27,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
+import StringIO
from optparse import make_option
@@ -52,6 +53,10 @@ class CommandOptions(object):
port = make_option("--port", action="store", dest="port", default=None, help="Specify a port (e.g., mac, qt, gtk, ...).")
reviewer = make_option("-r", "--reviewer", action="store", type="string", dest="reviewer", help="Update ChangeLogs to say Reviewed by REVIEWER.")
complete_rollout = make_option("--complete-rollout", action="store_true", dest="complete_rollout", help="Commit the revert and re-open the original bug.")
+ obsolete_patches = make_option("--no-obsolete", action="store_false", dest="obsolete_patches", default=True, help="Do not obsolete old patches before posting this one.")
+ review = make_option("--no-review", action="store_false", dest="review", default=True, help="Do not mark the patch for review.")
+ request_commit = make_option("--request-commit", action="store_true", dest="request_commit", default=False, help="Mark the patch as needing auto-commit after review.")
+ description = make_option("-m", "--description", action="store", type="string", dest="description", help="Description string for the attachment (default: \"patch\")")
class AbstractStep(object):
@@ -62,6 +67,7 @@ class AbstractStep(object):
def _run_script(self, script_name, quiet=False, port=WebKitPort):
log("Running %s" % script_name)
+ # FIXME: This should use self.port()
self._tool.executive.run_and_throw_if_fail(port.script_path(script_name), quiet)
# FIXME: The port should live on the tool.
@@ -105,8 +111,59 @@ class MetaStep(AbstractStep):
class PrepareChangelogStep(AbstractStep):
+ @classmethod
+ def options(cls):
+ return [
+ CommandOptions.port,
+ CommandOptions.quiet,
+ CommandOptions.non_interactive,
+ ]
+
def run(self, state):
- self._run_script("prepare-ChangeLog")
+ os.chdir(self._tool.scm().checkout_root)
+ args = [self.port().script_path("prepare-ChangeLog")]
+ if not self._options.non_interactive:
+ args.append("-o")
+ if state["bug_id"]:
+ args.append("--bug=%s" % state["bug_id"])
+ self._tool.executive.run_and_throw_if_fail(args, self._options.quiet)
+ if not self._options.non_interactive:
+ self._tool.user.prompt("Press enter when ready to continue.")
+
+
+class ObsoletePatchesOnBugStep(AbstractStep):
+ @classmethod
+ def options(cls):
+ return [
+ CommandOptions.obsolete_patches,
+ ]
+
+ def run(self, state):
+ if not self._options.obsolete_patches:
+ return
+ bug_id = state["bug_id"]
+ patches = self._tool.bugs.fetch_patches_from_bug(bug_id)
+ if not patches:
+ return
+ log("Obsoleting %s on bug %s" % (pluralize("old patch", len(patches)), bug_id))
+ for patch in patches:
+ self._tool.bugs.obsolete_attachment(patch["id"])
+
+
+class PostDiffToBugStep(AbstractStep):
+ @classmethod
+ def options(cls):
+ return [
+ CommandOptions.description,
+ CommandOptions.review,
+ CommandOptions.request_commit,
+ ]
+
+ def run(self, state):
+ diff = self._tool.scm().create_patch()
+ diff_file = StringIO.StringIO(diff) # add_patch_to_bug expects a file-like object
+ description = self._options.description or "Patch"
+ self._tool.bugs.add_patch_to_bug(state["bug_id"], diff_file, description, mark_for_review=self._options.review, mark_for_commit_queue=self._options.request_commit)
class PrepareChangelogForRevertStep(AbstractStep):
diff --git a/WebKitTools/Scripts/modules/commands/download.py b/WebKitTools/Scripts/modules/commands/download.py
index b8fcb18..555c58d 100644
--- a/WebKitTools/Scripts/modules/commands/download.py
+++ b/WebKitTools/Scripts/modules/commands/download.py
@@ -52,6 +52,7 @@ class AbstractDeclarativeCommmand(Command):
Command.__init__(self, self.help_text, self.argument_names, options)
+# FIXME: Move this to a more general location.
class AbstractSequencedCommmand(AbstractDeclarativeCommmand):
steps = None
def __init__(self):
diff --git a/WebKitTools/Scripts/modules/commands/upload.py b/WebKitTools/Scripts/modules/commands/upload.py
index ef8ba1e..8f93130 100644
--- a/WebKitTools/Scripts/modules/commands/upload.py
+++ b/WebKitTools/Scripts/modules/commands/upload.py
@@ -36,6 +36,8 @@ import sys
from optparse import make_option
from modules.bugzilla import parse_bug_id
+from modules.buildsteps import PrepareChangelogStep, CommandOptions, ObsoletePatchesOnBugStep, PostDiffToBugStep
+from modules.commands.download import AbstractSequencedCommmand
from modules.comments import bug_comment_from_svn_revision
from modules.grammar import pluralize
from modules.logging import error, log
@@ -52,59 +54,50 @@ class CommitMessageForCurrentDiff(Command):
print "%s" % tool.scm().commit_message_for_this_commit().message()
-class ObsoleteAttachments(Command):
+class ObsoleteAttachments(AbstractSequencedCommmand):
name = "obsolete-attachments"
- def __init__(self):
- Command.__init__(self, "Mark all attachments on a bug as obsolete", "BUGID")
+ help_text = "Mark all attachments on a bug as obsolete"
+ argument_names = "BUGID"
+ steps = [
+ ObsoletePatchesOnBugStep,
+ ]
- def execute(self, options, args, tool):
- bug_id = args[0]
- attachments = tool.bugs.fetch_attachments_from_bug(bug_id)
- for attachment in attachments:
- if not attachment["is_obsolete"]:
- tool.bugs.obsolete_attachment(attachment["id"])
+ def _prepare_state(self, options, args, tool):
+ return { "bug_id" : args[0] }
-class PostDiff(Command):
+class PostDiff(AbstractSequencedCommmand):
name = "post-diff"
+ help_text = "Attach the current working directory diff to a bug as a patch file"
+ argument_names = "[BUGID]"
show_in_main_help = True
- def __init__(self):
- options = [
- make_option("-m", "--description", action="store", type="string", dest="description", help="Description string for the attachment (default: \"patch\")"),
- ]
- options += self.posting_options()
- Command.__init__(self, "Attach the current working directory diff to a bug as a patch file", "[BUGID]", options=options)
-
- @staticmethod
- def posting_options():
- return [
- make_option("--no-obsolete", action="store_false", dest="obsolete_patches", default=True, help="Do not obsolete old patches before posting this one."),
- make_option("--no-review", action="store_false", dest="review", default=True, help="Do not mark the patch for review."),
- make_option("--request-commit", action="store_true", dest="request_commit", default=False, help="Mark the patch as needing auto-commit after review."),
- ]
-
- @staticmethod
- def obsolete_patches_on_bug(bug_id, bugs):
- patches = bugs.fetch_patches_from_bug(bug_id)
- if len(patches):
- log("Obsoleting %s on bug %s" % (pluralize("old patch", len(patches)), bug_id))
- for patch in patches:
- bugs.obsolete_attachment(patch["id"])
+ steps = [
+ ObsoletePatchesOnBugStep,
+ PostDiffToBugStep,
+ ]
- def execute(self, options, args, tool):
+ def _prepare_state(self, options, args, tool):
# Perfer a bug id passed as an argument over a bug url in the diff (i.e. ChangeLogs).
bug_id = (args and args[0]) or parse_bug_id(tool.scm().create_patch())
if not bug_id:
error("No bug id passed and no bug url found in diff, can't post.")
+ return { "bug_id" : bug_id }
- if options.obsolete_patches:
- self.obsolete_patches_on_bug(bug_id, tool.bugs)
- diff = tool.scm().create_patch()
- diff_file = StringIO.StringIO(diff) # add_patch_to_bug expects a file-like object
+class SubmitPatch(AbstractSequencedCommmand):
+ name = "submit-patch"
+ help_text = "Experimental. Creates a patch from the current working copy and uploads bugzilla"
+ argument_names = "BUGID"
+ steps = [
+ PrepareChangelogStep,
+ # FIXME: Add a CreateBugStep!
+ ObsoletePatchesOnBugStep,
+ PostDiffToBugStep,
+ ]
- description = options.description or "Patch"
- tool.bugs.add_patch_to_bug(bug_id, diff_file, description, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)
+ def _prepare_state(self, options, args, tool):
+ bug_id = args[0]
+ return { "bug_id" : bug_id }
class PostCommits(Command):
@@ -115,8 +108,10 @@ class PostCommits(Command):
make_option("-b", "--bug-id", action="store", type="string", dest="bug_id", help="Specify bug id if no URL is provided in the commit log."),
make_option("--add-log-as-comment", action="store_true", dest="add_log_as_comment", default=False, help="Add commit log message as a comment when uploading the patch."),
make_option("-m", "--description", action="store", type="string", dest="description", help="Description string for the attachment (default: description from commit message)"),
+ CommandOptions.obsolete_patches,
+ CommandOptions.review,
+ CommandOptions.request_commit,
]
- options += PostDiff.posting_options()
Command.__init__(self, "Attach a range of local commits to bugs as patch files", "COMMITISH", options=options, requires_local_commits=True)
def _comment_text_for_commit(self, options, commit_message, tool, commit_id):
@@ -147,7 +142,8 @@ class PostCommits(Command):
continue
if options.obsolete_patches and bug_id not in have_obsoleted_patches:
- PostDiff.obsolete_patches_on_bug(bug_id, tool.bugs)
+ state = { "bug_id": bug_id }
+ ObsoletePatchesOnBugStep(tool, options).run(state)
have_obsoleted_patches.add(bug_id)
diff_file = self._diff_file_for_commit(tool, commit_id)
diff --git a/WebKitTools/Scripts/modules/commands/upload_unittest.py b/WebKitTools/Scripts/modules/commands/upload_unittest.py
index e206d10..ff7371f 100644
--- a/WebKitTools/Scripts/modules/commands/upload_unittest.py
+++ b/WebKitTools/Scripts/modules/commands/upload_unittest.py
@@ -33,8 +33,13 @@ from modules.commands.upload import *
class UploadCommandsTest(CommandsTest):
def test_obsolete_attachments(self):
- self.assert_execute_outputs(ObsoleteAttachments(), [42])
+ expected_stderr = "Obsoleting 2 old patches on bug 42\n"
+ self.assert_execute_outputs(ObsoleteAttachments(), [42], expected_stderr=expected_stderr)
def test_post_diff(self):
expected_stderr = "Obsoleting 2 old patches on bug 42\n"
self.assert_execute_outputs(PostDiff(), [42], expected_stderr=expected_stderr)
+
+ def test_submit_patch(self):
+ expected_stderr = "Obsoleting 2 old patches on bug 42\n"
+ self.assert_execute_outputs(SubmitPatch(), [42], expected_stderr=expected_stderr)
diff --git a/WebKitTools/Scripts/modules/mock_bugzillatool.py b/WebKitTools/Scripts/modules/mock_bugzillatool.py
index 351398f..29a4f05 100644
--- a/WebKitTools/Scripts/modules/mock_bugzillatool.py
+++ b/WebKitTools/Scripts/modules/mock_bugzillatool.py
@@ -108,6 +108,7 @@ class MockBuildBot(Mock):
def red_core_builders_names(self):
return []
+
class MockSCM(Mock):
def __init__(self):
Mock.__init__(self)
@@ -142,6 +143,11 @@ class MockSCM(Mock):
return []
+class MockUser(object):
+ def prompt(self, message):
+ return "Mock user response"
+
+
class MockStatusBot(object):
def __init__(self):
self.statusbot_host = "example.com"
@@ -158,6 +164,7 @@ class MockBugzillaTool():
self.bugs = MockBugzilla()
self.buildbot = MockBuildBot()
self.executive = Mock()
+ self.user = MockUser()
self._scm = MockSCM()
self.status_bot = MockStatusBot()
diff --git a/WebKitTools/Scripts/modules/user.py b/WebKitTools/Scripts/modules/user.py
new file mode 100644
index 0000000..1b023f4
--- /dev/null
+++ b/WebKitTools/Scripts/modules/user.py
@@ -0,0 +1,31 @@
+# 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.
+
+class User(object):
+ def prompt(self, message):
+ return raw_input(message)
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list