[Buildbot-commits] buildbot/contrib darcs_buildbot.py,1.2,1.3
Brian Warner
warner at users.sourceforge.net
Thu Jan 18 01:24:12 UTC 2007
Update of /cvsroot/buildbot/buildbot/contrib
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv24369/contrib
Modified Files:
darcs_buildbot.py
Log Message:
[project @ darcs_buildbot.py: enhance to handle multiple patches in a single push. Fixes SF#1534049]
Original author: warner at lothar.com
Date: 2007-01-17 23:59:03
Index: darcs_buildbot.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/contrib/darcs_buildbot.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- darcs_buildbot.py 28 May 2006 07:59:32 -0000 1.2
+++ darcs_buildbot.py 18 Jan 2007 01:24:10 -0000 1.3
@@ -17,29 +17,11 @@
# "python2.3-xml" package under debian).
import os, sys, commands
-from StringIO import StringIO
-from buildbot.scripts import runner
+from buildbot.clients import sendchange
+from twisted.internet import defer, reactor
import xml
from xml.dom import minidom
-MASTER = sys.argv[1]
-
-out = commands.getoutput("darcs changes --last=1 --xml-output --summary")
-#out = commands.getoutput("darcs changes -p 'project @ 2006-05-21 19:07:27 by warner' --xml-output --summary")
-try:
- doc = minidom.parseString(out)
-except xml.parsers.expat.ExpatError, e:
- print "failed to parse XML"
- print str(e)
- print "purported XML is:"
- print "--BEGIN--"
- print out
- print "--END--"
- sys.exit(1)
-
-c = doc.getElementsByTagName("changelog")[0]
-p = c.getElementsByTagName("patch")[0]
-
def getText(node):
return "".join([cn.data
for cn in node.childNodes
@@ -50,37 +32,111 @@
return ""
return getText(children[0])
+def makeChange(p):
-author = p.getAttribute("author")
-revision = p.getAttribute("hash")
-comments = getTextFromChild(p, "name") + "\n" + getTextFromChild(p, "comment")
+ author = p.getAttribute("author")
+ revision = p.getAttribute("hash")
+ comments = (getTextFromChild(p, "name") + "\n" +
+ getTextFromChild(p, "comment"))
-summary = c.getElementsByTagName("summary")[0]
-files = []
-for filenode in summary.childNodes:
- if filenode.nodeName in ("add_file", "modify_file", "remove_file"):
- filename = getText(filenode).strip()
- files.append(filename)
+ summary = p.getElementsByTagName("summary")[0]
+ files = []
+ for filenode in summary.childNodes:
+ if filenode.nodeName in ("add_file", "modify_file", "remove_file"):
+ filename = getText(filenode).strip()
+ files.append(filename)
-# note that these are all unicode. Because PB can't handle unicode, we encode
-# them into ascii, which will blow up early if there's anything we can't get
-# to the far side. When we move to something that *can* handle unicode (like
-# newpb), remove this.
-author = author.encode("ascii")
-comments = comments.encode("ascii")
-files = [f.encode("ascii") for f in files]
-revision = revision.encode("ascii")
+ # note that these are all unicode. Because PB can't handle unicode, we
+ # encode them into ascii, which will blow up early if there's anything we
+ # can't get to the far side. When we move to something that *can* handle
+ # unicode (like newpb), remove this.
+ author = author.encode("ascii")
+ comments = comments.encode("ascii")
+ files = [f.encode("ascii") for f in files]
+ revision = revision.encode("ascii")
-change = {
- 'master': MASTER,
- # note: this is more likely to be a full email address, which would make
- # the left-hand "Changes" column kind of wide. The buildmaster should
- # probably be improved to display an abbreviation of the username.
- 'username': author,
- 'revision': revision,
- 'comments': comments,
- 'files': files,
- }
+ change = {
+ # note: this is more likely to be a full email address, which would
+ # make the left-hand "Changes" column kind of wide. The buildmaster
+ # should probably be improved to display an abbreviation of the
+ # username.
+ 'username': author,
+ 'revision': revision,
+ 'comments': comments,
+ 'files': files,
+ }
+ return change
-runner.sendchange(change, True)
+
+
+MASTER = sys.argv[1]
+LASTCHANGEFILE = ".darcs_buildbot-lastchange"
+
+def getSomeChanges(count):
+ out = commands.getoutput("darcs changes --last=%d --xml-output --summary"
+ % count)
+ try:
+ doc = minidom.parseString(out)
+ except xml.parsers.expat.ExpatError, e:
+ print "failed to parse XML"
+ print str(e)
+ print "purported XML is:"
+ print "--BEGIN--"
+ print out
+ print "--END--"
+ sys.exit(1)
+
+ c = doc.getElementsByTagName("changelog")[0]
+ changes = []
+ for i,p in enumerate(c.getElementsByTagName("patch")):
+ if i >= count:
+ break
+ changes.append(makeChange(p))
+ return changes
+
+def findNewChanges():
+ if os.path.exists(LASTCHANGEFILE):
+ f = open(LASTCHANGEFILE, "r")
+ lastchange = f.read()
+ f.close()
+ else:
+ return getSomeChanges(1)
+ lookback = 10
+ while True:
+ changes = getSomeChanges(lookback)
+ # getSomeChanges returns newest-first, so changes[0] is the newest.
+ # we want to scan the newest first until we find the changes we sent
+ # last time, then deliver everything newer than that (and send them
+ # oldest-first).
+ for i,c in enumerate(changes):
+ if c['revision'] == lastchange:
+ newchanges = changes[:i]
+ newchanges.reverse()
+ return newchanges
+ if 2*lookback > 100:
+ raise RuntimeError("unable to find our most recent change "
+ "(%s) in the last %d changes" % (lastchange,
+ lookback))
+ lookback = 2*lookback
+
+changes = findNewChanges()
+s = sendchange.Sender(MASTER, None)
+d = defer.Deferred()
+reactor.callLater(0, d.callback, None)
+def _send(res, c):
+ branch = None
+ print "sending", c['revision'], "to buildbot"
+ return s.send(branch, c['revision'], c['comments'], c['files'],
+ c['username'])
+for c in changes:
+ d.addCallback(_send, c)
+d.addCallbacks(s.printSuccess, s.printFailure)
+d.addBoth(s.stop)
+s.run()
+
+if changes:
+ lastchange = changes[-1]['revision']
+ f = open(LASTCHANGEFILE, "w")
+ f.write(lastchange)
+ f.close()
More information about the Commits
mailing list