Fix status where change object's comments field is None
[buildbot.git] / contrib / svn_watcher.py
bloba7ac668f9b171f5cd274f0d7a09b4ec3a8f5bcd4
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,
19 # added invocation option
21 import subprocess
22 import xml.dom.minidom
23 import sys
24 import time
25 import os
28 if sys.platform == 'win32':
29 import win32pipe
32 def getoutput(cmd):
33 p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
34 return p.stdout.read()
37 def checkChanges(repo, master, verbose=False, oldRevision=-1):
38 cmd = ["svn", "log", "--non-interactive", "--xml", "--verbose",
39 "--limit=1", repo]
40 if verbose == True:
41 print "Getting last revision of repository: " + repo
43 if sys.platform == 'win32':
44 f = win32pipe.popen(cmd)
45 xml1 = ''.join(f.readlines())
46 f.close()
47 else:
48 xml1 = getoutput(cmd)
50 if verbose == True:
51 print "XML\n-----------\n"+xml1+"\n\n"
53 doc = xml.dom.minidom.parseString(xml1)
54 el = doc.getElementsByTagName("logentry")[0]
55 revision = el.getAttribute("revision")
56 author = "".join([t.data for t in
57 el.getElementsByTagName("author")[0].childNodes])
58 comments = "".join([t.data for t in
59 el.getElementsByTagName("msg")[0].childNodes])
61 pathlist = el.getElementsByTagName("paths")[0]
62 paths = []
63 for p in pathlist.getElementsByTagName("path"):
64 paths.append("".join([t.data for t in p.childNodes]))
66 if verbose == True:
67 print "PATHS"
68 print paths
70 if revision != oldRevision:
71 cmd = ["buildbot", "sendchange", "--master=%s"%master,
72 "--revision=%s"%revision, "--username=%s"%author,
73 "--comments=%s"%comments]
74 cmd += paths
76 if verbose == True:
77 print cmd
79 if sys.platform == 'win32':
80 f = win32pipe.popen(cmd)
81 print time.strftime("%H.%M.%S ") + "Revision "+revision+ ": "+ \
82 ''.join(f.readlines())
83 f.close()
84 else:
85 xml1 = getoutput(cmd)
86 else:
87 print time.strftime("%H.%M.%S ") + \
88 "nothing has changed since revision "+revision
90 return revision
93 if __name__ == '__main__':
94 if len(sys.argv) == 4 and sys.argv[3] == 'watch':
95 oldRevision = -1
96 print "Watching for changes in repo "+ sys.argv[1] +\
97 " master " + sys.argv[2]
98 while 1:
99 oldRevision = checkChanges(
100 sys.argv[1], sys.argv[2], False, oldRevision)
101 time.sleep(10*60) # Check the repository every 10 minutes
103 elif len(sys.argv) == 3:
104 checkChanges(sys.argv[1], sys.argv[2], True)
105 else:
106 print os.path.basename(
107 sys.argv[0]) + ": http://host/path/to/repo master:port [watch]"