[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