TAG buildbot-0.7.3
[buildbot.git] / contrib / svn_watcher.py
blobad1843545d0d99b6a72f0ffc270414a2ab4c4d95
1 #!/usr/bin/python
3 # This is a program which will poll a (remote) SVN repository, looking for
4 # new revisions. It then uses the 'buildbot sendchange' command to deliver
5 # information about the Change to a (remote) buildmaster. It can be run from
6 # a cron job on a periodic basis, or can be told (with the 'watch' option) to
7 # automatically repeat its check every 10 minutes.
9 # This script does not store any state information, so to avoid spurious
10 # changes you must use the 'watch' option and let it run forever.
12 # You will need to provide it with the location of the buildmaster's
13 # PBChangeSource port (in the form hostname:portnum), and the svnurl of the
14 # repository to watch.
17 # 15.03.06 by John Pye
18 # 29.03.06 by Niklaus Giger, added support to run under windows, added invocation option
19 import commands
20 import xml.dom.minidom
21 import sys
22 import time
23 import os
24 if sys.platform == 'win32':
25 import win32pipe
27 def checkChanges(repo, master, verbose=False, oldRevision=-1):
28 cmd ="svn log --non-interactive --xml --verbose --limit=1 "+repo
29 if verbose == True:
30 print "Getting last revision of repository: " + repo
32 if sys.platform == 'win32':
33 f = win32pipe.popen(cmd)
34 xml1 = ''.join(f.readlines())
35 f.close()
36 else:
37 xml1 = commands.getoutput(cmd)
39 if verbose == True:
40 print "XML\n-----------\n"+xml1+"\n\n"
42 doc = xml.dom.minidom.parseString(xml1)
43 el = doc.getElementsByTagName("logentry")[0]
44 revision = el.getAttribute("revision")
45 author = "".join([t.data for t in
46 el.getElementsByTagName("author")[0].childNodes])
47 comments = "".join([t.data for t in
48 el.getElementsByTagName("msg")[0].childNodes])
50 pathlist = el.getElementsByTagName("paths")[0]
51 paths = []
52 for p in pathlist.getElementsByTagName("path"):
53 paths.append("".join([t.data for t in p.childNodes]))
55 if verbose == True:
56 print "PATHS"
57 print paths
59 if revision != oldRevision:
60 cmd = "buildbot sendchange --master="+master+" --revision=\""+revision+"\" --username=\""+author+"\"--comments=\""+comments+"\" "+" ".join(paths)
62 if verbose == True:
63 print cmd
65 if sys.platform == 'win32':
66 f = win32pipe.popen(cmd)
67 print time.strftime("%H.%M.%S ") + "Revision "+revision+ ": "+ ''.join(f.readlines())
68 f.close()
69 else:
70 xml1 = commands.getoutput(cmd)
71 else:
72 print time.strftime("%H.%M.%S ") + "nothing has changed since revision "+revision
74 return revision
76 if __name__ == '__main__':
77 if len(sys.argv) == 4 and sys.argv[3] == 'watch':
78 oldRevision = -1
79 print "Watching for changes in repo "+ sys.argv[1] + " master " + sys.argv[2]
80 while 1:
81 oldRevision = checkChanges(sys.argv[1], sys.argv[2], False, oldRevision)
82 time.sleep(10*60) # Check the repository every 10 minutes
84 elif len(sys.argv) == 3:
85 checkChanges(sys.argv[1], sys.argv[2], True )
86 else:
87 print os.path.basename(sys.argv[0]) + ": http://host/path/to/repo master:port [watch]"