Changeset 140511 in webkit


Ignore:
Timestamp:
Jan 22, 2013 11:22:31 PM (11 years ago)
Author:
commit-queue@webkit.org
Message:

prepare-Changelog should support updating the list of changed files
https://bugs.webkit.org/show_bug.cgi?id=74358

Patch by Timothy Loh <timloh@chromium.com> on 2013-01-22
Reviewed by Eric Seidel.

Needing to re-make ChangeLog entries when the list of files/functions
changes is a bit annoying, it'd be nice to have this more automated.
This patch makes `webkit-patch update' update the date line and bug
description if needed, and if the list of changed files/functions has
changed, either updates the list (if there are no annotations), or
otherwise appends the new list below.

  • Scripts/webkitpy/tool/steps/preparechangelog.py:

(PrepareChangeLog._resolve_existing_entry):
(PrepareChangeLog):
(PrepareChangeLog._merge_entries):
(PrepareChangeLog.run):

  • Scripts/webkitpy/tool/steps/preparechangelog_unittest.py:

(PrepareChangeLogTest.test_resolve_existing_entry):
(make_entry):
(test_ensure_bug_url):

Location:
trunk/Tools
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r140510 r140511  
     12013-01-22  Timothy Loh  <timloh@chromium.com>
     2
     3        prepare-Changelog should support updating the list of changed files
     4        https://bugs.webkit.org/show_bug.cgi?id=74358
     5
     6        Reviewed by Eric Seidel.
     7
     8        Needing to re-make ChangeLog entries when the list of files/functions
     9        changes is a bit annoying, it'd be nice to have this more automated.
     10        This patch makes `webkit-patch update' update the date line and bug
     11        description if needed, and if the list of changed files/functions has
     12        changed, either updates the list (if there are no annotations), or
     13        otherwise appends the new list below.
     14
     15        * Scripts/webkitpy/tool/steps/preparechangelog.py:
     16        (PrepareChangeLog._resolve_existing_entry):
     17        (PrepareChangeLog):
     18        (PrepareChangeLog._merge_entries):
     19        (PrepareChangeLog.run):
     20        * Scripts/webkitpy/tool/steps/preparechangelog_unittest.py:
     21        (PrepareChangeLogTest.test_resolve_existing_entry):
     22        (make_entry):
     23        (test_ensure_bug_url):
     24
    1252013-01-22  Tim 'mithro' Ansell  <mithro@mithis.com>
    226
  • trunk/Tools/Scripts/webkitpy/tool/steps/preparechangelog.py

    r138775 r140511  
    2727# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2828
     29import codecs
    2930import logging
     31import os
     32import re
    3033import sys
    3134
     
    5962                    self._tool.bugs.bug_url_for_bug_id(bug_id))
    6063
     64    def _resolve_existing_entry(self, changelog_path):
     65        # When this is called, the top entry in the ChangeLog was just created
     66        # by prepare-ChangeLog, as an clean updated version of the one below it.
     67        with codecs.open(changelog_path, "r", "utf-8") as changelog_file:
     68            entries_gen = ChangeLog.parse_entries_from_file(changelog_file)
     69            entries = zip(entries_gen, range(2))
     70
     71        if not len(entries):
     72            raise Exception("Expected to find at least two ChangeLog entries in %s but found none." % changelog_path)
     73        if len(entries) == 1:
     74            # If we get here, it probably means we've just rolled over to a
     75            # new CL file, so we don't have anything to resolve.
     76            return
     77
     78        (new_entry, _), (old_entry, _) = entries
     79        final_entry = self._merge_entries(old_entry, new_entry)
     80
     81        changelog = ChangeLog(changelog_path)
     82        changelog.delete_entries(2)
     83        changelog.prepend_text(final_entry)
     84
     85    def _merge_entries(self, old_entry, new_entry):
     86        final_entry = old_entry.contents()
     87
     88        new_date_line = new_entry.date_line()
     89        old_date_line = old_entry.date_line()
     90        if new_date_line != old_date_line:
     91            final_entry = final_entry.replace(old_date_line, new_date_line)
     92
     93        new_bug_desc = new_entry.bug_description()
     94        old_bug_desc = old_entry.bug_description()
     95        if new_bug_desc and old_bug_desc and new_bug_desc != old_bug_desc:
     96            final_entry = final_entry.replace(old_bug_desc, new_bug_desc)
     97
     98        new_touched = new_entry.touched_functions()
     99        old_touched = old_entry.touched_functions()
     100        if new_touched != old_touched:
     101            if old_entry.is_touched_files_text_clean():
     102                final_entry = final_entry.replace(old_entry.touched_files_text(), new_entry.touched_files_text())
     103            else:
     104                final_entry += "\n" + new_entry.touched_files_text()
     105
     106        return final_entry + "\n"
     107
    61108    def run(self, state):
    62109        if self.cached_lookup(state, "changelogs"):
    63110            self._ensure_bug_url(state)
    64             return
     111
    65112        args = self._tool.deprecated_port().prepare_changelog_command()
    66113        if state.get("bug_id"):
     
    76123
    77124        try:
    78             self._tool.executive.run_and_throw_if_fail(args, self._options.quiet, cwd=self._tool.scm().checkout_root)
     125            output = self._tool.executive.run_and_throw_if_fail(args, self._options.quiet, cwd=self._tool.scm().checkout_root)
    79126        except ScriptError, e:
    80127            _log.error("Unable to prepare ChangeLogs.")
    81128            sys.exit(1)
     129
     130        # These are the ChangeLog entries added by prepare-Changelog
     131        changelogs = re.findall(r'Editing the (\S*/ChangeLog) file.', output)
     132        changelogs = set(os.path.join(self._tool.scm().checkout_root, f) for f in changelogs)
     133        for changelog in changelogs & set(self.cached_lookup(state, "changelogs")):
     134            self._resolve_existing_entry(changelog)
     135
    82136        self.did_modify_checkout(state)
  • trunk/Tools/Scripts/webkitpy/tool/steps/preparechangelog_unittest.py

    r140510 r140511  
    3737from webkitpy.tool.steps.preparechangelog import PrepareChangeLog
    3838
     39# FIXME: These tests should use a MockFileSystem instead of a real file system,
     40# once changelog.py and preparechangelog.py are FileSystem compatible.
    3941
    4042class PrepareChangeLogTest(changelog_unittest.ChangeLogTest):
     43    def test_resolve_existing_entry(self):
     44        step = PrepareChangeLog(MockTool(), MockOptions())
     45
     46        roll_over = "== Rolled over to ChangeLog-2012-10-02 =="
     47
     48        headers = ["2013-01-18  Timothy Loh  <timloh@chromium.com>\n\n",
     49                   "2013-01-20  Timothy Loh  <timloh@chromium.com>\n\n",
     50                  u"2009-08-17  Tor Arne Vestb\xf8  <vestbo@webkit.org>\n\n",
     51                  u"2009-08-18  Tor Arne Vestb\xf8  <vestbo@webkit.org>\n\n",
     52                  ]
     53
     54        bug_descs = ["        prepare-Changelog should support updating the list of changed files\n",
     55                     "        webkit-patch upload should support updating the list of changed files\n"]
     56
     57        bug_url = "        https://bugs.webkit.org/show_bug.cgi?id=74358\n\n"
     58
     59        descriptions = ["", "        A description of the changes.\n\n",
     60                "        A description.\n\n        With some\n        line breaks\n\n"]
     61
     62        changes = [
     63"""        * Scripts/webkitpy/tool/steps/preparechangelog.py:
     64        (PrepareChangeLog):
     65        (PrepareChangeLog.run):\n\n""",
     66"""        * Scripts/webkitpy/tool/steps/preparechangelog.py:
     67        (PrepareChangeLog._resolve_existing_entry):
     68        (PrepareChangeLog):
     69        (PrepareChangeLog.run):\n\n""",
     70"""        * Scripts/webkitpy/tool/steps/preparechangelog.py:
     71        (PrepareChangeLog): Some annotations
     72        (PrepareChangeLog.run):
     73            More annotations\n\n""",
     74"""        * Scripts/webkitpy/tool/steps/preparechangelog.py:
     75        (PrepareChangeLog): Some annotations
     76        (PrepareChangeLog.run):
     77            More annotations
     78
     79        * Scripts/webkitpy/tool/steps/preparechangelog.py:
     80        (PrepareChangeLog._resolve_existing_entry):
     81        (PrepareChangeLog):
     82        (PrepareChangeLog.run):\n\n""",
     83            ]
     84
     85        def make_entry(indices):
     86            a, b, c, d = indices
     87            return headers[a] + bug_descs[b] + bug_url + descriptions[c] + changes[d]
     88
     89        test_cases = [((0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0)),
     90                      ((0, 0, 0, 0), (0, 0, 1, 0), (0, 0, 1, 0)),
     91                      ((1, 0, 0, 0), (0, 0, 2, 0), (1, 0, 2, 0)),
     92                      ((0, 1, 0, 0), (0, 0, 1, 0), (0, 1, 1, 0)),
     93                      ((0, 0, 0, 1), (0, 0, 0, 0), (0, 0, 0, 1)),
     94                      ((0, 0, 0, 0), (0, 0, 1, 1), (0, 0, 1, 0)),
     95                      ((0, 0, 0, 0), (0, 0, 2, 2), (0, 0, 2, 2)),
     96                      ((0, 0, 0, 1), (0, 0, 1, 2), (0, 0, 1, 3)),
     97                      ((1, 1, 0, 1), (0, 0, 0, 2), (1, 1, 0, 3)),
     98                      ((3, 0, 0, 0), (2, 0, 1, 0), (3, 0, 1, 0)),
     99        ]
     100
     101        for new, old, final in test_cases:
     102            new_entry = make_entry(new)
     103            old_entry = make_entry(old)
     104            start_file = new_entry + old_entry + roll_over
     105
     106            final_entry = make_entry(final)
     107            end_file = final_entry + roll_over
     108
     109            path = self._write_tmp_file_with_contents(start_file.encode("utf-8"))
     110            step._resolve_existing_entry(path)
     111            actual_output = self._read_file_contents(path, "utf-8")
     112            self.assertEquals(actual_output, end_file)
     113
    41114    def test_ensure_bug_url(self):
    42         # FIXME: This should use a MockFileSystem instead of a real FileSystem.
    43115        capture = OutputCapture()
    44116        step = PrepareChangeLog(MockTool(), MockOptions())
     
    50122            "changelogs": [changelog_path],
    51123        }
    52         capture.assert_outputs(self, step.run, [state])
     124        capture.assert_outputs(self, step._ensure_bug_url, [state])
    53125        actual_contents = self._read_file_contents(changelog_path, "utf-8")
    54126        expected_message = "Example title\n        http://example.com/1234"
Note: See TracChangeset for help on using the changeset viewer.