Title: [90968] trunk/Tools
Revision
90968
Author
[email protected]
Date
2011-07-13 18:39:12 -0700 (Wed, 13 Jul 2011)

Log Message

gardening server should have an API for parsing changelogs
https://bugs.webkit.org/show_bug.cgi?id=64495

Reviewed by Eric Seidel.

This patch exposes much of the same information from CommitInfo in a
dictionary form, which is easier to send over-the-wire as JSON to the
frontend.

* Scripts/webkitpy/common/checkout/checkout.py:
* Scripts/webkitpy/common/checkout/checkout_unittest.py:
* Scripts/webkitpy/tool/mocktool.py:
* Scripts/webkitpy/tool/servers/gardeningserver.py:
* Scripts/webkitpy/tool/servers/gardeningserver_unittest.py:
* Scripts/webkitpy/tool/servers/reflectionhandler.py:

Modified Paths

Diff

Modified: trunk/Tools/ChangeLog (90967 => 90968)


--- trunk/Tools/ChangeLog	2011-07-14 01:03:02 UTC (rev 90967)
+++ trunk/Tools/ChangeLog	2011-07-14 01:39:12 UTC (rev 90968)
@@ -1,3 +1,21 @@
+2011-07-13  Adam Barth  <[email protected]>
+
+        gardening server should have an API for parsing changelogs
+        https://bugs.webkit.org/show_bug.cgi?id=64495
+
+        Reviewed by Eric Seidel.
+
+        This patch exposes much of the same information from CommitInfo in a
+        dictionary form, which is easier to send over-the-wire as JSON to the
+        frontend.
+
+        * Scripts/webkitpy/common/checkout/checkout.py:
+        * Scripts/webkitpy/common/checkout/checkout_unittest.py:
+        * Scripts/webkitpy/tool/mocktool.py:
+        * Scripts/webkitpy/tool/servers/gardeningserver.py:
+        * Scripts/webkitpy/tool/servers/gardeningserver_unittest.py:
+        * Scripts/webkitpy/tool/servers/reflectionhandler.py:
+
 2011-07-13  Eric Seidel  <[email protected]>
 
         REGRESSION: GitTestWithMock.test_create_patch fails

Modified: trunk/Tools/Scripts/webkitpy/common/checkout/checkout.py (90967 => 90968)


--- trunk/Tools/Scripts/webkitpy/common/checkout/checkout.py	2011-07-14 01:03:02 UTC (rev 90967)
+++ trunk/Tools/Scripts/webkitpy/common/checkout/checkout.py	2011-07-14 01:39:12 UTC (rev 90968)
@@ -58,8 +58,9 @@
         changelog_file = StringIO.StringIO(changelog_contents.decode("utf-8", "ignore"))
         return ChangeLog.parse_latest_entry_from_file(changelog_file)
 
-    def changelog_entries_for_revision(self, revision):
-        changed_files = self._scm.changed_files_for_revision(revision)
+    def changelog_entries_for_revision(self, revision, changed_files=None):
+        if not changed_files:
+            changed_files = self._scm.changed_files_for_revision(revision)
         # FIXME: This gets confused if ChangeLog files are moved, as
         # deletes are still "changed files" per changed_files_for_revision.
         # FIXME: For now we hack around this by caching any exceptions
@@ -74,26 +75,31 @@
                 pass
         return changelog_entries
 
-    @memoized
-    def commit_info_for_revision(self, revision):
-        committer_email = self._scm.committer_email_for_revision(revision)
-        changelog_entries = self.changelog_entries_for_revision(revision)
+    def _changelog_data_for_revision(self, revision):
+        changed_files = self._scm.changed_files_for_revision(revision)
+        changelog_entries = self.changelog_entries_for_revision(revision, changed_files=changed_files)
         # Assume for now that the first entry has everything we need:
         # FIXME: This will throw an exception if there were no ChangeLogs.
         if not len(changelog_entries):
             return None
         changelog_entry = changelog_entries[0]
