1cad810f21b803229eb11403f9209855525a25d57Steve Block# Copyright (C) 2010 Google Inc. All rights reserved. 2cad810f21b803229eb11403f9209855525a25d57Steve Block# 3cad810f21b803229eb11403f9209855525a25d57Steve Block# Redistribution and use in source and binary forms, with or without 4cad810f21b803229eb11403f9209855525a25d57Steve Block# modification, are permitted provided that the following conditions are 5cad810f21b803229eb11403f9209855525a25d57Steve Block# met: 6cad810f21b803229eb11403f9209855525a25d57Steve Block# 7cad810f21b803229eb11403f9209855525a25d57Steve Block# * Redistributions of source code must retain the above copyright 8cad810f21b803229eb11403f9209855525a25d57Steve Block# notice, this list of conditions and the following disclaimer. 9cad810f21b803229eb11403f9209855525a25d57Steve Block# * Redistributions in binary form must reproduce the above 10cad810f21b803229eb11403f9209855525a25d57Steve Block# copyright notice, this list of conditions and the following disclaimer 11cad810f21b803229eb11403f9209855525a25d57Steve Block# in the documentation and/or other materials provided with the 12cad810f21b803229eb11403f9209855525a25d57Steve Block# distribution. 13cad810f21b803229eb11403f9209855525a25d57Steve Block# * Neither the name of Google Inc. nor the names of its 14cad810f21b803229eb11403f9209855525a25d57Steve Block# contributors may be used to endorse or promote products derived from 15cad810f21b803229eb11403f9209855525a25d57Steve Block# this software without specific prior written permission. 16cad810f21b803229eb11403f9209855525a25d57Steve Block# 17cad810f21b803229eb11403f9209855525a25d57Steve Block# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18cad810f21b803229eb11403f9209855525a25d57Steve Block# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19cad810f21b803229eb11403f9209855525a25d57Steve Block# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20cad810f21b803229eb11403f9209855525a25d57Steve Block# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21cad810f21b803229eb11403f9209855525a25d57Steve Block# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22cad810f21b803229eb11403f9209855525a25d57Steve Block# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23cad810f21b803229eb11403f9209855525a25d57Steve Block# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24cad810f21b803229eb11403f9209855525a25d57Steve Block# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25cad810f21b803229eb11403f9209855525a25d57Steve Block# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26cad810f21b803229eb11403f9209855525a25d57Steve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27cad810f21b803229eb11403f9209855525a25d57Steve Block# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28cad810f21b803229eb11403f9209855525a25d57Steve Block 29cad810f21b803229eb11403f9209855525a25d57Steve Blockfrom webkitpy.tool.steps.abstractstep import AbstractStep 30cad810f21b803229eb11403f9209855525a25d57Steve Blockfrom webkitpy.tool.steps.options import Options 31cad810f21b803229eb11403f9209855525a25d57Steve Blockfrom webkitpy.common.checkout.diff_parser import DiffParser 32cad810f21b803229eb11403f9209855525a25d57Steve Blockfrom webkitpy.common.system.deprecated_logging import error, log 33cad810f21b803229eb11403f9209855525a25d57Steve Block 34cad810f21b803229eb11403f9209855525a25d57Steve Block 35cad810f21b803229eb11403f9209855525a25d57Steve Block# This is closely related to the ValidateReviewer step and the CommitterValidator class. 36cad810f21b803229eb11403f9209855525a25d57Steve Block# We may want to unify more of this code in one place. 37cad810f21b803229eb11403f9209855525a25d57Steve Blockclass ValidateChangeLogs(AbstractStep): 38cad810f21b803229eb11403f9209855525a25d57Steve Block def _check_changelog_diff(self, diff_file): 39cad810f21b803229eb11403f9209855525a25d57Steve Block if not self._tool.checkout().is_path_to_changelog(diff_file.filename): 40cad810f21b803229eb11403f9209855525a25d57Steve Block return True 41cad810f21b803229eb11403f9209855525a25d57Steve Block # Each line is a tuple, the first value is the deleted line number 42cad810f21b803229eb11403f9209855525a25d57Steve Block # Date, reviewer, bug title, bug url, and empty lines could all be 43cad810f21b803229eb11403f9209855525a25d57Steve Block # identical in the most recent entries. If the diff starts any 44cad810f21b803229eb11403f9209855525a25d57Steve Block # later than that, assume that the entry is wrong. 45cad810f21b803229eb11403f9209855525a25d57Steve Block if diff_file.lines[0][0] < 8: 46cad810f21b803229eb11403f9209855525a25d57Steve Block return True 4765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if self._options.non_interactive: 4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return False 4965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 50cad810f21b803229eb11403f9209855525a25d57Steve Block log("The diff to %s looks wrong. Are you sure your ChangeLog entry is at the top of the file?" % (diff_file.filename)) 51cad810f21b803229eb11403f9209855525a25d57Steve Block # FIXME: Do we need to make the file path absolute? 52cad810f21b803229eb11403f9209855525a25d57Steve Block self._tool.scm().diff_for_file(diff_file.filename) 53cad810f21b803229eb11403f9209855525a25d57Steve Block if self._tool.user.confirm("OK to continue?", default='n'): 54cad810f21b803229eb11403f9209855525a25d57Steve Block return True 55cad810f21b803229eb11403f9209855525a25d57Steve Block return False 56cad810f21b803229eb11403f9209855525a25d57Steve Block 57cad810f21b803229eb11403f9209855525a25d57Steve Block def run(self, state): 58cad810f21b803229eb11403f9209855525a25d57Steve Block parsed_diff = DiffParser(self.cached_lookup(state, "diff").splitlines()) 59cad810f21b803229eb11403f9209855525a25d57Steve Block for filename, diff_file in parsed_diff.files.items(): 60cad810f21b803229eb11403f9209855525a25d57Steve Block if not self._check_changelog_diff(diff_file): 61cad810f21b803229eb11403f9209855525a25d57Steve Block error("ChangeLog entry in %s is not at the top of the file." % diff_file.filename) 62