[pypy-svn] buildbot default: ignore duplicate commits in case the same payload is sent twice by bitbucket

antocuni commits-noreply at bitbucket.org
Mon Apr 18 10:53:42 CEST 2011


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: 
Changeset: r449:56a99650a46b
Date: 2011-04-18 10:50 +0200
http://bitbucket.org/pypy/buildbot/changeset/56a99650a46b/

Log:	ignore duplicate commits in case the same payload is sent twice by
	bitbucket

diff --git a/bitbucket_hook/hook.py b/bitbucket_hook/hook.py
--- a/bitbucket_hook/hook.py
+++ b/bitbucket_hook/hook.py
@@ -76,6 +76,22 @@
 
 class BitbucketHookHandler(object):
     Popen, PIPE = Popen, PIPE
+
+    def __init__(self):
+        self.seen_nodes = set()
+
+    def get_commits(self, service, payload):
+        import operator
+        commits = sorted(self.payload['commits'],
+                         key=operator.itemgetter('revision'))
+        for commit in commits:
+            node = commit['raw_node']
+            key = service, node
+            if key in self.seen_nodes:
+                continue
+            self.seen_nodes.add(key)
+            yield commit
+
     def _hgexe(self, argv):
         proc = self.Popen([hgexe] + list(argv), stdout=self.PIPE,
                           stderr=self.PIPE)
@@ -119,12 +135,15 @@
         else:
             return self.call_subprocess([BOT, CHANNEL, message])
 
+    def check_for_local_repo(self, local_repo):
+        return local_repo.check(dir=True)
+
     def handle(self, payload, test=False):
         path = payload['repository']['absolute_url']
         self.payload = payload
         self.local_repo = LOCAL_REPOS.join(path)
         self.remote_repo = REMOTE_BASE + path
-        if not self.local_repo.check(dir=True):
+        if not self.check_for_local_repo(self.local_repo):
             print >> sys.stderr, 'Ignoring unknown repo', path
             return
         self.hg('pull', '-R', self.local_repo)
@@ -134,9 +153,7 @@
     USE_COLOR_CODES = True
     LISTFILES = False
     def handle_irc_message(self, test=False):
-        import operator
-        commits = sorted(self.payload['commits'],
-                         key=operator.itemgetter('revision'))
+        commits = self.get_commits('irc', self.payload)
         if test:
             print "#" * 20
             print "IRC messages:"
@@ -171,9 +188,7 @@
             self.send_irc_message(irc_msg, test)
 
     def handle_diff_email(self, test=False):
-        import operator
-        commits = sorted(self.payload['commits'],
-                         key=operator.itemgetter('revision'))
+        commits = self.get_commits('email', self.payload)
         for commit in commits:
             self.send_diff_for_commit(commit, test)
 

diff --git a/bitbucket_hook/test/test_hook.py b/bitbucket_hook/test/test_hook.py
--- a/bitbucket_hook/test/test_hook.py
+++ b/bitbucket_hook/test/test_hook.py
@@ -4,12 +4,19 @@
 
 class BaseHandler(BitbucketHookHandler):
 
+    USE_COLOR_CODES = False
+
     def __init__(self):
+        BitbucketHookHandler.__init__(self)
         self.mails = []
+        self.messages = []
 
     def send(self, from_, to, subject, body, test=False):
         self.mails.append((from_, to, subject, body))
 
+    def send_irc_message(self, message, test=False):
+        self.messages.append(message)
+
 
 def test_non_ascii_encoding_guess_utf8():
     class MyHandler(BaseHandler):
@@ -34,14 +41,15 @@
 def test_sort_commits():
     class MyHandler(BaseHandler):
         def __init__(self):
+            BaseHandler.__init__(self)
             self.sent_commits = []
         def send_diff_for_commit(self, commit, test=False):
             self.sent_commits.append(commit['node'])
     #
     handler = MyHandler()
     handler.payload = {
-        'commits': [{'revision': 43, 'node': 'second'},
-                    {'revision': 42, 'node': 'first'}]
+        'commits': [{'revision': 43, 'node': 'second', 'raw_node': 'first'},
+                    {'revision': 42, 'node': 'first', 'raw_node': 'second'}]
         }
     handler.handle_diff_email()
     assert handler.sent_commits == ['first', 'second']
@@ -182,26 +190,21 @@
 
 
 def test_irc_message():
-    class MyHandler(BaseHandler):
-        USE_COLOR_CODES = False
-        def __init__(self):
-            self.messages = []
-        def send_irc_message(self, message, test=False):
-            self.messages.append(message)
-
-    handler = MyHandler()
+    handler = BaseHandler()
     handler.payload = {
         'commits': [{'revision': 42,
                      'branch': u'default',
                      'author': u'antocuni',
                      'message': u'this is a test',
-                     'node': 'abcdef'
+                     'node': 'abcdef',
+                     'raw_node': 'abcdef',
                      },
                     {'revision': 43,
                      'author': u'antocuni',
                      'branch': u'mybranch',
                      'message': LONG_MESSAGE,
-                     'node': 'xxxyyy'
+                     'node': 'xxxyyy',
+                     'raw_node': 'xxxyyy',
                      }
                     ]}
 
@@ -246,3 +249,26 @@
     handler.handle(test_payload)
     handler.handle(test_payload, test=True)
 
+
+def test_ignore_duplicate_commits():
+    class MyHandler(BaseHandler):
+        def hg(self, *args):
+            return '<hg %s>' % ' '.join(map(str, args))
+        def check_for_local_repo(self, local_repo):
+            return True
+
+    handler = MyHandler()
+    commits, _ = irc_cases()
+    payload = {u'repository': {u'absolute_url': '',
+                               u'name': u'test',
+                               u'owner': u'antocuni',
+                               u'slug': u'test',
+                               u'website': u''},
+               u'user': u'antocuni',
+               'commits': commits['commits']}
+    handler.handle(payload)
+    handler.handle(payload)
+    #
+    num_commits = len(commits['commits'])
+    assert len(handler.mails) == num_commits
+    assert len(handler.messages) == num_commits


More information about the Pypy-commit mailing list