-        changelog_data = {
+        return {
             "bug_id": parse_bug_id_from_changelog(changelog_entry.contents()),
             "author_name": changelog_entry.author_name(),
             "author_email": changelog_entry.author_email(),
             "author": changelog_entry.author(),
             "reviewer_text": changelog_entry.reviewer_text(),
             "reviewer": changelog_entry.reviewer(),
+            "contents": changelog_entry.contents(),
+            "changed_files": changed_files,
         }
-        # We could pass the changelog_entry instead of a dictionary here, but that makes
-        # mocking slightly more involved, and would make aggregating data from multiple
-        # entries more difficult to wire in if we need to do that in the future.
+
+    @memoized
+    def commit_info_for_revision(self, revision):
+        committer_email = self._scm.committer_email_for_revision(revision)
+        changelog_data = self._changelog_data_for_revision(revision)
+        if not changelog_data:
+            return None
         return CommitInfo(revision, committer_email, changelog_data)
 
     def bug_id_for_revision(self, revision):

Modified: trunk/Tools/Scripts/webkitpy/common/checkout/checkout_unittest.py (90967 => 90968)


--- trunk/Tools/Scripts/webkitpy/common/checkout/checkout_unittest.py	2011-07-14 01:03:02 UTC (rev 90967)
+++ trunk/Tools/Scripts/webkitpy/common/checkout/checkout_unittest.py	2011-07-14 01:39:12 UTC (rev 90968)
@@ -178,9 +178,10 @@
 
     def test_commit_info_for_revision(self):
         scm = Mock()
-        scm.committer_email_for_revision = lambda revision: "[email protected]"
+        scm.changed_files_for_revision = lambda revision: ['path/to/file', 'another/file']
+        scm.committer_email_for_revision = lambda revision, changed_files=None: "[email protected]"
         checkout = Checkout(scm)
-        checkout.changelog_entries_for_revision = lambda revision: [ChangeLogEntry(_changelog1entry1)]
+        checkout.changelog_entries_for_revision = lambda revision, changed_files=None: [ChangeLogEntry(_changelog1entry1)]
         commitinfo = checkout.commit_info_for_revision(4)
         self.assertEqual(commitinfo.bug_id(), 36629)
         self.assertEqual(commitinfo.author_name(), u"Tor Arne Vestb\u00f8")
@@ -189,15 +190,25 @@
         self.assertEqual(commitinfo.reviewer(), None)
         self.assertEqual(commitinfo.committer_email(), "[email protected]")
         self.assertEqual(commitinfo.committer(), None)
+        self.assertEqual(commitinfo.to_json(), {
+            'bug_id': 36629,
+            'author_email': '[email protected]',
+            'changed_files': [
+                'path/to/file',
+                'another/file',
+            ],
+            'reviewer_text': None,
+            'author_name': u'Tor Arne Vestb\xf8',
+        })
 
-        checkout.changelog_entries_for_revision = lambda revision: []
+        checkout.changelog_entries_for_revision = lambda revision, changed_files=None: []
         self.assertEqual(checkout.commit_info_for_revision(1), None)
 
     def test_bug_id_for_revision(self):
         scm = Mock()
         scm.committer_email_for_revision = lambda revision: "[email protected]"
         checkout = Checkout(scm)
-        checkout.changelog_entries_for_revision = lambda revision: [ChangeLogEntry(_changelog1entry1)]
+        checkout.changelog_entries_for_revision = lambda revision, changed_files=None: [ChangeLogEntry(_changelog1entry1)]
         self.assertEqual(checkout.bug_id_for_revision(4), 36629)
 
     def test_bug_id_for_this_commit(self):
@@ -215,7 +226,7 @@
         self.assertEqual(checkout.modified_changelogs(git_commit=None), expected_changlogs)
 
     def test_suggested_reviewers(self):
-        def mock_changelog_entries_for_revision(revision):
+        def mock_changelog_entries_for_revision(revision, changed_files=None):
             if revision % 2 == 0:
                 return [ChangeLogEntry(_changelog1entry1)]
             return [ChangeLogEntry(_changelog1entry2)]

Modified: trunk/Tools/Scripts/webkitpy/common/checkout/commitinfo.py (90967 => 90968)


--- trunk/Tools/Scripts/webkitpy/common/checkout/commitinfo.py	2011-07-14 01:03:02 UTC (rev 90967)
+++ trunk/Tools/Scripts/webkitpy/common/checkout/commitinfo.py	2011-07-14 01:39:12 UTC (rev 90968)
@@ -36,12 +36,7 @@
     def __init__(self, revision, committer_email, changelog_data, committer_list=CommitterList()):
         self._revision = revision
         self._committer_email = committer_email
-        self._bug_id = changelog_data["bug_id"]
-        self._author_name = changelog_data["author_name"]
-        self._author_email = changelog_data["author_email"]
-        self._author = changelog_data["author"]
-        self._reviewer_text = changelog_data["reviewer_text"]
-        self._reviewer = changelog_data["reviewer"]
+        self._changelog_data = changelog_data
 
         # Derived values:
         self._committer = committer_list.committer_by_email(committer_email)
@@ -56,23 +51,35 @@
         return self._committer_email
 
     def bug_id(self):
-        return self._bug_id  # May be None
+        return self._changelog_data["bug_id"]  # May be None
 
     def author(self):
-        return self._author  # May be None
+        return self._changelog_data["author"]  # May be None
 
     def author_name(self):
-        return self._author_name
+        return self._changelog_data["author_name"]
 
     def author_email(self):
-        return self._author_email
+        return self._changelog_data["author_email"]
 
     def reviewer(self):
-        return self._reviewer # May be None
+        return self._changelog_data["reviewer"]  # May be None
 
     def reviewer_text(self):
-        return self._reviewer_text # May be None
+        return self._changelog_data["reviewer_text"]  # May be None
 
+    def changed_files(self):
+        return self._changelog_data["changed_files"]
+
+    def to_json(self):
+        return {
+            "bug_id": self.bug_id(),
+            "author_name": self.author_name(),
+            "author_email": self.author_email(),
+            "reviewer_text": self.reviewer_text(),
+            "changed_files": self.changed_files(),
+        }
+
     def responsible_parties(self):
         responsible_parties = [
             self.committer(),

Modified: trunk/Tools/Scripts/webkitpy/tool/mocktool.py (90967 => 90968)


--- trunk/Tools/Scripts/webkitpy/tool/mocktool.py	2011-07-14 01:03:02 UTC (rev 90967)
+++ trunk/Tools/Scripts/webkitpy/tool/mocktool.py	2011-07-14 01:39:12 UTC (rev 90968)
@@ -543,6 +543,10 @@
             "author": self._committer_list.contributor_by_email("[email protected]"),
             "reviewer_text": "Darin Adler",
             "reviewer": self._committer_list.committer_by_name("Darin Adler"),
+            "changed_files": [
+                "path/to/file",
+                "another/file",
+            ],
         })
 
     def is_path_to_changelog(self, path):

