Subversion repository monitor

By Ghost on Thursday 12 November 2009 01:14 - Comments (12)
Category: Linux, Views: 14.255

At my work, we use a subversion repository to (not surprisingly) store our code. I found out that my colleague used a tool called CommitMonitor to get a notification whenever a commit is made to the repository. Inspired by this tool, I whipped up my own repository monitor for Linux using python.


The obligatory screenshot:
Svnnotify in Karmic

The full program listing is:

Python:
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
#!/usr/bin/python
#
# Script to notify the user for changes in a subversion repository.
#
# Depends on a configuration file with the following entries:
#
#   [server]
#   server=SVN_REPO_TO_MONITOR
#   user=YOUR_SVN_USERNAME
#   pass=YOUR_SVN_PASSWORD
#

try:
    import pysvn, pynotify
except:
    print "Error while loading external depencencies."
    print "Make sure 'pysvn' and 'pynotify' is installed."
    exit()

import datetime, time, ConfigParser as cfg

def read_config():
    """Read the configuration file containing server, username and password"""
    global svn_root, svn_username, svn_password

    config_file = 'svnnotify.cfg'
    config_header = 'server'

    try:
        parser = cfg.ConfigParser()
        parser.read(config_file)
        svn_root = parser.get(config_header, 'server')
        svn_username = parser.get(config_header, 'user')
        svn_password = parser.get(config_header, 'pass')
    except BaseException as e:
        print "Error while parsing file '%s':" % config_file
        print e
        exit()

def notify(paths, authors):
    """Display the changed paths using libnotify"""
    title_string = 'New commits to repository'
    path_string = ', '.join(paths)
    author_string = ', '.join(authors)
    message_string = path_string
    
    if pynotify.init("SVN Monitor"):
        n = pynotify.Notification(title_string, message_string, "emblem-shared")
        n.show()

def log_message(paths, authors):
    """Print a log message containing the time, authors and paths"""
    now = datetime.datetime.now()
    now = now.strftime("%H:%M")
    path_string = ', '.join(paths)
    author_string = ', '.join(authors)
    print "[%s] Paths: %s -- Authors: %s" % (now, path_string, author_string)
    

def credentials(realm, username, may_save):
    """Return the default login credentials"""
    return True, svn_username, svn_password, False

def discover_changes(last_revision=pysvn.Revision(pysvn.opt_revision_kind.number, 0)):
    """Find out the changes occured since the last time this method is ran"""
    if last_revision is None:
        last_revision=pysvn.Revision(pysvn.opt_revision_kind.number, 0)
    client = pysvn.Client()
    client.callback_get_login = credentials
    log = client.log(
        svn_root, 
        discover_changed_paths=True,
        revision_end=last_revision
        )
    if len(log) is 1:
        return last_revision, None, None
    authors = []
    paths = []
    for entry in log[:-1]:
        if entry.author not in authors:
            authors.append(entry.author)
        for change in entry.changed_paths:
            path = change.path.split('/',2)[1]
            if path not in paths:
                paths.append(path)
    last_revision = log[0].revision
        
    return last_revision, authors, paths

if __name__ == '__main__':
    read_config()
    print 'Monitoring SVN repository: %s' % svn_root
    print '- Press %s to quit -' % '^C'
    last_revision = None
    while True:
        last_revision, authors, paths = discover_changes(last_revision)
        if paths is not None:
            log_message(paths, authors)
            notify(paths, authors)
        time.sleep(5 * 60)



You have to drop a configuration file called 'svnnotify.cfg' in the same directory as the script with the following contents:

code:
1
2
3
4
[server]
server=SVN_REPO_TO_MONITOR
user=YOUR_SVN_USERNAME
pass=YOUR_SVN_PASSWORD

Volgende: Programming Atmel using MySmartUSB Light and Ubuntu 10-'10 Programming Atmel using MySmartUSB Light and Ubuntu
Volgende: Why people are allowed to stick with Windows 07-'09 Why people are allowed to stick with Windows

Comments


By Tweakers user Nick_S, Thursday 12 November 2009 02:37

It's a very nice script, which is querying your repository each 5 minutes. This is not very nice, especially when SVN has a nice feature for this, called hooks. I suppose you have access to your repository (the real server side repository directory structure, not just SVN) access. You can drop any script in the hooks directory of your repository. There are different hooks (pre-commit, post-commit, pre-lock, post-lock, etc) With this, you can setup a pushing notification mechanisme, instead of a pulling one.

By Tweakers user Ghost, Thursday 12 November 2009 02:49

You are absolutely correct about that. Although I am considering exactly that approach for monitoring my own repository (perhaps a XMPP-like thing), this script is specifically designed to work with repositories I do not have control over. I agree the 5 minute delay might be a bit too short, though |:(

[Comment edited on Thursday 12 November 2009 02:57]


By Tweakers user LinuX-TUX, Thursday 12 November 2009 10:45

Bookmarked, als je dat heb gevormd op de manier Nick_S aangaf, dan ga ik gretig gebruik maken van je Script :Y)

Nu eerst nog dat bestandje met [server] erin localiseren...

By Tweakers user Nick_S, Thursday 12 November 2009 11:46

I don't think you are going to find that. ;) You're supposed to make it yourself and put it in the directory containing the script.

Hooks that e-mail on post-commit are readily available.

By Christian Madsen, Tuesday 3 August 2010 09:14

This is really cool. Linux is lacking such a tool.

I hope that you find the necessary time for getting it into the official distributions.

By Ben Axelrod, Friday 24 September 2010 15:22

Great tool! I have been looking for an svn commit monitor for linux for a while. I am going to expand it to monitor multiple repositories.

By Mark, Wednesday 10 November 2010 17:11

Getting the following error:
pysvn._pysvn_2_6.ClientError: OPTIONS of 'https://svn_domain.com/view': 200 OK (https://svn_domain.com/view)

Am i doing something wrong?

Thanks.

By Tweakers user Ghost, Thursday 11 November 2010 09:23

The monitor is only designed for and tested with svnserve-based servers. A quick glance at the programming guide tells me you need additional callbacks for HTTPS access to repositories, perhaps even for HTTP.

You might want to look into the callback_ssl_server_trust_prompt callback method for this.

By Galen, Thursday 15 September 2011 21:35

FYI: CommitMonitor works just fine using wine on fedora 14

By Gavin Davies, Monday 2 April 2012 13:13

I found this useful! I made some modifications so I've put it on my Github giving you credit: https://github.com/gavD/svnnotify

I'll happily take it down if you're not cool with that! :)

Thanks,
- Gav

By Tweakers user Ghost, Monday 2 April 2012 13:15

No worries, Gav. Glad I could help :)

By Hugo, Thursday 26 April 2012 08:36

Nice job.

Maybe you like:
http://specto.sourceforge.net/
(is not my project)

Comments are closed