[Buildbot-commits] buildbot/contrib svnpoller.py,NONE,1.1 svn_watcher.py,NONE,1.1 README.txt,1.1,1.2

Brian Warner warner at users.sourceforge.net
Mon Apr 17 18:11:45 UTC 2006


Update of /cvsroot/buildbot/buildbot/contrib
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv688/contrib

Modified Files:
	README.txt 
Added Files:
	svnpoller.py svn_watcher.py 
Log Message:
Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-496
Creator:  Brian Warner <warner at lothar.com>

add contrib/svnpoller.py and contrib/svn_watcher.py

	* contrib/svnpoller.py: added script by John Pye to poll a remote
	SVN repository (by running 'svn log') from a cronjob, and run
	'buildbot sendchange' to deliver the changes to a remote
	buildmaster.
	* contrib/svn_watcher.py: added script by Niklaus Giger (a
	modification of svnpoller.py), same purpose, but this one loops
	internally (rather than expecting to run from a cronjob) and works
	under windows.
	* contrib/README.txt: same


Index: README.txt
===================================================================
RCS file: /cvsroot/buildbot/buildbot/contrib/README.txt,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- README.txt	19 Jul 2004 18:37:59 -0000	1.1
+++ README.txt	17 Apr 2006 18:11:42 -0000	1.2
@@ -1,4 +1,5 @@
-Utility scripts:
+Utility scripts, things contributed by users but not strictly a part of
+buildbot:
 
 debugclient.py (and debug.*): debugging gui for buildbot
 
@@ -9,3 +10,22 @@
 
 svn_buildbot.py: a script intended to be run from a subversion hook-script
                  which submits changes to svn (requires python 2.3)
+
+svnpoller.py: this script is intended to be run from a cronjob, and uses 'svn
+              log' to poll a (possibly remote) SVN repository for changes.
+              For each change it finds, it runs 'buildbot sendchange' to
+              deliver them to a waiting PBChangeSource on a (possibly remote)
+              buildmaster. Modify the svnurl to point at your own SVN
+              repository, and of course the user running the script must have
+              read permissions to that repository. It keeps track of the last
+              revision in a file, change 'fname' to set the location of this
+              state file. Modify the --master argument to the 'buildbot
+              sendchange' command to point at your buildmaster. Contributed
+              by John Pye. Note that if there are multiple changes within a
+              single polling interval, this will miss all but the last one.
+
+svn_watcher.py: adapted from svnpoller.py by Niklaus Giger to add options and
+                run under windows. Runs as a standalone script (it loops
+                internally rather than expecting to run from a cronjob),
+                polls an SVN repository every 10 minutes. It expects the
+                svnurl and buildmaster location as command-line arguments.

--- NEW FILE: svn_watcher.py ---
#!/usr/bin/python

# This is a program which will poll a (remote) SVN repository, looking for
# new revisions. It then uses the 'buildbot sendchange' command to deliver
# information about the Change to a (remote) buildmaster. It can be run from
# a cron job on a periodic basis, or can be told (with the 'watch' option) to
# automatically repeat its check every 10 minutes.

# This script does not store any state information, so to avoid spurious
# changes you must use the 'watch' option and let it run forever.

# You will need to provide it with the location of the buildmaster's
# PBChangeSource port (in the form hostname:portnum), and the svnurl of the
# repository to watch.


# 15.03.06 by John Pye
# 29.03.06 by Niklaus Giger, added support to run under windows, added invocation option
import commands
import xml.dom.minidom
import sys
import time
import os
if sys.platform == 'win32':
    import win32pipe