Modified: trunk/Tools/Scripts/webkitpy/tool/servers/gardeningserver.py (90967 => 90968)


--- trunk/Tools/Scripts/webkitpy/tool/servers/gardeningserver.py	2011-07-14 01:03:02 UTC (rev 90967)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/gardeningserver.py	2011-07-14 01:39:12 UTC (rev 90968)
@@ -55,6 +55,19 @@
     def _run_webkit_patch(self, args):
         return self.server.tool.executive.run_command([self.server.tool.path()] + args)
 
+    def changelog(self):
+        revision = self.query['revision'][0]
+        head_revision = self.server.tool.scm().head_svn_revision()
+        if revision > head_revision:
+            # Updating the working copy could conflict with any rebaselines we have in progress.
+            update_webkit_command = self.server.tool.port().update_webkit_command()
+            self.server.tool.executive.run_and_throw_if_fail(update_webkit_command, quiet=True)
+        commit_info = self.server.tool.checkout().commit_info_for_revision(revision)
+        if not commit_info:
+            self.send_error(404, "File not found")
+        else:
+            self._serve_json(commit_info.to_json())
+
     def rollout(self):
         revision = self.query['revision'][0]
         reason = self.query['reason'][0]

Modified: trunk/Tools/Scripts/webkitpy/tool/servers/gardeningserver_unittest.py (90967 => 90968)


