[Buildbot-devel] Twisted exception with Buildbot 0.8.5 + Mercurial hook (Followup)

Bob Hood bhood2 at comcast.net
Sun May 26 19:34:06 UTC 2013


This is a follow-up.

I tried Benoît's suggestion, and enabled the 'fork' option in [hgbuildbot]. 
The results were inconsistent -- e.g., notifications for pushes I made were
not being received properly by Buildbot, but updates made by some other
developers were.  Instead of trying to figure out why, I just decided my time
would be better spent added my own notification mechanism, which has turned
out to be entirely consistent.

First, I added a new predicate option to the [hgbuildbot] section called
'shell'.  If enabled, the following new code in changes/hgbuildbot.py is
executed.  I've fully aware that this is probably not canon for Buidlbot's
coding idiom, and of course I'd welcome any suggestions of improvement. 
However, this modification I'm made works completely as I expect it to (so
far, all notifications are delivered), and I get no conflicts between Twisted
implementations:

--- hgbuildbot.py.original    2013-05-24 19:58:52.215045281 -0700
+++ hgbuildbot.py    2013-05-26 12:19:12.203316209 -0700
@@ -54,6 +54,7 @@
 #                                        # the default of PBChangeSource.
 
 import os
+import subprocess
 
 from mercurial.node import bin, hex, nullid #@UnresolvedImport
 from mercurial.context import workingctx #@UnresolvedImport
@@ -90,6 +91,7 @@
         category = ui.config('hgbuildbot', 'category', None)
         project = ui.config('hgbuildbot', 'project', '')
         auth = ui.config('hgbuildbot', 'auth', None)
+        shell = ui.config('hgbuildbot', 'shell', None)
     else:
         ui.write("* You must add a [hgbuildbot] section to .hg/hgrc in "
                  "order to use buildbot hook\n")
@@ -124,9 +126,11 @@
         auth = 'change:changepw'
     auth = auth.split(':', 1)
 
-    s = sendchange.Sender(master, auth=auth)
-    d = defer.Deferred()
-    reactor.callLater(0, d.callback, None)
+    if not shell:
+        s = sendchange.Sender(master, auth=auth)
+        d = defer.Deferred()
+        reactor.callLater(0, d.callback, None)
+
     # process changesets
     def _send(res, c):
         if not fork:
@@ -144,6 +148,44 @@
 
     repository = strip(repo.root, stripcount)
 
+    def _shell(c):
+        # fix string encodings
+        for key in c:
+            if type(c[key]) == str:
+                c[key] = fromlocal(c[key])
+        c['files'] = list(c['files'])
+        for i, file in enumerate(c.get('files', [])):
+            if type(file) == str:
+                c['files'][i] = fromlocal(file)
+
+        # build command line
+        command = ['buildbot', 'sendchange']
+        command += ['--master', master]
+        command += ['--vc', 'hg']
+        command += ['--branch', c['branch']]
+        command += ['--revision', c['revision']]
+        if ' ' in c['comments']:
+            command += ['--comments', '"%s"' % c['comments']]
+        else:
+            command += ['--comments', c['comments']]
+        command += ['--who', c['username']]
+        command += ['--auth', ':'.join(auth)]
+        if category:
+            command += ['--category', category]
+        if repository:
+            command += ['--repository', repository]
+        if project:
+            command += ['--project', project]
+        command += c['files']
+
+        # execute it
+        result = subprocess.call(' '.join(command), shell=True)
+        if result:
+            ui.status("Buildbot notification failed: %d\n" % result)
+        else:
+            ui.status("rev %s sent\n" % c['revision'])
+        return result
+
     for rev in xrange(start, end):
         # send changeset
         node = repo.changelog.node(rev)
@@ -164,7 +206,11 @@
             'files': files,
             'branch': branch
         }
-        d.addCallback(_send, change)
+
+        if not shell:
+            d.addCallback(_send, change)
+        else:
+            _shell(change)
 
     def _printSuccess(res):
         ui.status(s.getSuccessString(res) + '\n')
@@ -172,9 +218,10 @@
     def _printFailure(why):
         ui.warn(s.getFailureString(why) + '\n')
 
-    d.addCallbacks(_printSuccess, _printFailure)
-    d.addBoth(lambda _ : reactor.stop())
-    reactor.run()
+    if not shell:
+        d.addCallbacks(_printSuccess, _printFailure)
+        d.addBoth(lambda _ : reactor.stop())
+        reactor.run()
 
     if fork:
         os._exit(os.EX_OK)





More information about the devel mailing list