3 # Copyright (C) 2011 Patrick Gansterer <paroga@paroga.com>
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
8 # 1. Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # 2. Redistributions in binary form must reproduce the above copyright
11 # notice, this list of conditions and the following disclaimer in the
12 # documentation and/or other materials provided with the distribution.
14 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 """Checks WebKit style for ChangeLog files."""
29 from common import TabChecker
30 from webkitpy.common.checkout.changelog import parse_bug_id_from_changelog
33 class ChangeLogChecker(object):
35 """Processes text lines for checking style."""
37 def __init__(self, file_path, handle_style_error, should_line_be_checked):
38 self.file_path = file_path
39 self.handle_style_error = handle_style_error
40 self.should_line_be_checked = should_line_be_checked
41 self._tab_checker = TabChecker(file_path, handle_style_error)
43 def check_entry(self, first_line_checked, entry_lines):
46 for line in entry_lines:
47 if parse_bug_id_from_changelog(line):
49 if re.search("Unreviewed", line, re.IGNORECASE):
51 if re.search("build", line, re.IGNORECASE) and re.search("fix", line, re.IGNORECASE):
54 self.handle_style_error(first_line_checked,
55 "changelog/bugnumber", 5,
56 "ChangeLog entry has no bug number")
57 # check file change descriptions for style violations
58 line_no = first_line_checked - 1
59 for line in entry_lines:
61 # filter file change descriptions
62 if not re.match('\s*\*\s', line):
64 if re.search(':\s*$', line) or re.search(':\s', line):
66 self.handle_style_error(line_no,
67 "changelog/filechangedescriptionwhitespace", 5,
68 "Need whitespace between colon and description")
71 def check(self, lines):
72 self._tab_checker.check(lines)
73 first_line_checked = 0
76 for line_index, line in enumerate(lines):
77 if not self.should_line_be_checked(line_index + 1):
78 # If we transitioned from finding changed lines to
79 # unchanged lines, then we are done.
80 if first_line_checked:
83 if not first_line_checked:
84 first_line_checked = line_index + 1
85 entry_lines.append(line)
87 self.check_entry(first_line_checked, entry_lines)