Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(540)

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/tool/webkit_patch.py

Issue 2110893003: Merge webkit_patch and multi_command_tool. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sort imports; remove out-of-date comment. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright (c) 2010 Google Inc. All rights reserved. 1 # Copyright (c) 2010 Google Inc. All rights reserved.
2 # Copyright (c) 2009 Apple Inc. All rights reserved. 2 # Copyright (c) 2009 Apple Inc. All rights reserved.
3 # 3 #
4 # Redistribution and use in source and binary forms, with or without 4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are 5 # modification, are permitted provided that the following conditions are
6 # met: 6 # met:
7 # 7 #
8 # * Redistributions of source code must retain the above copyright 8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer. 9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above 10 # * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following disclaimer 11 # copyright notice, this list of conditions and the following disclaimer
12 # in the documentation and/or other materials provided with the 12 # in the documentation and/or other materials provided with the
13 # distribution. 13 # distribution.
14 # * Neither the name of Google Inc. nor the names of its 14 # * Neither the name of Google Inc. nor the names of its
15 # contributors may be used to endorse or promote products derived from 15 # contributors may be used to endorse or promote products derived from
16 # this software without specific prior written permission. 16 # this software without specific prior written permission.
17 # 17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #
30 # A tool for automating dealing with bugzilla, posting patches, committing patch es, etc.
31 29
32 from optparse import make_option 30 """Webkit-patch is a tool with multiple sub-commands with different purposes.
31
32 Historically, it had commands related to dealing with bugzilla, and posting
33 and comitting patches to WebKit. More recently, it has commands for printing
34 expectations, fetching new test baselines, starting a commit-announcer IRC bot,
35 etc. These commands don't necessarily have anything to do with each other.
36 """
37
38 import logging
39 import optparse
40 import sys
33 41
34 from webkitpy.common.host import Host 42 from webkitpy.common.host import Host
35 from webkitpy.tool.multi_command_tool import MultiCommandTool
36
37 from webkitpy.tool.commands.analyze_baselines import AnalyzeBaselines 43 from webkitpy.tool.commands.analyze_baselines import AnalyzeBaselines
44 from webkitpy.tool.commands.command import HelpPrintingOptionParser
38 from webkitpy.tool.commands.commit_announcer import CommitAnnouncerCommand 45 from webkitpy.tool.commands.commit_announcer import CommitAnnouncerCommand
39 from webkitpy.tool.commands.flaky_tests import FlakyTests 46 from webkitpy.tool.commands.flaky_tests import FlakyTests
47 from webkitpy.tool.commands.help_command import HelpCommand
40 from webkitpy.tool.commands.layout_tests_server import LayoutTestsServer 48 from webkitpy.tool.commands.layout_tests_server import LayoutTestsServer
41 from webkitpy.tool.commands.pretty_diff import PrettyDiff 49 from webkitpy.tool.commands.pretty_diff import PrettyDiff
42 from webkitpy.tool.commands.queries import CrashLog 50 from webkitpy.tool.commands.queries import CrashLog
43 from webkitpy.tool.commands.queries import PrintBaselines 51 from webkitpy.tool.commands.queries import PrintBaselines
44 from webkitpy.tool.commands.queries import PrintExpectations 52 from webkitpy.tool.commands.queries import PrintExpectations
53 from webkitpy.tool.commands.rebaseline_from_try_jobs import RebaselineFromTryJob s
45 from webkitpy.tool.commands.rebaseline import AutoRebaseline 54 from webkitpy.tool.commands.rebaseline import AutoRebaseline
46 from webkitpy.tool.commands.rebaseline import CopyExistingBaselinesInternal 55 from webkitpy.tool.commands.rebaseline import CopyExistingBaselinesInternal
47 from webkitpy.tool.commands.rebaseline import OptimizeBaselines 56 from webkitpy.tool.commands.rebaseline import OptimizeBaselines
48 from webkitpy.tool.commands.rebaseline import Rebaseline 57 from webkitpy.tool.commands.rebaseline import Rebaseline
49 from webkitpy.tool.commands.rebaseline import RebaselineExpectations 58 from webkitpy.tool.commands.rebaseline import RebaselineExpectations
50 from webkitpy.tool.commands.rebaseline import RebaselineJson 59 from webkitpy.tool.commands.rebaseline import RebaselineJson
51 from webkitpy.tool.commands.rebaseline import RebaselineTest 60 from webkitpy.tool.commands.rebaseline import RebaselineTest
52 from webkitpy.tool.commands.rebaseline_server import RebaselineServer 61 from webkitpy.tool.commands.rebaseline_server import RebaselineServer
53 from webkitpy.tool.commands.rebaseline_from_try_jobs import RebaselineFromTryJob s
54 62
55 63
56 class WebKitPatch(MultiCommandTool, Host): 64 _log = logging.getLogger(__name__)
65
66
67 class WebKitPatch(Host):
57 global_options = [ 68 global_options = [
58 make_option("-v", "--verbose", action="store_true", dest="verbose", defa ult=False, help="enable all logging"), 69 optparse.make_option(
59 make_option("-d", "--directory", action="append", dest="patch_directorie s", 70 "-v", "--verbose", action="store_true", dest="verbose", default=Fals e,
60 default=[], help="Directory to look at for changed files"), 71 help="enable all logging"),
72 optparse.make_option(
73 "-d", "--directory", action="append", dest="patch_directories", defa ult=[],
74 help="Directory to look at for changed files"),
61 ] 75 ]
62 76
63 def __init__(self, path): 77 def __init__(self):
64 MultiCommandTool.__init__(self, commands=[ 78 super(WebKitPatch, self).__init__()
79 self.commands = [
65 AnalyzeBaselines(), 80 AnalyzeBaselines(),
66 AutoRebaseline(), 81 AutoRebaseline(),
67 CommitAnnouncerCommand(), 82 CommitAnnouncerCommand(),
68 CopyExistingBaselinesInternal(), 83 CopyExistingBaselinesInternal(),
69 CrashLog(), 84 CrashLog(),
70 FlakyTests(), 85 FlakyTests(),
71 LayoutTestsServer(), 86 LayoutTestsServer(),
72 OptimizeBaselines(), 87 OptimizeBaselines(),
73 PrettyDiff(), 88 PrettyDiff(),
74 PrintBaselines(), 89 PrintBaselines(),
75 PrintExpectations(), 90 PrintExpectations(),
76 Rebaseline(), 91 Rebaseline(),
77 RebaselineExpectations(), 92 RebaselineExpectations(),
78 RebaselineFromTryJobs(), 93 RebaselineFromTryJobs(),
79 RebaselineJson(), 94 RebaselineJson(),
80 RebaselineServer(), 95 RebaselineServer(),
81 RebaselineTest(), 96 RebaselineTest(),
82 ]) 97 ]
83 Host.__init__(self) 98 self.help_command = HelpCommand()
84 self._path = path 99 self.commands.append(self.help_command)
100 # FIXME: Since tool is passed to Command.execute, it may not be necessar y to set a tool attribute on the
101 # command objects here - maybe this should be done inside of Command.exe cute for commands that use self._tool.
102 for command in self.commands:
103 command.bind_to_tool(self)
85 104
86 def path(self): 105 def main(self, argv=None):
87 return self._path 106 argv = argv or sys.argv
107 (command_name, args) = self._split_command_name_from_args(argv[1:])
108
109 option_parser = self._create_option_parser()
110 self._add_global_options(option_parser)
111
112 command = self.command_by_name(command_name) or self.help_command
113 if not command:
114 option_parser.error("%s is not a recognized command" % command_name)
115
116 command.set_option_parser(option_parser)
117 (options, args) = command.parse_args(args)
118 self._handle_global_options(options)
119
120 (should_execute, failure_reason) = self._should_execute_command(command)
121 if not should_execute:
122 _log.error(failure_reason)
123 return 0 # FIXME: Should this really be 0?
124
125 result = command.check_arguments_and_execute(options, args, self)
126 return result
127
128 @staticmethod
129 def _split_command_name_from_args(args):
130 # Assume the first argument which doesn't start with "-" is the command name.
131 command_index = 0
132 for arg in args:
133 if arg[0] != "-":
134 break
135 command_index += 1
136 else:
137 return (None, args[:])
138
139 command = args[command_index]
140 return (command, args[:command_index] + args[command_index + 1:])
141
142 def _create_option_parser(self):
143 usage = "Usage: %prog [options] COMMAND [ARGS]"
144 name = optparse.OptionParser().get_prog_name()
145 return HelpPrintingOptionParser(epilog_method=self.help_command._help_ep ilog, prog=name, usage=usage)
146
147 def _add_global_options(self, option_parser):
148 global_options = self.global_options or []
149 for option in global_options:
150 option_parser.add_option(option)
151
152 # FIXME: This may be unnecessary since we pass global options to all command s during execute() as well.
153 def _handle_global_options(self, options):
154 self.initialize_scm(options.patch_directories)
155
156 def _should_execute_command(self, command):
157 if command.requires_local_commits and not self.scm().supports_local_comm its():
158 failure_reason = "%s requires local commits using %s in %s." % (
159 command.name, self.scm().display_name(), self.scm().checkout_roo t)
160 return (False, failure_reason)
161 return (True, None)
162
163 def name(self):
164 return optparse.OptionParser().get_prog_name()
88 165
89 def should_show_in_main_help(self, command): 166 def should_show_in_main_help(self, command):
90 if not command.show_in_main_help: 167 if not command.show_in_main_help:
91 return False 168 return False
92 if command.requires_local_commits: 169 if command.requires_local_commits:
93 return self.scm().supports_local_commits() 170 return self.scm().supports_local_commits()
94 return True 171 return True
95 172
96 # FIXME: This may be unnecessary since we pass global options to all command s during execute() as well. 173 def command_by_name(self, command_name):
97 def handle_global_options(self, options): 174 for command in self.commands:
98 self.initialize_scm(options.patch_directories) 175 if command_name == command.name:
99 176 return command
100 def should_execute_command(self, command): 177 return None
101 if command.requires_local_commits and not self.scm().supports_local_comm its():
102 failure_reason = "%s requires local commits using %s in %s." % (
103 command.name, self.scm().display_name(), self.scm().checkout_roo t)
104 return (False, failure_reason)
105 return (True, None)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698