Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/buildbot/contrib/svn_watcher.py
blob: a7ac668f9b171f5cd274f0d7a09b4ec3a8f5bcd4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/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 subprocess
import xml.dom.minidom
import sys
import time
import os


if sys.platform == 'win32':
    import win32pipe


def getoutput(cmd):
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    return p.stdout.read()


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 = 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=%s"%master,
               "--revision=%s"%revision, "--username=%s"%author,
               "--comments=%s"%comments]
        cmd += 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 = 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]"