--- trunk/Tools/Scripts/webkitpy/tool/servers/gardeningserver_unittest.py	2011-07-14 01:03:02 UTC (rev 90967)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/gardeningserver_unittest.py	2011-07-14 01:39:12 UTC (rev 90968)
@@ -26,6 +26,12 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+try:
+    import json
+except ImportError:
+    # python 2.5 compatibility
+    import webkitpy.thirdparty.simplejson as json
+
 import unittest
 
 from webkitpy.common.system.outputcapture import OutputCapture
@@ -51,19 +57,32 @@
         print text
         print "== End Response =="
 
+    def _serve_json(self, json_object):
+        print "== Begin JSON Response =="
+        print json.dumps(json_object)
+        print "== End JSON Response =="
 
+
 class GardeningServerTest(unittest.TestCase):
     def _post_to_path(self, path, expected_stderr=None, expected_stdout=None):
         handler = TestGardeningHTTPRequestHandler(MockServer())
         handler.path = path
         OutputCapture().assert_outputs(self, handler.do_POST, expected_stderr=expected_stderr, expected_stdout=expected_stdout)
 
+    def test_changelog(self):
+        expected_stderr = "MOCK run_and_throw_if_fail: ['mock-update-webkit']\n"
+        expected_stdout = """== Begin JSON Response ==
+{"bug_id": 42, "author_email": "[email protected]", "reviewer_text": "Darin Adler", "author_name": "Adam Barth", "changed_files": ["path/to/file", "another/file"]}
+== End JSON Response ==
+"""
+        self._post_to_path("/changelog?revision=2314", expected_stderr=expected_stderr, expected_stdout=expected_stdout)
+
     def test_rollout(self):
         expected_stderr = "MOCK run_command: ['echo', 'rollout', '--force-clean', '--non-interactive', '2314', 'MOCK rollout reason']\n"
         expected_stdout = "== Begin Response ==\nsuccess\n== End Response ==\n"
         self._post_to_path("/rollout?revision=2314&reason=MOCK+rollout+reason", expected_stderr=expected_stderr, expected_stdout=expected_stdout)
 
-    def test_rebaseline_test(self):
+    def test_rebaseline(self):
         expected_stderr = "MOCK run_command: ['echo', 'rebaseline-test', 'MOCK builder', 'user-scripts/another-test.html', 'txt']\n"
         expected_stdout = "== Begin Response ==\nsuccess\n== End Response ==\n"
         self._post_to_path("/rebaseline?builder=MOCK+builder&test=user-scripts/another-test.html&suffix=txt", expected_stderr=expected_stderr, expected_stdout=expected_stdout)

Modified: trunk/Tools/Scripts/webkitpy/tool/servers/reflectionhandler.py (90967 => 90968)


--- trunk/Tools/Scripts/webkitpy/tool/servers/reflectionhandler.py	2011-07-14 01:03:02 UTC (rev 90967)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/reflectionhandler.py	2011-07-14 01:39:12 UTC (rev 90968)
@@ -28,6 +28,12 @@
 
 from __future__ import with_statement
 
+try:
+    import json
+except ImportError:
+    # python 2.5 compatibility
+    import webkitpy.thirdparty.simplejson as json
+
 import BaseHTTPServer
 
 import codecs
@@ -92,11 +98,11 @@
         self.end_headers()
         self.wfile.write(text)
 
-    def _serve_json(self, json):
+    def _serve_json(self, json_object):
         self.send_response(200)
         self.send_header('Content-type', 'application/json')
         self.end_headers()
-        simplejson.dump(json, self.wfile)
+        json.dump(json_object, self.wfile)
 
     def _serve_file(self, file_path, cacheable_seconds=0):
         if not os.path.exists(file_path):
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to