Bug 1001106 - Add a repository hook to enforce new review requirements for changing .webidl files; r=ted
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 28 Apr 2014 15:33:35 -0400
changeset 184 cacacc4b45e03c9b3729d0fe5f0ce070649e7d41
parent 183 c4662670ff3cfd8fac40594cab7507af1ea89090
child 185 723018c7baf1155adf3c940d5869a52044ca32fe
push id112
push usereakhgari@mozilla.com
push dateMon, 28 Apr 2014 19:34:15 +0000
reviewersted
bugs1001106
Bug 1001106 - Add a repository hook to enforce new review requirements for changing .webidl files; r=ted
mozhghooks/prevent_webidl_changes.py
runtests.py
new file mode 100755
--- /dev/null
+++ b/mozhghooks/prevent_webidl_changes.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python
+# Copyright (C) 2012 Mozilla Foundation
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+"""
+This hook is to prevent changes to .webidl files in pushes without proper DOM peer review.
+"""
+
+import re
+
+def hook(ui, repo, hooktype, node, **kwargs):
+    DOM_peers = [
+        'jst',              # Johnny Stenback
+        'peterv',           # Peter Van der Beken
+        'bz', 'bzbarsky',   # Boris Zbarsky
+        'sicking', 'jonas', # Jonas Sicking
+        'smaug',            # Olli Pettay
+        'bent',             # Ben Turner
+        'mounir',           # Mounir Lamouri
+        'khuey',            # Kyle Huey
+        'jlebar',           # Justin Lebar
+        'hsivonen',         # Henri Sivonen
+        'mrbkap',           # Blake Kaplan
+        'bholley',          # Bobby Holley
+    ]
+    error = ""
+    webidlReviewed = False
+    # Loop through each changeset being added to the repository
+    for change_id in xrange(repo[node].rev(), len(repo)):
+        # Loop through each file for the current changeset
+        for file in repo[change_id].files():
+            # Only Check WebIDL Files
+            if file.endswith('.webidl'):
+                webidlReviewed = True
+                match = re.search('\Wr\s*=\s*(\w+(?:,\w+)*)', repo.changectx('tip').description().lower())
+                validReview = False
+                if match:
+                    for reviewer in match.group(1).split(','):
+                        if reviewer in DOM_peers:
+                            validReview = True
+                            break
+                if not validReview:
+                        error += "WebIDL file %s altered in this changeset without DOM peer review" % file
+    # Check if an error occured in any of the files that were changed
+    if error != "":
+        print "\n\n************************** ERROR ****************************"
+        ui.warn("\n\r*** " + error + "***\n\r")
+        print "\n\rChanges to WebIDL files in this repo require review from a DOM peer in the form of r=...\n\rThis is to ensure that we behave responsibly with exposing new Web APIs. We appreciate your understanding..\n\r"
+        print "*************************************************************\n\n"
+        # Reject the changesets
+        return 1
+    else:
+        if webidlReviewed:
+            print "You've received proper review from a DOM peer on your WebIDL change(s) in your push, thanks for paying enough attention."
+    # Accept the changesets
+    return 0
--- a/runtests.py
+++ b/runtests.py
@@ -860,10 +860,54 @@ class TestPreventUUIDHook(unittest.TestC
 
   def testUUIDDeletedIDLNoApproveShouldFail(self):
     """ Test that changeset with .idl file removed should fail without approval"""
     u = self.ui
     remove(u, self.clonerepo, join(self.clonedir, "original.idl"))
     commit(u, self.clonerepo, message="checkin 2 removed idl file ")
     self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
 
+class TestPreventWebIDLHook(unittest.TestCase):
+  def setUp(self):
+    self.ui = ui.ui()
+    self.ui.quiet = True
+    self.ui.verbose = False
+    self.repodir = mkdtemp(prefix="hg-TestPreventWebIDLHook")
+    init(self.ui, dest=self.repodir)
+    addHook(self.repodir, "prevent_webidl_changes.hook")
+    self.repo = hg.repository(self.ui, self.repodir)
+    self.clonedir = mkdtemp(prefix="hg-test")
+    clone(self.ui, self.repo, self.clonedir)
+    self.clonerepo = hg.repository(self.ui, self.clonedir)
+    # Create a pre-existing repo with a file that contains UUID
+    appendFile(join(self.clonedir, "original.webidl"), "interface Foo{};")
+    add(self.ui, self.clonerepo, join(self.clonedir, "original.webidl"))
+    commit(self.ui, self.clonerepo, message="original repo commit r=jst")
+    push(self.ui, self.clonerepo, dest=self.repodir)
+
+  def tearDown(self):
+    shutil.rmtree(self.repodir)
+    shutil.rmtree(self.clonedir)
+
+  def testWebIDLEditWithoutReviewShouldFail(self):
+    """ Test that editing .webidl file without review should fail """
+    u = self.ui
+    editFile(join(self.clonedir, "original.webidl"), "interface Foo{};", "interface Bar{};")
+    commit(u, self.clonerepo, message="checkin 1 bug 12345")
+    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
+
+  def testWebIDLEditWithoutProperReviewShouldFail(self):
+    """ Test that editing .webidl file without proper DOM peer review should fail """
+    u = self.ui
+    editFile(join(self.clonedir, "original.webidl"), "interface Foo{};", "interface Bar{};")
+    commit(u, self.clonerepo, message="checkin 1 bug 12345; r=foobar")
+    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
+
+  def testWebIDLEditWithProperReviewShouldPass(self):
+    """ Test that editing .webidl file with proper DOM peer review should pass """
+    u = self.ui
+    editFile(join(self.clonedir, "original.webidl"), "interface Foo{};", "interface Bar{};")
+    commit(u, self.clonerepo, message="checkin 1 bug 12345; r=foobar,jst")
+    result = push(u, self.clonerepo, dest=self.repodir)
+    self.assertEqual(result, 0)
+
 if __name__ == '__main__':
   unittest.main()