summaryrefslogtreecommitdiffstats
path: root/WebKitTools/Scripts/webkitpy/commands
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-04-27 16:31:00 +0100
committerSteve Block <steveblock@google.com>2010-05-11 14:42:12 +0100
commitdcc8cf2e65d1aa555cce12431a16547e66b469ee (patch)
tree92a8d65cd5383bca9749f5327fb5e440563926e6 /WebKitTools/Scripts/webkitpy/commands
parentccac38a6b48843126402088a309597e682f40fe6 (diff)
downloadexternal_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.zip
external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.gz
external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.bz2
Merge webkit.org at r58033 : Initial merge by git
Change-Id: If006c38561af287c50cd578d251629b51e4d8cd1
Diffstat (limited to 'WebKitTools/Scripts/webkitpy/commands')
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/__init__.py1
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/abstractsequencedcommand.py43
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/commandtest.py38
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/download.py284
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/download_unittest.py127
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/early_warning_system.py122
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/early_warning_system_unittest.py62
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/openbugs.py63
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/openbugs_unittest.py50
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/queries.py116
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/queries_unittest.py63
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/queues.py295
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/queues_unittest.py102
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/queuestest.py99
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/upload.py447
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/upload_unittest.py87
16 files changed, 0 insertions, 1999 deletions
diff --git a/WebKitTools/Scripts/webkitpy/commands/__init__.py b/WebKitTools/Scripts/webkitpy/commands/__init__.py
deleted file mode 100644
index ef65bee..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# Required for Python to search this directory for module files
diff --git a/WebKitTools/Scripts/webkitpy/commands/abstractsequencedcommand.py b/WebKitTools/Scripts/webkitpy/commands/abstractsequencedcommand.py
deleted file mode 100644
index 53af5b1..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/abstractsequencedcommand.py
+++ /dev/null
@@ -1,43 +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.multicommandtool import AbstractDeclarativeCommand
-from webkitpy.stepsequence import StepSequence
-
-
-class AbstractSequencedCommand(AbstractDeclarativeCommand):
- steps = None
- def __init__(self):
- self._sequence = StepSequence(self.steps)
- AbstractDeclarativeCommand.__init__(self, self._sequence.options())
-
- def _prepare_state(self, options, args, tool):
- return None
-
- def execute(self, options, args, tool):
- self._sequence.run_and_handle_errors(tool, options, self._prepare_state(options, args, tool))
diff --git a/WebKitTools/Scripts/webkitpy/commands/commandtest.py b/WebKitTools/Scripts/webkitpy/commands/commandtest.py
deleted file mode 100644
index a56cb05..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/commandtest.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# 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 unittest
-
-from webkitpy.mock import Mock
-from webkitpy.mock_bugzillatool import MockBugzillaTool
-from webkitpy.outputcapture import OutputCapture
-
-class CommandsTest(unittest.TestCase):
- def assert_execute_outputs(self, command, args, expected_stdout="", expected_stderr="", options=Mock(), tool=MockBugzillaTool()):
- command.bind_to_tool(tool)
- OutputCapture().assert_outputs(self, command.execute, [options, args, tool], expected_stdout=expected_stdout, expected_stderr=expected_stderr)
diff --git a/WebKitTools/Scripts/webkitpy/commands/download.py b/WebKitTools/Scripts/webkitpy/commands/download.py
deleted file mode 100644
index 49a6862..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/download.py
+++ /dev/null
@@ -1,284 +0,0 @@
-# Copyright (c) 2009, Google Inc. All rights reserved.
-# Copyright (c) 2009 Apple 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 os
-
-from optparse import make_option
-
-import webkitpy.steps as steps
-
-from webkitpy.bugzilla import parse_bug_id
-# We could instead use from modules import buildsteps and then prefix every buildstep with "buildsteps."
-from webkitpy.changelogs import ChangeLog
-from webkitpy.commands.abstractsequencedcommand import AbstractSequencedCommand
-from webkitpy.comments import bug_comment_from_commit_text
-from webkitpy.executive import ScriptError
-from webkitpy.grammar import pluralize
-from webkitpy.webkit_logging import error, log
-from webkitpy.multicommandtool import AbstractDeclarativeCommand
-from webkitpy.stepsequence import StepSequence
-
-
-class Build(AbstractSequencedCommand):
- name = "build"
- help_text = "Update working copy and build"
- steps = [
- steps.CleanWorkingDirectory,
- steps.Update,
- steps.Build,
- ]
-
-
-class BuildAndTest(AbstractSequencedCommand):
- name = "build-and-test"
- help_text = "Update working copy, build, and run the tests"
- steps = [
- steps.CleanWorkingDirectory,
- steps.Update,
- steps.Build,
- steps.RunTests,
- ]
-
-
-class Land(AbstractSequencedCommand):
- name = "land"
- help_text = "Land the current working directory diff and updates the associated bug if any"
- argument_names = "[BUGID]"
- show_in_main_help = True
- steps = [
- steps.EnsureBuildersAreGreen,
- steps.UpdateChangeLogsWithReviewer,
- steps.EnsureBuildersAreGreen,
- steps.Build,
- steps.RunTests,
- steps.Commit,
- steps.CloseBugForLandDiff,
- ]
- long_help = """land commits the current working copy diff (just as svn or git commit would).
-land will build and run the tests before committing.
-If a bug id is provided, or one can be found in the ChangeLog land will update the bug after committing."""
-
- def _prepare_state(self, options, args, tool):
- return {
- "bug_id" : (args and args[0]) or parse_bug_id(tool.scm().create_patch()),
- }
-
-
-class AbstractPatchProcessingCommand(AbstractDeclarativeCommand):
- # Subclasses must implement the methods below. We don't declare them here
- # because we want to be able to implement them with mix-ins.
- #
- # def _fetch_list_of_patches_to_process(self, options, args, tool):
- # def _prepare_to_process(self, options, args, tool):
-
- @staticmethod
- def _collect_patches_by_bug(patches):
- bugs_to_patches = {}
- for patch in patches:
- bugs_to_patches[patch.bug_id()] = bugs_to_patches.get(patch.bug_id(), []) + [patch]
- return bugs_to_patches
-
- def execute(self, options, args, tool):
- self._prepare_to_process(options, args, tool)
- patches = self._fetch_list_of_patches_to_process(options, args, tool)
-
- # It's nice to print out total statistics.
- bugs_to_patches = self._collect_patches_by_bug(patches)
- log("Processing %s from %s." % (pluralize("patch", len(patches)), pluralize("bug", len(bugs_to_patches))))
-
- for patch in patches:
- self._process_patch(patch, options, args, tool)
-
-
-class AbstractPatchSequencingCommand(AbstractPatchProcessingCommand):
- prepare_steps = None
- main_steps = None
-
- def __init__(self):
- options = []
- self._prepare_sequence = StepSequence(self.prepare_steps)
- self._main_sequence = StepSequence(self.main_steps)
- options = sorted(set(self._prepare_sequence.options() + self._main_sequence.options()))
- AbstractPatchProcessingCommand.__init__(self, options)
-
- def _prepare_to_process(self, options, args, tool):
- self._prepare_sequence.run_and_handle_errors(tool, options)
-
- def _process_patch(self, patch, options, args, tool):
- state = { "patch" : patch }
- self._main_sequence.run_and_handle_errors(tool, options, state)
-
-
-class ProcessAttachmentsMixin(object):
- def _fetch_list_of_patches_to_process(self, options, args, tool):
- return map(lambda patch_id: tool.bugs.fetch_attachment(patch_id), args)
-
-
-class ProcessBugsMixin(object):
- def _fetch_list_of_patches_to_process(self, options, args, tool):
- all_patches = []
- for bug_id in args:
- patches = tool.bugs.fetch_bug(bug_id).reviewed_patches()
- log("%s found on bug %s." % (pluralize("reviewed patch", len(patches)), bug_id))
- all_patches += patches
- return all_patches
-
-
-class CheckStyle(AbstractPatchSequencingCommand, ProcessAttachmentsMixin):
- name = "check-style"
- help_text = "Run check-webkit-style on the specified attachments"
- argument_names = "ATTACHMENT_ID [ATTACHMENT_IDS]"
- main_steps = [
- steps.CleanWorkingDirectory,
- steps.Update,
- steps.ApplyPatch,
- steps.CheckStyle,
- ]
-
-
-class BuildAttachment(AbstractPatchSequencingCommand, ProcessAttachmentsMixin):
- name = "build-attachment"
- help_text = "Apply and build patches from bugzilla"
- argument_names = "ATTACHMENT_ID [ATTACHMENT_IDS]"
- main_steps = [
- steps.CleanWorkingDirectory,
- steps.Update,
- steps.ApplyPatch,
- steps.Build,
- ]
-
-
-class AbstractPatchApplyingCommand(AbstractPatchSequencingCommand):
- prepare_steps = [
- steps.EnsureLocalCommitIfNeeded,
- steps.CleanWorkingDirectoryWithLocalCommits,
- steps.Update,
- ]
- main_steps = [
- steps.ApplyPatchWithLocalCommit,
- ]
- long_help = """Updates the working copy.
-Downloads and applies the patches, creating local commits if necessary."""
-
-
-class ApplyAttachment(AbstractPatchApplyingCommand, ProcessAttachmentsMixin):
- name = "apply-attachment"
- help_text = "Apply an attachment to the local working directory"
- argument_names = "ATTACHMENT_ID [ATTACHMENT_IDS]"
- show_in_main_help = True
-
-
-class ApplyFromBug(AbstractPatchApplyingCommand, ProcessBugsMixin):
- name = "apply-from-bug"
- help_text = "Apply reviewed patches from provided bugs to the local working directory"
- argument_names = "BUGID [BUGIDS]"
- show_in_main_help = True
-
-
-class AbstractPatchLandingCommand(AbstractPatchSequencingCommand):
- prepare_steps = [
- steps.EnsureBuildersAreGreen,
- ]
- main_steps = [
- steps.CleanWorkingDirectory,
- steps.Update,
- steps.ApplyPatch,
- steps.EnsureBuildersAreGreen,
- steps.Build,
- steps.RunTests,
- steps.Commit,
- steps.ClosePatch,
- steps.CloseBug,
- ]
- long_help = """Checks to make sure builders are green.
-Updates the working copy.
-Applies the patch.
-Builds.
-Runs the layout tests.
-Commits the patch.
-Clears the flags on the patch.
-Closes the bug if no patches are marked for review."""
-
-
-class LandAttachment(AbstractPatchLandingCommand, ProcessAttachmentsMixin):
- name = "land-attachment"
- help_text = "Land patches from bugzilla, optionally building and testing them first"
- argument_names = "ATTACHMENT_ID [ATTACHMENT_IDS]"
- show_in_main_help = True
-
-
-class LandFromBug(AbstractPatchLandingCommand, ProcessBugsMixin):
- name = "land-from-bug"
- help_text = "Land all patches on the given bugs, optionally building and testing them first"
- argument_names = "BUGID [BUGIDS]"
- show_in_main_help = True
-
-
-class Rollout(AbstractSequencedCommand):
- name = "rollout"
- show_in_main_help = True
- help_text = "Revert the given revision in the working copy and optionally commit the revert and re-open the original bug"
- argument_names = "REVISION REASON"
- long_help = """Updates the working copy.
-Applies the inverse diff for the provided revision.
-Creates an appropriate rollout ChangeLog, including a trac link and bug link.
-Opens the generated ChangeLogs in $EDITOR.
-Shows the prepared diff for confirmation.
-Commits the revert and updates the bug (including re-opening the bug if necessary)."""
- steps = [
- steps.CleanWorkingDirectory,
- steps.Update,
- steps.RevertRevision,
- steps.PrepareChangeLogForRevert,
- steps.EditChangeLog,
- steps.ConfirmDiff,
- steps.CompleteRollout,
- ]
-
- @staticmethod
- def _parse_bug_id_from_revision_diff(tool, revision):
- original_diff = tool.scm().diff_for_revision(revision)
- return parse_bug_id(original_diff)
-
- def execute(self, options, args, tool):
- revision = args[0]
- reason = args[1]
- bug_id = self._parse_bug_id_from_revision_diff(tool, revision)
- if options.complete_rollout:
- if bug_id:
- log("Will re-open bug %s after rollout." % bug_id)
- else:
- log("Failed to parse bug number from diff. No bugs will be updated/reopened after the rollout.")
-
- state = {
- "revision" : revision,
- "bug_id" : bug_id,
- "reason" : reason,
- }
- self._sequence.run_and_handle_errors(tool, options, state)
diff --git a/WebKitTools/Scripts/webkitpy/commands/download_unittest.py b/WebKitTools/Scripts/webkitpy/commands/download_unittest.py
deleted file mode 100644
index f60c5b8..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/download_unittest.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# 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.
-
-from webkitpy.commands.commandtest import CommandsTest
-from webkitpy.commands.download import *
-from webkitpy.mock import Mock
-
-class DownloadCommandsTest(CommandsTest):
- def _default_options(self):
- options = Mock()
- options.force_clean = False
- options.clean = True
- options.check_builders = True
- options.quiet = False
- options.non_interactive = False
- options.update = True
- options.build = True
- options.test = True
- options.close_bug = True
- options.complete_rollout = False
- return options
-
- def test_build(self):
- expected_stderr = "Updating working directory\nBuilding WebKit\n"
- self.assert_execute_outputs(Build(), [], options=self._default_options(), expected_stderr=expected_stderr)
-
- def test_build_and_test(self):
- expected_stderr = "Updating working directory\nBuilding WebKit\nRunning Python unit tests\nRunning Perl unit tests\nRunning JavaScriptCore tests\nRunning run-webkit-tests\n"
- self.assert_execute_outputs(BuildAndTest(), [], options=self._default_options(), expected_stderr=expected_stderr)
-
- def test_apply_attachment(self):
- options = self._default_options()
- options.update = True
- options.local_commit = True
- expected_stderr = "Updating working directory\nProcessing 1 patch from 1 bug.\nProcessing patch 197 from bug 42.\n"
- self.assert_execute_outputs(ApplyAttachment(), [197], options=options, expected_stderr=expected_stderr)
-
- def test_apply_patches(self):
- options = self._default_options()
- options.update = True
- options.local_commit = True
- expected_stderr = "Updating working directory\n2 reviewed patches found on bug 42.\nProcessing 2 patches from 1 bug.\nProcessing patch 197 from bug 42.\nProcessing patch 128 from bug 42.\n"
- self.assert_execute_outputs(ApplyFromBug(), [42], options=options, expected_stderr=expected_stderr)
-
- def test_land_diff(self):
- expected_stderr = "Building WebKit\nRunning Python unit tests\nRunning Perl unit tests\nRunning JavaScriptCore tests\nRunning run-webkit-tests\nUpdating bug 42\n"
- self.assert_execute_outputs(Land(), [42], options=self._default_options(), expected_stderr=expected_stderr)
-
- def test_check_style(self):
- expected_stderr = "Processing 1 patch from 1 bug.\nUpdating working directory\nProcessing patch 197 from bug 42.\nRunning check-webkit-style\n"
- self.assert_execute_outputs(CheckStyle(), [197], options=self._default_options(), expected_stderr=expected_stderr)
-
- def test_build_attachment(self):
- expected_stderr = "Processing 1 patch from 1 bug.\nUpdating working directory\nProcessing patch 197 from bug 42.\nBuilding WebKit\n"
- self.assert_execute_outputs(BuildAttachment(), [197], options=self._default_options(), expected_stderr=expected_stderr)
-
- def test_land_attachment(self):
- # FIXME: This expected result is imperfect, notice how it's seeing the same patch as still there after it thought it would have cleared the flags.
- expected_stderr = """Processing 1 patch from 1 bug.
-Updating working directory
-Processing patch 197 from bug 42.
-Building WebKit
-Running Python unit tests
-Running Perl unit tests
-Running JavaScriptCore tests
-Running run-webkit-tests
-Not closing bug 42 as attachment 197 has review=+. Assuming there are more patches to land from this bug.
-"""
- self.assert_execute_outputs(LandAttachment(), [197], options=self._default_options(), expected_stderr=expected_stderr)
-
- def test_land_patches(self):
- # FIXME: This expected result is imperfect, notice how it's seeing the same patch as still there after it thought it would have cleared the flags.
- expected_stderr = """2 reviewed patches found on bug 42.
-Processing 2 patches from 1 bug.
-Updating working directory
-Processing patch 197 from bug 42.
-Building WebKit
-Running Python unit tests
-Running Perl unit tests
-Running JavaScriptCore tests
-Running run-webkit-tests
-Not closing bug 42 as attachment 197 has review=+. Assuming there are more patches to land from this bug.
-Updating working directory
-Processing patch 128 from bug 42.
-Building WebKit
-Running Python unit tests
-Running Perl unit tests
-Running JavaScriptCore tests
-Running run-webkit-tests
-Not closing bug 42 as attachment 197 has review=+. Assuming there are more patches to land from this bug.
-"""
- self.assert_execute_outputs(LandFromBug(), [42], options=self._default_options(), expected_stderr=expected_stderr)
-
- def test_rollout(self):
- expected_stderr = "Updating working directory\nRunning prepare-ChangeLog\n\nNOTE: Rollout support is experimental.\nPlease verify the rollout diff and use \"webkit-patch land 12345\" to commit the rollout.\n"
- self.assert_execute_outputs(Rollout(), [852, "Reason"], options=self._default_options(), expected_stderr=expected_stderr)
-
- def test_complete_rollout(self):
- options = self._default_options()
- options.complete_rollout = True
- expected_stderr = "Will re-open bug 12345 after rollout.\nUpdating working directory\nRunning prepare-ChangeLog\nBuilding WebKit\n"
- self.assert_execute_outputs(Rollout(), [852, "Reason"], options=options, expected_stderr=expected_stderr)
diff --git a/WebKitTools/Scripts/webkitpy/commands/early_warning_system.py b/WebKitTools/Scripts/webkitpy/commands/early_warning_system.py
deleted file mode 100644
index e3e14dd..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/early_warning_system.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-from StringIO import StringIO
-
-from webkitpy.commands.queues import AbstractReviewQueue
-from webkitpy.committers import CommitterList
-from webkitpy.executive import ScriptError
-from webkitpy.webkitport import WebKitPort
-from webkitpy.queueengine import QueueEngine
-
-
-class AbstractEarlyWarningSystem(AbstractReviewQueue):
- _build_style = "release"
-
- def __init__(self):
- AbstractReviewQueue.__init__(self)
- self.port = WebKitPort.port(self.port_name)
-
- def should_proceed_with_work_item(self, patch):
- try:
- self.run_webkit_patch([
- "build",
- self.port.flag(),
- "--build-style=%s" % self._build_style,
- "--force-clean",
- "--quiet"])
- self._update_status("Building", patch)
- except ScriptError, e:
- self._update_status("Unable to perform a build")
- return False
- return True
-
- def _review_patch(self, patch):
- self.run_webkit_patch([
- "build-attachment",
- self.port.flag(),
- "--build-style=%s" % self._build_style,
- "--force-clean",
- "--quiet",
- "--non-interactive",
- "--parent-command=%s" % self.name,
- "--no-update",
- patch.id()])
-
- @classmethod
- def handle_script_error(cls, tool, state, script_error):
- is_svn_apply = script_error.command_name() == "svn-apply"
- status_id = cls._update_status_for_script_error(tool, state, script_error, is_error=is_svn_apply)
- if is_svn_apply:
- QueueEngine.exit_after_handled_error(script_error)
- results_link = tool.status_server.results_url_for_status(status_id)
- message = "Attachment %s did not build on %s:\nBuild output: %s" % (state["patch"].id(), cls.port_name, results_link)
- tool.bugs.post_comment_to_bug(state["patch"].bug_id(), message, cc=cls.watchers)
- exit(1)
-
-
-class GtkEWS(AbstractEarlyWarningSystem):
- name = "gtk-ews"
- port_name = "gtk"
- watchers = AbstractEarlyWarningSystem.watchers + [
- "gns@gnome.org",
- "xan.lopez@gmail.com",
- ]
-
-
-class QtEWS(AbstractEarlyWarningSystem):
- name = "qt-ews"
- port_name = "qt"
-
-
-class ChromiumEWS(AbstractEarlyWarningSystem):
- name = "chromium-ews"
- port_name = "chromium"
- watchers = AbstractEarlyWarningSystem.watchers + [
- "dglazkov@chromium.org",
- ]
-
-
-# For platforms that we can't run inside a VM (like Mac OS X), we require
-# patches to be uploaded by committers, who are generally trustworthy folk. :)
-class AbstractCommitterOnlyEWS(AbstractEarlyWarningSystem):
- def __init__(self, committers=CommitterList()):
- AbstractEarlyWarningSystem.__init__(self)
- self._committers = committers
-
- def process_work_item(self, patch):
- if not self._committers.committer_by_email(patch.attacher_email()):
- self._did_error(patch, "%s cannot process patches from non-committers :(" % self.name)
- return
- AbstractEarlyWarningSystem.process_work_item(self, patch)
-
-
-class MacEWS(AbstractCommitterOnlyEWS):
- name = "mac-ews"
- port_name = "mac"
diff --git a/WebKitTools/Scripts/webkitpy/commands/early_warning_system_unittest.py b/WebKitTools/Scripts/webkitpy/commands/early_warning_system_unittest.py
deleted file mode 100644
index d516b84..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/early_warning_system_unittest.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# 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 os
-
-from webkitpy.commands.early_warning_system import *
-from webkitpy.commands.queuestest import QueuesTest
-from webkitpy.mock import Mock
-
-class EarlyWarningSytemTest(QueuesTest):
- def test_chromium_ews(self):
- expected_stderr = {
- "begin_work_queue" : "CAUTION: chromium-ews will discard all local changes in \"%s\"\nRunning WebKit chromium-ews.\n" % os.getcwd(),
- "handle_unexpected_error" : "Mock error message\n",
- }
- self.assert_queue_outputs(ChromiumEWS(), expected_stderr=expected_stderr)
-
- def test_qt_ews(self):
- expected_stderr = {
- "begin_work_queue" : "CAUTION: qt-ews will discard all local changes in \"%s\"\nRunning WebKit qt-ews.\n" % os.getcwd(),
- "handle_unexpected_error" : "Mock error message\n",
- }
- self.assert_queue_outputs(QtEWS(), expected_stderr=expected_stderr)
-
- def test_gtk_ews(self):
- expected_stderr = {
- "begin_work_queue" : "CAUTION: gtk-ews will discard all local changes in \"%s\"\nRunning WebKit gtk-ews.\n" % os.getcwd(),
- "handle_unexpected_error" : "Mock error message\n",
- }
- self.assert_queue_outputs(GtkEWS(), expected_stderr=expected_stderr)
-
- def test_mac_ews(self):
- expected_stderr = {
- "begin_work_queue" : "CAUTION: mac-ews will discard all local changes in \"%s\"\nRunning WebKit mac-ews.\n" % os.getcwd(),
- "handle_unexpected_error" : "Mock error message\n",
- }
- self.assert_queue_outputs(MacEWS(), expected_stderr=expected_stderr)
diff --git a/WebKitTools/Scripts/webkitpy/commands/openbugs.py b/WebKitTools/Scripts/webkitpy/commands/openbugs.py
deleted file mode 100644
index 25bdefc..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/openbugs.py
+++ /dev/null
@@ -1,63 +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.
-
-import re
-import sys
-
-from webkitpy.multicommandtool import AbstractDeclarativeCommand
-from webkitpy.webkit_logging import log
-
-
-class OpenBugs(AbstractDeclarativeCommand):
- name = "open-bugs"
- help_text = "Finds all bug numbers passed in arguments (or stdin if no args provided) and opens them in a web browser"
-
- bug_number_regexp = re.compile(r"\b\d{4,6}\b")
-
- def _open_bugs(self, bug_ids):
- for bug_id in bug_ids:
- bug_url = self.tool.bugs.bug_url_for_bug_id(bug_id)
- self.tool.user.open_url(bug_url)
-
- # _find_bugs_in_string mostly exists for easy unit testing.
- def _find_bugs_in_string(self, string):
- return self.bug_number_regexp.findall(string)
-
- def _find_bugs_in_iterable(self, iterable):
- return sum([self._find_bugs_in_string(string) for string in iterable], [])
-
- def execute(self, options, args, tool):
- if args:
- bug_ids = self._find_bugs_in_iterable(args)
- else:
- # This won't open bugs until stdin is closed but could be made to easily. That would just make unit testing slightly harder.
- bug_ids = self._find_bugs_in_iterable(sys.stdin)
-
- log("%s bugs found in input." % len(bug_ids))
-
- self._open_bugs(bug_ids)
diff --git a/WebKitTools/Scripts/webkitpy/commands/openbugs_unittest.py b/WebKitTools/Scripts/webkitpy/commands/openbugs_unittest.py
deleted file mode 100644
index 71fefd2..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/openbugs_unittest.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# 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.
-
-from webkitpy.commands.commandtest import CommandsTest
-from webkitpy.commands.openbugs import OpenBugs
-
-class OpenBugsTest(CommandsTest):
-
- find_bugs_in_string_expectations = [
- ["123", []],
- ["1234", ["1234"]],
- ["12345", ["12345"]],
- ["123456", ["123456"]],
- ["1234567", []],
- [" 123456 234567", ["123456", "234567"]],
- ]
-
- def test_find_bugs_in_string(self):
- openbugs = OpenBugs()
- for expectation in self.find_bugs_in_string_expectations:
- self.assertEquals(openbugs._find_bugs_in_string(expectation[0]), expectation[1])
-
- def test_args_parsing(self):
- expected_stderr = "2 bugs found in input.\nMOCK: user.open_url: http://example.com/12345\nMOCK: user.open_url: http://example.com/23456\n"
- self.assert_execute_outputs(OpenBugs(), ["12345\n23456"], expected_stderr=expected_stderr)
diff --git a/WebKitTools/Scripts/webkitpy/commands/queries.py b/WebKitTools/Scripts/webkitpy/commands/queries.py
deleted file mode 100644
index 3ca4f42..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/queries.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2009, Google Inc. All rights reserved.
-# Copyright (c) 2009 Apple 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 optparse import make_option
-
-from webkitpy.buildbot import BuildBot
-from webkitpy.committers import CommitterList
-from webkitpy.webkit_logging import log
-from webkitpy.multicommandtool import AbstractDeclarativeCommand
-
-
-class BugsToCommit(AbstractDeclarativeCommand):
- name = "bugs-to-commit"
- help_text = "List bugs in the commit-queue"
-
- def execute(self, options, args, tool):
- # FIXME: This command is poorly named. It's fetching the commit-queue list here. The name implies it's fetching pending-commit (all r+'d patches).
- bug_ids = tool.bugs.queries.fetch_bug_ids_from_commit_queue()
- for bug_id in bug_ids:
- print "%s" % bug_id
-
-
-class PatchesInCommitQueue(AbstractDeclarativeCommand):
- name = "patches-in-commit-queue"
- help_text = "List patches in the commit-queue"
-
- def execute(self, options, args, tool):
- patches = tool.bugs.queries.fetch_patches_from_commit_queue()
- log("Patches in commit queue:")
- for patch in patches:
- print patch.url()
-
-
-class PatchesToCommitQueue(AbstractDeclarativeCommand):
- name = "patches-to-commit-queue"
- help_text = "Patches which should be added to the commit queue"
- def __init__(self):
- options = [
- make_option("--bugs", action="store_true", dest="bugs", help="Output bug links instead of patch links"),
- ]
- AbstractDeclarativeCommand.__init__(self, options=options)
-
- @staticmethod
- def _needs_commit_queue(patch):
- if patch.commit_queue() == "+": # If it's already cq+, ignore the patch.
- log("%s already has cq=%s" % (patch.id(), patch.commit_queue()))
- return False
-
- # We only need to worry about patches from contributers who are not yet committers.
- committer_record = CommitterList().committer_by_email(patch.attacher_email())
- if committer_record:
- log("%s committer = %s" % (patch.id(), committer_record))
- return not committer_record
-
- def execute(self, options, args, tool):
- patches = tool.bugs.queries.fetch_patches_from_pending_commit_list()
- patches_needing_cq = filter(self._needs_commit_queue, patches)
- if options.bugs:
- bugs_needing_cq = map(lambda patch: patch.bug_id(), patches_needing_cq)
- bugs_needing_cq = sorted(set(bugs_needing_cq))
- for bug_id in bugs_needing_cq:
- print "%s" % tool.bugs.bug_url_for_bug_id(bug_id)
- else:
- for patch in patches_needing_cq:
- print "%s" % tool.bugs.attachment_url_for_id(patch.id(), action="edit")
-
-
-class PatchesToReview(AbstractDeclarativeCommand):
- name = "patches-to-review"
- help_text = "List patches that are pending review"
-
- def execute(self, options, args, tool):
- patch_ids = tool.bugs.queries.fetch_attachment_ids_from_review_queue()
- log("Patches pending review:")
- for patch_id in patch_ids:
- print patch_id
-
-
-class TreeStatus(AbstractDeclarativeCommand):
- name = "tree-status"
- help_text = "Print the status of the %s buildbots" % BuildBot.default_host
- long_help = """Fetches build status from http://build.webkit.org/one_box_per_builder
-and displayes the status of each builder."""
-
- def execute(self, options, args, tool):
- for builder in tool.buildbot.builder_statuses():
- status_string = "ok" if builder["is_green"] else "FAIL"
- print "%s : %s" % (status_string.ljust(4), builder["name"])
diff --git a/WebKitTools/Scripts/webkitpy/commands/queries_unittest.py b/WebKitTools/Scripts/webkitpy/commands/queries_unittest.py
deleted file mode 100644
index b858777..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/queries_unittest.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# 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.
-
-from webkitpy.bugzilla import Bugzilla
-from webkitpy.commands.commandtest import CommandsTest
-from webkitpy.commands.queries import *
-from webkitpy.mock import Mock
-from webkitpy.mock_bugzillatool import MockBugzillaTool
-
-class QueryCommandsTest(CommandsTest):
- def test_bugs_to_commit(self):
- expected_stderr = "Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)\n"
- self.assert_execute_outputs(BugsToCommit(), None, "42\n77\n", expected_stderr)
-
- def test_patches_in_commit_queue(self):
- expected_stdout = "http://example.com/197\nhttp://example.com/103\n"
- expected_stderr = "Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)\nPatches in commit queue:\n"
- self.assert_execute_outputs(PatchesInCommitQueue(), None, expected_stdout, expected_stderr)
-
- def test_patches_to_commit_queue(self):
- expected_stdout = "http://example.com/104&action=edit\n"
- expected_stderr = "197 already has cq=+\n128 already has cq=+\n105 committer = \"Eric Seidel\" <eric@webkit.org>\n"
- options = Mock()
- options.bugs = False
- self.assert_execute_outputs(PatchesToCommitQueue(), None, expected_stdout, expected_stderr, options=options)
-
- expected_stdout = "http://example.com/77\n"
- options.bugs = True
- self.assert_execute_outputs(PatchesToCommitQueue(), None, expected_stdout, expected_stderr, options=options)
-
- def test_patches_to_review(self):
- expected_stdout = "103\n"
- expected_stderr = "Patches pending review:\n"
- self.assert_execute_outputs(PatchesToReview(), None, expected_stdout, expected_stderr)
-
- def test_tree_status(self):
- expected_stdout = "ok : Builder1\nok : Builder2\n"
- self.assert_execute_outputs(TreeStatus(), None, expected_stdout)
diff --git a/WebKitTools/Scripts/webkitpy/commands/queues.py b/WebKitTools/Scripts/webkitpy/commands/queues.py
deleted file mode 100644
index 6ea1c48..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/queues.py
+++ /dev/null
@@ -1,295 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2009, Google Inc. All rights reserved.
-# Copyright (c) 2009 Apple 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 traceback
-import os
-
-from datetime import datetime
-from optparse import make_option
-from StringIO import StringIO
-
-from webkitpy.bugzilla import CommitterValidator
-from webkitpy.executive import ScriptError
-from webkitpy.grammar import pluralize
-from webkitpy.webkit_logging import error, log
-from webkitpy.multicommandtool import Command
-from webkitpy.patchcollection import PersistentPatchCollection, PersistentPatchCollectionDelegate
-from webkitpy.statusserver import StatusServer
-from webkitpy.stepsequence import StepSequenceErrorHandler
-from webkitpy.queueengine import QueueEngine, QueueEngineDelegate
-
-class AbstractQueue(Command, QueueEngineDelegate):
- watchers = [
- "webkit-bot-watchers@googlegroups.com",
- ]
-
- _pass_status = "Pass"
- _fail_status = "Fail"
- _error_status = "Error"
-
- def __init__(self, options=None): # Default values should never be collections (like []) as default values are shared between invocations
- options_list = (options or []) + [
- make_option("--no-confirm", action="store_false", dest="confirm", default=True, help="Do not ask the user for confirmation before running the queue. Dangerous!"),
- ]
- Command.__init__(self, "Run the %s" % self.name, options=options_list)
-
- def _cc_watchers(self, bug_id):
- try:
- self.tool.bugs.add_cc_to_bug(bug_id, self.watchers)
- except Exception, e:
- traceback.print_exc()
- log("Failed to CC watchers.")
-
- def _update_status(self, message, patch=None, results_file=None):
- self.tool.status_server.update_status(self.name, message, patch, results_file)
-
- def _did_pass(self, patch):
- self._update_status(self._pass_status, patch)
-
- def _did_fail(self, patch):
- self._update_status(self._fail_status, patch)
-
- def _did_error(self, patch, reason):
- message = "%s: %s" % (self._error_status, reason)
- self._update_status(message, patch)
-
- def queue_log_path(self):
- return "%s.log" % self.name
-
- def work_item_log_path(self, patch):
- return os.path.join("%s-logs" % self.name, "%s.log" % patch.bug_id())
-
- def begin_work_queue(self):
- log("CAUTION: %s will discard all local changes in \"%s\"" % (self.name, self.tool.scm().checkout_root))
- if self.options.confirm:
- response = self.tool.user.prompt("Are you sure? Type \"yes\" to continue: ")
- if (response != "yes"):
- error("User declined.")
- log("Running WebKit %s." % self.name)
-
- def should_continue_work_queue(self):
- return True
-
- def next_work_item(self):
- raise NotImplementedError, "subclasses must implement"
-
- def should_proceed_with_work_item(self, work_item):
- raise NotImplementedError, "subclasses must implement"
-
- def process_work_item(self, work_item):
- raise NotImplementedError, "subclasses must implement"
-
- def handle_unexpected_error(self, work_item, message):
- raise NotImplementedError, "subclasses must implement"
-
- def run_webkit_patch(self, args):
- webkit_patch_args = [self.tool.path()]
- # FIXME: This is a hack, we should have a more general way to pass global options.
- webkit_patch_args += ["--status-host=%s" % self.tool.status_server.host]
- webkit_patch_args += map(str, args)
- self.tool.executive.run_and_throw_if_fail(webkit_patch_args)
-
- def log_progress(self, patch_ids):
- log("%s in %s [%s]" % (pluralize("patch", len(patch_ids)), self.name, ", ".join(map(str, patch_ids))))
-
- def execute(self, options, args, tool, engine=QueueEngine):
- self.options = options
- self.tool = tool
- return engine(self.name, self).run()
-
- @classmethod
- def _update_status_for_script_error(cls, tool, state, script_error, is_error=False):
- message = script_error.message
- if is_error:
- message = "Error: %s" % message
- output = script_error.message_with_output(output_limit=5*1024*1024) # 5MB
- return tool.status_server.update_status(cls.name, message, state["patch"], StringIO(output))
-
-
-class CommitQueue(AbstractQueue, StepSequenceErrorHandler):
- name = "commit-queue"
- def __init__(self):
- AbstractQueue.__init__(self)
-
- # AbstractQueue methods
-
- def begin_work_queue(self):
- AbstractQueue.begin_work_queue(self)
- self.committer_validator = CommitterValidator(self.tool.bugs)
-
- def _validate_patches_in_commit_queue(self):
- # Not using BugzillaQueries.fetch_patches_from_commit_queue() so we can reject patches with invalid committers/reviewers.
- bug_ids = self.tool.bugs.queries.fetch_bug_ids_from_commit_queue()
- all_patches = sum([self.tool.bugs.fetch_bug(bug_id).commit_queued_patches(include_invalid=True) for bug_id in bug_ids], [])
- return self.committer_validator.patches_after_rejecting_invalid_commiters_and_reviewers(all_patches)
-
- def next_work_item(self):
- patches = self._validate_patches_in_commit_queue()
- # FIXME: We could sort the patches in a specific order here, was suggested by https://bugs.webkit.org/show_bug.cgi?id=33395
- if not patches:
- self._update_status("Empty queue")
- return None
- # Only bother logging if we have patches in the queue.
- self.log_progress([patch.id() for patch in patches])
- return patches[0]
-
- def _can_build_and_test(self):
- try:
- self.run_webkit_patch(["build-and-test", "--force-clean", "--non-interactive", "--build-style=both", "--quiet"])
- except ScriptError, e:
- self._update_status("Unabled to successfully build and test", None)
- return False
- return True
-
- def _builders_are_green(self):
- red_builders_names = self.tool.buildbot.red_core_builders_names()
- if red_builders_names:
- red_builders_names = map(lambda name: "\"%s\"" % name, red_builders_names) # Add quotes around the names.
- self._update_status("Builders [%s] are red. See http://build.webkit.org" % ", ".join(red_builders_names), None)
- return False
- return True
-
- def should_proceed_with_work_item(self, patch):
- if not self._builders_are_green():
- return False
- if not self._can_build_and_test():
- return False
- if not self._builders_are_green():
- return False
- self._update_status("Landing patch", patch)
- return True
-
- def process_work_item(self, patch):
- try:
- self._cc_watchers(patch.bug_id())
- # We pass --no-update here because we've already validated
- # that the current revision actually builds and passes the tests.
- # If we update, we risk moving to a revision that doesn't!
- self.run_webkit_patch(["land-attachment", "--force-clean", "--non-interactive", "--no-update", "--parent-command=commit-queue", "--build-style=both", "--quiet", patch.id()])
- self._did_pass(patch)
- except ScriptError, e:
- self._did_fail(patch)
- raise e
-
- def handle_unexpected_error(self, patch, message):
- self.committer_validator.reject_patch_from_commit_queue(patch.id(), message)
-
- # StepSequenceErrorHandler methods
-
- @staticmethod
- def _error_message_for_bug(tool, status_id, script_error):
- if not script_error.output:
- return script_error.message_with_output()
- results_link = tool.status_server.results_url_for_status(status_id)
- return "%s\nFull output: %s" % (script_error.message_with_output(), results_link)
-
- @classmethod
- def handle_script_error(cls, tool, state, script_error):
- status_id = cls._update_status_for_script_error(tool, state, script_error)
- validator = CommitterValidator(tool.bugs)
- validator.reject_patch_from_commit_queue(state["patch"].id(), cls._error_message_for_bug(tool, status_id, script_error))
-
-
-class AbstractReviewQueue(AbstractQueue, PersistentPatchCollectionDelegate, StepSequenceErrorHandler):
- def __init__(self, options=None):
- AbstractQueue.__init__(self, options)
-
- def _review_patch(self, patch):
- raise NotImplementedError, "subclasses must implement"
-
- # PersistentPatchCollectionDelegate methods
-
- def collection_name(self):
- return self.name
-
- def fetch_potential_patch_ids(self):
- return self.tool.bugs.queries.fetch_attachment_ids_from_review_queue()
-
- def status_server(self):
- return self.tool.status_server
-
- def is_terminal_status(self, status):
- return status == "Pass" or status == "Fail" or status.startswith("Error:")
-
- # AbstractQueue methods
-
- def begin_work_queue(self):
- AbstractQueue.begin_work_queue(self)
- self._patches = PersistentPatchCollection(self)
-
- def next_work_item(self):
- patch_id = self._patches.next()
- if patch_id:
- return self.tool.bugs.fetch_attachment(patch_id)
- self._update_status("Empty queue")
-
- def should_proceed_with_work_item(self, patch):
- raise NotImplementedError, "subclasses must implement"
-
- def process_work_item(self, patch):
- try:
- self._review_patch(patch)
- self._did_pass(patch)
- except ScriptError, e:
- if e.exit_code != QueueEngine.handled_error_code:
- self._did_fail(patch)
- raise e
-
- def handle_unexpected_error(self, patch, message):
- log(message)
-
- # StepSequenceErrorHandler methods
-
- @classmethod
- def handle_script_error(cls, tool, state, script_error):
- log(script_error.message_with_output())
-
-
-class StyleQueue(AbstractReviewQueue):
- name = "style-queue"
- def __init__(self):
- AbstractReviewQueue.__init__(self)
-
- def should_proceed_with_work_item(self, patch):
- self._update_status("Checking style", patch)
- return True
-
- def _review_patch(self, patch):
- self.run_webkit_patch(["check-style", "--force-clean", "--non-interactive", "--parent-command=style-queue", patch.id()])
-
- @classmethod
- def handle_script_error(cls, tool, state, script_error):
- is_svn_apply = script_error.command_name() == "svn-apply"
- status_id = cls._update_status_for_script_error(tool, state, script_error, is_error=is_svn_apply)
- if is_svn_apply:
- QueueEngine.exit_after_handled_error(script_error)
- message = "Attachment %s did not pass %s:\n\n%s\n\nIf any of these errors are false positives, please file a bug against check-webkit-style." % (state["patch"].id(), cls.name, script_error.message_with_output(output_limit=3*1024))
- tool.bugs.post_comment_to_bug(state["patch"].bug_id(), message, cc=cls.watchers)
- exit(1)
diff --git a/WebKitTools/Scripts/webkitpy/commands/queues_unittest.py b/WebKitTools/Scripts/webkitpy/commands/queues_unittest.py
deleted file mode 100644
index 87cd645..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/queues_unittest.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# 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 os
-
-from webkitpy.commands.commandtest import CommandsTest
-from webkitpy.commands.queues import *
-from webkitpy.commands.queuestest import QueuesTest
-from webkitpy.mock_bugzillatool import MockBugzillaTool
-from webkitpy.outputcapture import OutputCapture
-
-
-class TestQueue(AbstractQueue):
- name = "test-queue"
-
-
-class TestReviewQueue(AbstractReviewQueue):
- name = "test-review-queue"
-
-
-class AbstractQueueTest(CommandsTest):
- def _assert_log_progress_output(self, patch_ids, progress_output):
- OutputCapture().assert_outputs(self, TestQueue().log_progress, [patch_ids], expected_stderr=progress_output)
-
- def test_log_progress(self):
- self._assert_log_progress_output([1,2,3], "3 patches in test-queue [1, 2, 3]\n")
- self._assert_log_progress_output(["1","2","3"], "3 patches in test-queue [1, 2, 3]\n")
- self._assert_log_progress_output([1], "1 patch in test-queue [1]\n")
-
- def _assert_run_webkit_patch(self, run_args):
- queue = TestQueue()
- tool = MockBugzillaTool()
- queue.bind_to_tool(tool)
-
- queue.run_webkit_patch(run_args)
- expected_run_args = ["echo", "--status-host=example.com"] + map(str, run_args)
- tool.executive.run_and_throw_if_fail.assert_called_with(expected_run_args)
-
- def test_run_webkit_patch(self):
- self._assert_run_webkit_patch([1])
- self._assert_run_webkit_patch(["one", 2])
-
-
-class AbstractReviewQueueTest(CommandsTest):
- def test_patch_collection_delegate_methods(self):
- queue = TestReviewQueue()
- tool = MockBugzillaTool()
- queue.bind_to_tool(tool)
- self.assertEquals(queue.collection_name(), "test-review-queue")
- self.assertEquals(queue.fetch_potential_patch_ids(), [103])
- queue.status_server()
- self.assertTrue(queue.is_terminal_status("Pass"))
- self.assertTrue(queue.is_terminal_status("Fail"))
- self.assertTrue(queue.is_terminal_status("Error: Your patch exploded"))
- self.assertFalse(queue.is_terminal_status("Foo"))
-
-
-class CommitQueueTest(QueuesTest):
- def test_commit_queue(self):
- expected_stderr = {
- "begin_work_queue" : "CAUTION: commit-queue will discard all local changes in \"%s\"\nRunning WebKit commit-queue.\n" % os.getcwd(),
- # FIXME: The commit-queue warns about bad committers twice. This is due to the fact that we access Attachment.reviewer() twice and it logs each time.
- "next_work_item" : """Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
-Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)
-2 patches in commit-queue [197, 106]
-""",
- }
- self.assert_queue_outputs(CommitQueue(), expected_stderr=expected_stderr)
-
-
-class StyleQueueTest(QueuesTest):
- def test_style_queue(self):
- expected_stderr = {
- "begin_work_queue" : "CAUTION: style-queue will discard all local changes in \"%s\"\nRunning WebKit style-queue.\n" % os.getcwd(),
- "handle_unexpected_error" : "Mock error message\n",
- }
- self.assert_queue_outputs(StyleQueue(), expected_stderr=expected_stderr)
diff --git a/WebKitTools/Scripts/webkitpy/commands/queuestest.py b/WebKitTools/Scripts/webkitpy/commands/queuestest.py
deleted file mode 100644
index 09d1c26..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/queuestest.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# 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 unittest
-
-from webkitpy.bugzilla import Attachment
-from webkitpy.mock import Mock
-from webkitpy.mock_bugzillatool import MockBugzillaTool
-from webkitpy.outputcapture import OutputCapture
-
-
-class MockQueueEngine(object):
- def __init__(self, name, queue):
- pass
-
- def run(self):
- pass
-
-
-class QueuesTest(unittest.TestCase):
- mock_work_item = Attachment({
- "id" : 1234,
- "bug_id" : 345,
- "attacher_email": "adam@example.com",
- }, None)
-
- def assert_queue_outputs(self, queue, args=None, work_item=None, expected_stdout=None, expected_stderr=None, options=Mock(), tool=MockBugzillaTool()):
- if not expected_stdout:
- expected_stdout = {}
- if not expected_stderr:
- expected_stderr = {}
- if not args:
- args = []
- if not work_item:
- work_item = self.mock_work_item
- tool.user.prompt = lambda message: "yes"
-
- queue.execute(options, args, tool, engine=MockQueueEngine)
-
- OutputCapture().assert_outputs(self,
- queue.queue_log_path,
- expected_stdout=expected_stdout.get("queue_log_path", ""),
- expected_stderr=expected_stderr.get("queue_log_path", ""))
- OutputCapture().assert_outputs(self,
- queue.work_item_log_path,
- args=[work_item],
- expected_stdout=expected_stdout.get("work_item_log_path", ""),
- expected_stderr=expected_stderr.get("work_item_log_path", ""))
- OutputCapture().assert_outputs(self,
- queue.begin_work_queue,
- expected_stdout=expected_stdout.get("begin_work_queue", ""),
- expected_stderr=expected_stderr.get("begin_work_queue", ""))
- OutputCapture().assert_outputs(self,
- queue.should_continue_work_queue,
- expected_stdout=expected_stdout.get("should_continue_work_queue", ""), expected_stderr=expected_stderr.get("should_continue_work_queue", ""))
- OutputCapture().assert_outputs(self,
- queue.next_work_item,
- expected_stdout=expected_stdout.get("next_work_item", ""),
- expected_stderr=expected_stderr.get("next_work_item", ""))
- OutputCapture().assert_outputs(self,
- queue.should_proceed_with_work_item,
- args=[work_item],
- expected_stdout=expected_stdout.get("should_proceed_with_work_item", ""),
- expected_stderr=expected_stderr.get("should_proceed_with_work_item", ""))
- OutputCapture().assert_outputs(self,
- queue.process_work_item,
- args=[work_item],
- expected_stdout=expected_stdout.get("process_work_item", ""),
- expected_stderr=expected_stderr.get("process_work_item", ""))
- OutputCapture().assert_outputs(self,
- queue.handle_unexpected_error,
- args=[work_item, "Mock error message"],
- expected_stdout=expected_stdout.get("handle_unexpected_error", ""),
- expected_stderr=expected_stderr.get("handle_unexpected_error", ""))
diff --git a/WebKitTools/Scripts/webkitpy/commands/upload.py b/WebKitTools/Scripts/webkitpy/commands/upload.py
deleted file mode 100644
index 15bdfbb..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/upload.py
+++ /dev/null
@@ -1,447 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2009, Google Inc. All rights reserved.
-# Copyright (c) 2009 Apple 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 os
-import re
-import StringIO
-import sys
-
-from optparse import make_option
-
-import webkitpy.steps as steps
-
-from webkitpy.bugzilla import parse_bug_id
-from webkitpy.commands.abstractsequencedcommand import AbstractSequencedCommand
-from webkitpy.comments import bug_comment_from_svn_revision
-from webkitpy.committers import CommitterList
-from webkitpy.grammar import pluralize, join_with_separators
-from webkitpy.webkit_logging import error, log
-from webkitpy.mock import Mock
-from webkitpy.multicommandtool import AbstractDeclarativeCommand
-from webkitpy.user import User
-
-class CommitMessageForCurrentDiff(AbstractDeclarativeCommand):
- name = "commit-message"
- help_text = "Print a commit message suitable for the uncommitted changes"
-
- def execute(self, options, args, tool):
- os.chdir(tool.scm().checkout_root)
- print "%s" % tool.scm().commit_message_for_this_commit().message()
-
-class CleanPendingCommit(AbstractDeclarativeCommand):
- name = "clean-pending-commit"
- help_text = "Clear r+ on obsolete patches so they do not appear in the pending-commit list."
-
- # NOTE: This was designed to be generic, but right now we're only processing patches from the pending-commit list, so only r+ matters.
- def _flags_to_clear_on_patch(self, patch):
- if not patch.is_obsolete():
- return None
- what_was_cleared = []
- if patch.review() == "+":
- if patch.reviewer():
- what_was_cleared.append("%s's review+" % patch.reviewer().full_name)
- else:
- what_was_cleared.append("review+")
- return join_with_separators(what_was_cleared)
-
- def execute(self, options, args, tool):
- committers = CommitterList()
- for bug_id in tool.bugs.queries.fetch_bug_ids_from_pending_commit_list():
- bug = self.tool.bugs.fetch_bug(bug_id)
- patches = bug.patches(include_obsolete=True)
- for patch in patches:
- flags_to_clear = self._flags_to_clear_on_patch(patch)
- if not flags_to_clear:
- continue
- message = "Cleared %s from obsolete attachment %s so that this bug does not appear in http://webkit.org/pending-commit." % (flags_to_clear, patch.id())
- self.tool.bugs.obsolete_attachment(patch.id(), message)
-
-
-class AssignToCommitter(AbstractDeclarativeCommand):
- name = "assign-to-committer"
- help_text = "Assign bug to whoever attached the most recent r+'d patch"
-
- def _patches_have_commiters(self, reviewed_patches):
- for patch in reviewed_patches:
- if not patch.committer():
- return False
- return True
-
- def _assign_bug_to_last_patch_attacher(self, bug_id):
- committers = CommitterList()
- bug = self.tool.bugs.fetch_bug(bug_id)
- assigned_to_email = bug.assigned_to_email()
- if assigned_to_email != self.tool.bugs.unassigned_email:
- log("Bug %s is already assigned to %s (%s)." % (bug_id, assigned_to_email, committers.committer_by_email(assigned_to_email)))
- return
-
- reviewed_patches = bug.reviewed_patches()
- if not reviewed_patches:
- log("Bug %s has no non-obsolete patches, ignoring." % bug_id)
- return
-
- # We only need to do anything with this bug if one of the r+'d patches does not have a valid committer (cq+ set).
- if self._patches_have_commiters(reviewed_patches):
- log("All reviewed patches on bug %s already have commit-queue+, ignoring." % bug_id)
- return
-
- latest_patch = reviewed_patches[-1]
- attacher_email = latest_patch.attacher_email()
- committer = committers.committer_by_email(attacher_email)
- if not committer:
- log("Attacher %s is not a committer. Bug %s likely needs commit-queue+." % (attacher_email, bug_id))
- return
-
- reassign_message = "Attachment %s was posted by a committer and has review+, assigning to %s for commit." % (latest_patch.id(), committer.full_name)
- self.tool.bugs.reassign_bug(bug_id, committer.bugzilla_email(), reassign_message)
-
- def execute(self, options, args, tool):
- for bug_id in tool.bugs.queries.fetch_bug_ids_from_pending_commit_list():
- self._assign_bug_to_last_patch_attacher(bug_id)
-
-
-class ObsoleteAttachments(AbstractSequencedCommand):
- name = "obsolete-attachments"
- help_text = "Mark all attachments on a bug as obsolete"
- argument_names = "BUGID"
- steps = [
- steps.ObsoletePatches,
- ]
-
- def _prepare_state(self, options, args, tool):
- return { "bug_id" : args[0] }
-
-
-class AbstractPatchUploadingCommand(AbstractSequencedCommand):
- def _bug_id(self, args, tool, state):
- # Perfer a bug id passed as an argument over a bug url in the diff (i.e. ChangeLogs).
- bug_id = args and args[0]
- if not bug_id:
- state["diff"] = tool.scm().create_patch()
- bug_id = parse_bug_id(state["diff"])
- return bug_id
-
- def _prepare_state(self, options, args, tool):
- state = {}
- state["bug_id"] = self._bug_id(args, tool, state)
- if not state["bug_id"]:
- error("No bug id passed and no bug url found in diff.")
- return state
-
-
-class Post(AbstractPatchUploadingCommand):
- name = "post"
- help_text = "Attach the current working directory diff to a bug as a patch file"
- argument_names = "[BUGID]"
- show_in_main_help = True
- steps = [
- steps.CheckStyle,
- steps.ConfirmDiff,
- steps.ObsoletePatches,
- steps.PostDiff,
- ]
-
-
-class LandSafely(AbstractPatchUploadingCommand):
- name = "land-safely"
- help_text = "Land the current diff via the commit-queue (Experimental)"
- argument_names = "[BUGID]"
- steps = [
- steps.UpdateChangeLogsWithReviewer,
- steps.ObsoletePatches,
- steps.PostDiffForCommit,
- ]
-
-
-class Prepare(AbstractSequencedCommand):
- name = "prepare"
- help_text = "Creates a bug (or prompts for an existing bug) and prepares the ChangeLogs"
- argument_names = "[BUGID]"
- show_in_main_help = True
- steps = [
- steps.PromptForBugOrTitle,
- steps.CreateBug,
- steps.PrepareChangeLog,
- ]
-
- def _prepare_state(self, options, args, tool):
- bug_id = args and args[0]
- return { "bug_id" : bug_id }
-
-
-class Upload(AbstractPatchUploadingCommand):
- name = "upload"
- help_text = "Automates the process of uploading a patch for review"
- argument_names = "[BUGID]"
- show_in_main_help = True
- steps = [
- steps.CheckStyle,
- steps.PromptForBugOrTitle,
- steps.CreateBug,
- steps.PrepareChangeLog,
- steps.EditChangeLog,
- steps.ConfirmDiff,
- steps.ObsoletePatches,
- steps.PostDiff,
- ]
- long_help = """upload uploads the current diff to bugs.webkit.org.
- If no bug id is provided, upload will create a bug.
- If the current diff does not have a ChangeLog, upload
- will prepare a ChangeLog. Once a patch is read, upload
- will open the ChangeLogs for editing using the command in the
- EDITOR environment variable and will display the diff using the
- command in the PAGER environment variable."""
-
- def _prepare_state(self, options, args, tool):
- state = {}
- state["bug_id"] = self._bug_id(args, tool, state)
- return state
-
-
-class EditChangeLogs(AbstractSequencedCommand):
- name = "edit-changelogs"
- help_text = "Opens modified ChangeLogs in $EDITOR"
- show_in_main_help = True
- steps = [
- steps.EditChangeLog,
- ]
-
-
-class PostCommits(AbstractDeclarativeCommand):
- name = "post-commits"
- help_text = "Attach a range of local commits to bugs as patch files"
- argument_names = "COMMITISH"
-
- def __init__(self):
- options = [
- 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)"),
- steps.Options.obsolete_patches,
- steps.Options.review,
- steps.Options.request_commit,
- ]
- AbstractDeclarativeCommand.__init__(self, options=options, requires_local_commits=True)
-
- def _comment_text_for_commit(self, options, commit_message, tool, commit_id):
- comment_text = None
- if (options.add_log_as_comment):
- comment_text = commit_message.body(lstrip=True)
- comment_text += "---\n"
- comment_text += tool.scm().files_changed_summary_for_commit(commit_id)
- return comment_text
-
- def _diff_file_for_commit(self, tool, commit_id):
- diff = tool.scm().create_patch_from_local_commit(commit_id)
- return StringIO.StringIO(diff) # add_patch_to_bug expects a file-like object
-
- def execute(self, options, args, tool):
- commit_ids = tool.scm().commit_ids_from_commitish_arguments(args)
- if len(commit_ids) > 10: # We could lower this limit, 10 is too many for one bug as-is.
- error("webkit-patch does not support attaching %s at once. Are you sure you passed the right commit range?" % (pluralize("patch", len(commit_ids))))
-
- have_obsoleted_patches = set()
- for commit_id in commit_ids:
- commit_message = tool.scm().commit_message_for_local_commit(commit_id)
-
- # Prefer --bug-id=, then a bug url in the commit message, then a bug url in the entire commit diff (i.e. ChangeLogs).
- bug_id = options.bug_id or parse_bug_id(commit_message.message()) or parse_bug_id(tool.scm().create_patch_from_local_commit(commit_id))
- if not bug_id:
- log("Skipping %s: No bug id found in commit or specified with --bug-id." % commit_id)
- continue
-
- if options.obsolete_patches and bug_id not in have_obsoleted_patches:
- state = { "bug_id": bug_id }
- steps.ObsoletePatches(tool, options).run(state)
- have_obsoleted_patches.add(bug_id)
-
- diff_file = self._diff_file_for_commit(tool, commit_id)
- description = options.description or commit_message.description(lstrip=True, strip_url=True)
- comment_text = self._comment_text_for_commit(options, commit_message, tool, commit_id)
- tool.bugs.add_patch_to_bug(bug_id, diff_file, description, comment_text, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)
-
-
-class MarkBugFixed(AbstractDeclarativeCommand):
- name = "mark-bug-fixed"
- help_text = "Mark the specified bug as fixed"
- argument_names = "[SVN_REVISION]"
- def __init__(self):
- options = [
- make_option("--bug-id", action="store", type="string", dest="bug_id", help="Specify bug id if no URL is provided in the commit log."),
- make_option("--comment", action="store", type="string", dest="comment", help="Text to include in bug comment."),
- make_option("--open", action="store_true", default=False, dest="open_bug", help="Open bug in default web browser (Mac only)."),
- make_option("--update-only", action="store_true", default=False, dest="update_only", help="Add comment to the bug, but do not close it."),
- ]
- AbstractDeclarativeCommand.__init__(self, options=options)
-
- def _fetch_commit_log(self, tool, svn_revision):
- if not svn_revision:
- return tool.scm().last_svn_commit_log()
- return tool.scm().svn_commit_log(svn_revision)
-
- def _determine_bug_id_and_svn_revision(self, tool, bug_id, svn_revision):
- commit_log = self._fetch_commit_log(tool, svn_revision)
-
- if not bug_id:
- bug_id = parse_bug_id(commit_log)
-
- if not svn_revision:
- match = re.search("^r(?P<svn_revision>\d+) \|", commit_log, re.MULTILINE)
- if match:
- svn_revision = match.group('svn_revision')
-
- if not bug_id or not svn_revision:
- not_found = []
- if not bug_id:
- not_found.append("bug id")
- if not svn_revision:
- not_found.append("svn revision")
- error("Could not find %s on command-line or in %s."
- % (" or ".join(not_found), "r%s" % svn_revision if svn_revision else "last commit"))
-
- return (bug_id, svn_revision)
-
- def execute(self, options, args, tool):
- bug_id = options.bug_id
-
- svn_revision = args and args[0]
- if svn_revision:
- if re.match("^r[0-9]+$", svn_revision, re.IGNORECASE):
- svn_revision = svn_revision[1:]
- if not re.match("^[0-9]+$", svn_revision):
- error("Invalid svn revision: '%s'" % svn_revision)
-
- needs_prompt = False
- if not bug_id or not svn_revision:
- needs_prompt = True
- (bug_id, svn_revision) = self._determine_bug_id_and_svn_revision(tool, bug_id, svn_revision)
-
- log("Bug: <%s> %s" % (tool.bugs.bug_url_for_bug_id(bug_id), tool.bugs.fetch_bug_dictionary(bug_id)["title"]))
- log("Revision: %s" % svn_revision)
-
- if options.open_bug:
- tool.user.open_url(tool.bugs.bug_url_for_bug_id(bug_id))
-
- if needs_prompt:
- if not tool.user.confirm("Is this correct?"):
- exit(1)
-
- bug_comment = bug_comment_from_svn_revision(svn_revision)
- if options.comment:
- bug_comment = "%s\n\n%s" % (options.comment, bug_comment)
-
- if options.update_only:
- log("Adding comment to Bug %s." % bug_id)
- tool.bugs.post_comment_to_bug(bug_id, bug_comment)
- else:
- log("Adding comment to Bug %s and marking as Resolved/Fixed." % bug_id)
- tool.bugs.close_bug_as_fixed(bug_id, bug_comment)
-
-
-# FIXME: Requires unit test. Blocking issue: too complex for now.
-class CreateBug(AbstractDeclarativeCommand):
- name = "create-bug"
- help_text = "Create a bug from local changes or local commits"
- argument_names = "[COMMITISH]"
-
- def __init__(self):
- options = [
- steps.Options.cc,
- steps.Options.component,
- make_option("--no-prompt", action="store_false", dest="prompt", default=True, help="Do not prompt for bug title and comment; use commit log instead."),
- 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."),
- ]
- AbstractDeclarativeCommand.__init__(self, options=options)
-
- def create_bug_from_commit(self, options, args, tool):
- commit_ids = tool.scm().commit_ids_from_commitish_arguments(args)
- if len(commit_ids) > 3:
- error("Are you sure you want to create one bug with %s patches?" % len(commit_ids))
-
- commit_id = commit_ids[0]
-
- bug_title = ""
- comment_text = ""
- if options.prompt:
- (bug_title, comment_text) = self.prompt_for_bug_title_and_comment()
- else:
- commit_message = tool.scm().commit_message_for_local_commit(commit_id)
- bug_title = commit_message.description(lstrip=True, strip_url=True)
- comment_text = commit_message.body(lstrip=True)
- comment_text += "---\n"
- comment_text += tool.scm().files_changed_summary_for_commit(commit_id)
-
- diff = tool.scm().create_patch_from_local_commit(commit_id)
- diff_file = StringIO.StringIO(diff) # create_bug expects a file-like object
- bug_id = tool.bugs.create_bug(bug_title, comment_text, options.component, diff_file, "Patch", cc=options.cc, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)
-
- if bug_id and len(commit_ids) > 1:
- options.bug_id = bug_id
- options.obsolete_patches = False
- # FIXME: We should pass through --no-comment switch as well.
- PostCommits.execute(self, options, commit_ids[1:], tool)
-
- def create_bug_from_patch(self, options, args, tool):
- bug_title = ""
- comment_text = ""
- if options.prompt:
- (bug_title, comment_text) = self.prompt_for_bug_title_and_comment()
- else:
- commit_message = tool.scm().commit_message_for_this_commit()
- bug_title = commit_message.description(lstrip=True, strip_url=True)
- comment_text = commit_message.body(lstrip=True)
-
- diff = tool.scm().create_patch()
- diff_file = StringIO.StringIO(diff) # create_bug expects a file-like object
- bug_id = tool.bugs.create_bug(bug_title, comment_text, options.component, diff_file, "Patch", cc=options.cc, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)
-
- def prompt_for_bug_title_and_comment(self):
- bug_title = User.prompt("Bug title: ")
- print "Bug comment (hit ^D on blank line to end):"
- lines = sys.stdin.readlines()
- try:
- sys.stdin.seek(0, os.SEEK_END)
- except IOError:
- # Cygwin raises an Illegal Seek (errno 29) exception when the above
- # seek() call is made. Ignoring it seems to cause no harm.
- # FIXME: Figure out a way to get avoid the exception in the first
- # place.
- pass
- comment_text = "".join(lines)
- return (bug_title, comment_text)
-
- def execute(self, options, args, tool):
- if len(args):
- if (not tool.scm().supports_local_commits()):
- error("Extra arguments not supported; patch is taken from working directory.")
- self.create_bug_from_commit(options, args, tool)
- else:
- self.create_bug_from_patch(options, args, tool)
diff --git a/WebKitTools/Scripts/webkitpy/commands/upload_unittest.py b/WebKitTools/Scripts/webkitpy/commands/upload_unittest.py
deleted file mode 100644
index 7fa8797..0000000
--- a/WebKitTools/Scripts/webkitpy/commands/upload_unittest.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# 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.
-
-from webkitpy.commands.commandtest import CommandsTest
-from webkitpy.commands.upload import *
-from webkitpy.mock import Mock
-from webkitpy.mock_bugzillatool import MockBugzillaTool
-
-class UploadCommandsTest(CommandsTest):
- def test_commit_message_for_current_diff(self):
- tool = MockBugzillaTool()
- mock_commit_message_for_this_commit = Mock()
- mock_commit_message_for_this_commit.message = lambda: "Mock message"
- tool._scm.commit_message_for_this_commit = lambda: mock_commit_message_for_this_commit
- expected_stdout = "Mock message\n"
- self.assert_execute_outputs(CommitMessageForCurrentDiff(), [], expected_stdout=expected_stdout, tool=tool)
-
- def test_clean_pending_commit(self):
- self.assert_execute_outputs(CleanPendingCommit(), [])
-
- def test_assign_to_committer(self):
- tool = MockBugzillaTool()
- expected_stderr = "Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)\nBug 77 is already assigned to foo@foo.com (None).\nBug 76 has no non-obsolete patches, ignoring.\n"
- self.assert_execute_outputs(AssignToCommitter(), [], expected_stderr=expected_stderr, tool=tool)
- tool.bugs.reassign_bug.assert_called_with(42, "eric@webkit.org", "Attachment 128 was posted by a committer and has review+, assigning to Eric Seidel for commit.")
-
- def test_obsolete_attachments(self):
- expected_stderr = "Obsoleting 2 old patches on bug 42\n"
- self.assert_execute_outputs(ObsoleteAttachments(), [42], expected_stderr=expected_stderr)
-
- def test_post(self):
- expected_stderr = "Running check-webkit-style\nObsoleting 2 old patches on bug 42\n"
- self.assert_execute_outputs(Post(), [42], expected_stderr=expected_stderr)
-
- def test_post(self):
- expected_stderr = "Obsoleting 2 old patches on bug 42\n"
- self.assert_execute_outputs(LandSafely(), [42], expected_stderr=expected_stderr)
-
- def test_prepare_diff_with_arg(self):
- self.assert_execute_outputs(Prepare(), [42])
-
- def test_prepare(self):
- self.assert_execute_outputs(Prepare(), [])
-
- def test_upload(self):
- expected_stderr = "Running check-webkit-style\nObsoleting 2 old patches on bug 42\nMOCK: user.open_url: http://example.com/42\n"
- self.assert_execute_outputs(Upload(), [42], expected_stderr=expected_stderr)
-
- def test_mark_bug_fixed(self):
- tool = MockBugzillaTool()
- tool._scm.last_svn_commit_log = lambda: "r9876 |"
- options = Mock()
- options.bug_id = 42
- expected_stderr = """Bug: <http://example.com/42> Bug with two r+'d and cq+'d patches, one of which has an invalid commit-queue setter.
-Revision: 9876
-MOCK: user.open_url: http://example.com/42
-Adding comment to Bug 42.
-"""
- self.assert_execute_outputs(MarkBugFixed(), [], expected_stderr=expected_stderr, tool=tool, options=options)
-
- def test_edit_changelog(self):
- self.assert_execute_outputs(EditChangeLogs(), [])