def checkChanges(repo, master, verbose=False, oldRevision=-1):
    cmd ="svn log --non-interactive --xml --verbose --limit=1 "+repo
    if verbose == True:
        print "Getting last revision of repository: " + repo

    if sys.platform == 'win32':
        f = win32pipe.popen(cmd)
        xml1 = ''.join(f.readlines())
        f.close()
    else:
        xml1 = commands.getoutput(cmd)  
    
    if verbose == True:
        print "XML\n-----------\n"+xml1+"\n\n"
    
    doc = xml.dom.minidom.parseString(xml1)
    el = doc.getElementsByTagName("logentry")[0]
    revision = el.getAttribute("revision")
    author = "".join([t.data for t in
    el.getElementsByTagName("author")[0].childNodes])
    comments = "".join([t.data for t in
    el.getElementsByTagName("msg")[0].childNodes])
    
    pathlist = el.getElementsByTagName("paths")[0]
    paths = []
    for p in pathlist.getElementsByTagName("path"):
            paths.append("".join([t.data for t in p.childNodes]))

    if verbose == True:
        print "PATHS"
        print paths

    if  revision != oldRevision:
        cmd = "buildbot sendchange --master="+master+" --revision=\""+revision+"\" --username=\""+author+"\"--comments=\""+comments+"\" "+" ".join(paths)
    
        if verbose == True:
            print cmd
    
        if sys.platform == 'win32':
            f = win32pipe.popen(cmd)
            print time.strftime("%H.%M.%S ") + "Revision "+revision+ ": "+ ''.join(f.readlines())
            f.close()
        else:
            xml1 = commands.getoutput(cmd)  
    else:
        print time.strftime("%H.%M.%S ") + "nothing has changed since revision "+revision
       
    return revision

if __name__ == '__main__':
    if len(sys.argv) == 4 and sys.argv[3] == 'watch':
        oldRevision = -1
        print "Watching for changes in repo "+  sys.argv[1] + " master " +  sys.argv[2] 
        while 1:
            oldRevision = checkChanges(sys.argv[1],  sys.argv[2], False, oldRevision)
            time.sleep(10*60) # Check the repository every 10 minutes

    elif len(sys.argv) == 3:
        checkChanges(sys.argv[1],  sys.argv[2], True )
    else:
        print os.path.basename(sys.argv[0]) + ":  http://host/path/to/repo master:port [watch]"


--- NEW FILE: svnpoller.py ---
#!/usr/bin/python
"""
 svn.py
 Script for BuildBot to monitor a remote Subversion repository.
 Copyright (C) 2006 John Pye
"""
# This script is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA

import commands
import xml.dom.minidom
import ConfigParser
import os.path
import codecs

# change these settings to match your project
svnurl = "https://pse.cheme.cmu.edu/svn/ascend/code/trunk"
statefilename = "~/changemonitor/config.ini"
buildmaster = "buildbot.example.org:9989" # connects to a PBChangeSource

xml1 = commands.getoutput("svn log --non-interactive --verbose --xml --limit=1 " + svnurl)
#print "XML\n-----------\n"+xml1+"\n\n"

try:
	doc = xml.dom.minidom.parseString(xml1)
	el = doc.getElementsByTagName("logentry")[0]
	revision = el.getAttribute("revision")
	author = "".join([t.data for t in el.getElementsByTagName("author")[0].childNodes])
	comments = "".join([t.data for t in el.getElementsByTagName("msg")[0].childNodes])

	pathlist = el.getElementsByTagName("paths")[0]
	paths = []
	for p in pathlist.getElementsByTagName("path"):
		paths.append("".join([t.data for t in p.childNodes]))
	#print "PATHS"
	#print paths
except xml.parsers.expat.ExpatError, e:
	print "FAILED TO PARSE 'svn log' XML:"
	print str(e)
	print "----"
	print "RECEIVED TEXT:"
	print xml1
	import sys
	sys.exit(1)

fname = statefilename
fname = os.path.expanduser(fname)
ini = ConfigParser.SafeConfigParser()

try:
	ini.read(fname)
except:
	print "Creating changemonitor config.ini:",fname
	ini.add_section("CurrentRevision")
	ini.set("CurrentRevision",-1)

try:
	lastrevision = ini.get("CurrentRevision","changeset")
except ConfigParser.NoOptionError:
	print "NO OPTION FOUND"
	lastrevision = -1
except ConfigParser.NoSectionError:
	print "NO SECTION FOUND"
	lastrevision = -1

if lastrevision != revision:

	#comments = codecs.encodings.unicode_escape.encode(comments)
	cmd = "buildbot sendchange --master="+buildmaster+" --branch=trunk --revision=\""+revision+"\" --username=\""+author+"\" --comments=\""+comments+"\" "+" ".join(paths)

	#print cmd
	res = commands.getoutput(cmd)

	print "SUBMITTING NEW REVISION",revision
	if not ini.has_section("CurrentRevision"):
		ini.add_section("CurrentRevision")
	try:
		ini.set("CurrentRevision","changeset",revision)
		f = open(fname,"w")
		ini.write(f)
		#print "WROTE CHANGES TO",fname
	except:
		print "FAILED TO RECORD INI FILE"





More information about the Commits mailing list