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):