From: levin@chromium.org Date: Tue, 27 Sep 2011 23:42:12 +0000 (+0000) Subject: watchlist: Add support for cc and message rules. X-Git-Tag: 070512121124~23517 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f8a64aa5fca429ffeffb79a1d8dcc0ff22474d43;p=profile%2Fivi%2Fwebkit-efl.git watchlist: Add support for cc and message rules. https://bugs.webkit.org/show_bug.cgi?id=68950 Reviewed by Adam Barth. * Scripts/webkitpy/common/watchlist/watchlist.py: Added support to get the cc's and messages for a patch. * Scripts/webkitpy/common/watchlist/watchlist_unittest.py: Tests for the above. * Scripts/webkitpy/common/watchlist/watchlistparser.py: Parsing support for the rules. * Scripts/webkitpy/common/watchlist/watchlistrule.py: Copied from Tools/Scripts/webkitpy/common/watchlist/watchlist.py. A generic encapsulation of either a message list or a cc list. * Scripts/webkitpy/common/watchlist/watchlistrule_unittest.py: Copied from Tools/Scripts/webkitpy/common/watchlist/watchlist.py. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96170 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- diff --git a/Tools/ChangeLog b/Tools/ChangeLog index f3d6ff3..c349e4a 100644 --- a/Tools/ChangeLog +++ b/Tools/ChangeLog @@ -1,3 +1,19 @@ +2011-09-27 David Levin + + watchlist: Add support for cc and message rules. + https://bugs.webkit.org/show_bug.cgi?id=68950 + + Reviewed by Adam Barth. + + * Scripts/webkitpy/common/watchlist/watchlist.py: Added support to get + the cc's and messages for a patch. + * Scripts/webkitpy/common/watchlist/watchlist_unittest.py: Tests for the above. + * Scripts/webkitpy/common/watchlist/watchlistparser.py: Parsing support + for the rules. + * Scripts/webkitpy/common/watchlist/watchlistrule.py: Copied from Tools/Scripts/webkitpy/common/watchlist/watchlist.py. + A generic encapsulation of either a message list or a cc list. + * Scripts/webkitpy/common/watchlist/watchlistrule_unittest.py: Copied from Tools/Scripts/webkitpy/common/watchlist/watchlist.py. + 2011-09-27 Tom Zakrajsek webkit-patch doesn't like UTF-8 characters in reviewers names diff --git a/Tools/Scripts/webkitpy/common/watchlist/watchlist.py b/Tools/Scripts/webkitpy/common/watchlist/watchlist.py index fc31972..c000dfb 100644 --- a/Tools/Scripts/webkitpy/common/watchlist/watchlist.py +++ b/Tools/Scripts/webkitpy/common/watchlist/watchlist.py @@ -28,13 +28,22 @@ from webkitpy.common.checkout.diff_parser import DiffParser + class WatchList(object): def __init__(self): self._definitions = {} + self._cc_rules = set() + self._message_rules = set() def set_definitions(self, definitions): self._definitions = definitions + def set_cc_rules(self, cc_rules): + self._cc_rules = cc_rules + + def set_message_rules(self, message_rules): + self._message_rules = message_rules + def find_matching_definitions(self, diff): matching_definitions = set() patch_files = DiffParser(diff.splitlines()).files @@ -52,3 +61,23 @@ class WatchList(object): else: matching_definitions.add(definition) return matching_definitions + + def _determine_instructions(self, matching_definitions, rules): + instructions = set() + for rule in rules: + if rule.match(matching_definitions): + instructions.update(rule.instructions()) + return instructions + + def determine_cc_set(self, matching_definitions): + return self._determine_instructions(matching_definitions, self._cc_rules) + + def determine_messages(self, matching_definitions): + return self._determine_instructions(matching_definitions, self._message_rules) + + def determine_cc_set_and_messages(self, diff): + definitions = self.find_matching_definitions(diff) + return { + 'cc_set': self.determine_cc_set(definitions), + 'messages': self.determine_messages(definitions), + } diff --git a/Tools/Scripts/webkitpy/common/watchlist/watchlist_unittest.py b/Tools/Scripts/webkitpy/common/watchlist/watchlist_unittest.py index 2cb3bcd..f6e8be6 100644 --- a/Tools/Scripts/webkitpy/common/watchlist/watchlist_unittest.py +++ b/Tools/Scripts/webkitpy/common/watchlist/watchlist_unittest.py @@ -34,7 +34,7 @@ from webkitpy.common.checkout.diff_test_data import DIFF_TEST_DATA from webkitpy.common.watchlist.watchlistparser import WatchListParser -class WatchListParserTest(unittest.TestCase): +class WatchListTest(unittest.TestCase): def setUp(self): self._watch_list_parser = WatchListParser() @@ -59,3 +59,83 @@ class WatchListParserTest(unittest.TestCase): ' },' '}') self.assertEquals(set(['WatchList1']), watch_list.find_matching_definitions(DIFF_TEST_DATA)) + + def test_cc_rules_simple(self): + watch_list = self._watch_list_parser.parse( + '{' + ' "DEFINITIONS": {' + ' "WatchList1": {' + ' "filename": r"WebCore/rendering/style/StyleFlexibleBoxData\.h",' + ' },' + ' },' + ' "CC_RULES": {' + ' "WatchList1": [' + ' "levin@chromium.org",' + ' ],' + ' },' + '}') + cc_set_and_messages = watch_list.determine_cc_set_and_messages(DIFF_TEST_DATA) + self.assertEquals({ + 'cc_set': set(['levin@chromium.org']), + 'messages': set(), + }, cc_set_and_messages) + + def test_cc_rules_complex(self): + watch_list = self._watch_list_parser.parse( + '{' + ' "DEFINITIONS": {' + ' "WatchList1": {' + ' "filename": r"WebCore/rendering/style/StyleFlexibleBoxData\.h",' + ' },' + ' },' + ' "CC_RULES": {' + ' "WatchList2|WatchList1|WatchList3": [ "levin@chromium.org", ],' + ' },' + '}') + cc_set_and_messages = watch_list.determine_cc_set_and_messages(DIFF_TEST_DATA) + self.assertEquals({ + 'cc_set': set(['levin@chromium.org']), + 'messages': set(), + }, cc_set_and_messages) + + def test_cc_and_message_rules_complex(self): + watch_list = self._watch_list_parser.parse( + '{' + ' "DEFINITIONS": {' + ' "WatchList1": {' + ' "filename": r"WebCore/rendering/style/StyleFlexibleBoxData\.h",' + ' },' + ' },' + ' "CC_RULES": {' + ' "WatchList2|WatchList1|WatchList3": [ "levin@chromium.org", ],' + ' },' + ' "MESSAGE_RULES": {' + ' "WatchList2|WatchList1|WatchList3": [ "msg1", "msg2", ],' + ' },' + '}') + cc_set_and_messages = watch_list.determine_cc_set_and_messages(DIFF_TEST_DATA) + self.assertEquals({ + 'cc_set': set(['levin@chromium.org']), + 'messages': set(['msg1', 'msg2']), + }, cc_set_and_messages) + + def test_cc_and_message_rules_no_matches(self): + watch_list = self._watch_list_parser.parse( + '{' + ' "DEFINITIONS": {' + ' "WatchList1": {' + ' "filename": r"WebCore/rendering/style/ThisFileDoesNotExist\.h",' + ' },' + ' },' + ' "CC_RULES": {' + ' "WatchList2|WatchList1|WatchList3": [ "levin@chromium.org", ],' + ' },' + ' "MESSAGE_RULES": {' + ' "WatchList2|WatchList1|WatchList3": [ "msg1", "msg2", ],' + ' },' + '}') + cc_set_and_messages = watch_list.determine_cc_set_and_messages(DIFF_TEST_DATA) + self.assertEquals({ + 'cc_set': set(), + 'messages': set(), + }, cc_set_and_messages) diff --git a/Tools/Scripts/webkitpy/common/watchlist/watchlistparser.py b/Tools/Scripts/webkitpy/common/watchlist/watchlistparser.py index 846cabe..f3cc118 100644 --- a/Tools/Scripts/webkitpy/common/watchlist/watchlistparser.py +++ b/Tools/Scripts/webkitpy/common/watchlist/watchlistparser.py @@ -29,14 +29,21 @@ import re from webkitpy.common.watchlist.watchlist import WatchList from webkitpy.common.watchlist.filenamepattern import FilenamePattern +from webkitpy.common.watchlist.watchlistrule import WatchListRule class WatchListParser(object): _DEFINITIONS = 'DEFINITIONS' + _CC_RULES = 'CC_RULES' + _MESSAGE_RULES = 'MESSAGE_RULES' _INVALID_DEFINITION_NAME_REGEX = r'\|' def __init__(self): - self._section_parsers = {self._DEFINITIONS: self._parse_definition_section, } + self._section_parsers = { + self._DEFINITIONS: self._parse_definition_section, + self._CC_RULES: self._parse_cc_rules, + self._MESSAGE_RULES: self._parse_message_rules, + } self._definition_pattern_parsers = {'filename': FilenamePattern, } def parse(self, watch_list_contents): @@ -74,3 +81,15 @@ class WatchListParser(object): pattern = pattern_parser(definition[pattern_type]) definitions[name].append(pattern) watch_list.set_definitions(definitions) + + def _parse_rules(self, rules_section): + rules = [] + for complex_definition in rules_section: + rules.append(WatchListRule(complex_definition, rules_section[complex_definition])) + return rules + + def _parse_cc_rules(self, cc_section, watch_list): + watch_list.set_cc_rules(self._parse_rules(cc_section)) + + def _parse_message_rules(self, message_section, watch_list): + watch_list.set_message_rules(self._parse_rules(message_section)) diff --git a/Tools/Scripts/webkitpy/common/watchlist/watchlistrule.py b/Tools/Scripts/webkitpy/common/watchlist/watchlistrule.py new file mode 100644 index 0000000..ac3ea3c --- /dev/null +++ b/Tools/Scripts/webkitpy/common/watchlist/watchlistrule.py @@ -0,0 +1,43 @@ +# Copyright (C) 2011 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +class WatchListRule: + '''A rule with instructions to do when the rule is satisified.''' + def __init__(self, complex_definition, instructions): + self._definitions_to_match = complex_definition.split('|') + self._instructions = instructions + + def match(self, matching_definitions): + for test_definition in self._definitions_to_match: + if test_definition in matching_definitions: + return True + return False + + def instructions(self): + return self._instructions diff --git a/Tools/Scripts/webkitpy/common/watchlist/watchlistrule_unittest.py b/Tools/Scripts/webkitpy/common/watchlist/watchlistrule_unittest.py new file mode 100644 index 0000000..cb2985d --- /dev/null +++ b/Tools/Scripts/webkitpy/common/watchlist/watchlistrule_unittest.py @@ -0,0 +1,56 @@ +# Copyright (C) 2011 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +import unittest +from webkitpy.common.watchlist.watchlistrule import WatchListRule + + +class WatchListRuleTest(unittest.TestCase): + def test_action_list(self): + instructions = ['a', 'b'] + rule = WatchListRule('definition1', instructions[:]) + self.assertEqual(instructions, rule.instructions()) + + def test_simple_definition(self): + definition_name = 'definition1' + rule = WatchListRule(definition_name, []) + self.assertTrue(rule.match([definition_name])) + self.assertFalse(rule.match([definition_name + '1'])) + + def test_complex_definition(self): + definition_name1 = 'definition1' + definition_name2 = 'definition2' + definition_name3 = 'definition3' + rule = WatchListRule(definition_name1 + '|' + definition_name2 + '|' + definition_name3, []) + self.assertTrue(rule.match([definition_name1])) + self.assertTrue(rule.match([definition_name2])) + self.assertTrue(rule.match([definition_name3])) + self.assertFalse(rule.match([definition_name1 + '1'])) + self.assertFalse(rule.match([definition_name2 + '1'])) + self.assertFalse(rule.match([definition_name3 + '1']))