SVN post-commit hook cronjob
Few SVN hosting sites provide ssh access to their svn servers. Such is needed to create hooks, like a post-commit hook that sends an email with every commit. Such hooks are often required by the development team. This article discusses the creation of a cron job that polls the SVN repository to simulate a post-commit hook that sends an email with every commit.
Setting up sendEmail
sendEmail is a nice tool to send emails via command line. This is needed to script in the cronjob sending an email. On ubuntu, install it from apt-get by:
sudo apt-get install sendemail libio-socket-ssl-perl libcrypt-ssleay-perl
The latter 2 packages are needed for connecting to an SMTP server that uses a secure connection (like Gmail, which is used in the example).
The post-commit hook script
The following is a python script, that could be added as an entry in the cron table
[sourcecode language="python"]
#! /usr/bin/env python
import os,re
log_file = LOG_DIR
svn_log_seperator = '------------------------------------------------------------------------'
svn_dir = SVN_DIR
mail_filter = '[special mail identifier in subject]'
message_file = '/tmp/commit_mail'
mail_from = MAIL_FROM
mail_to = MAIL_TO
smtp_server = "smtp.gmail.com:587"
smtp_user = SMTP_USER
smtp_pass = SMTP_PASS
def send_mail(subject,mail):
mail_file = open(message_file,'w')
mail_file.write(mail)
mail_file.close()
mail_command = 'sendEmail -f %s -t %s -u "%s" -s %s -xu "%s" -xp "%s" -o message-file="%s"' % (mail_from, mail_to, subject, smtp_server, smtp_user, smtp_pass,message_file)
print mail_command
os.system(mail_command)
print "analyzing old log file"
old_log_f = open(log_file)
old_log = old_log_f.read().split(svn_log_seperator)
old_log_f.close()
print "updating svn"
os.system("/usr/local/bin/svn update %s" % svn_dir)
os.system("/usr/local/bin/svn log %s > %s" % (svn_dir,log_file))
print "got new log"
new_log_f = open(log_file)
new_log = new_log_f.read().split(svn_log_seperator)
new_log_f.close()
delta = set(new_log) - set(old_log)
for commit in delta:
l = [x for x in commit.split('\n') if x]
details = l[0].split('|')
subject = "%s %s %s" %(mail_filter,details[0],details[1])
f_diff=os.popen('/usr/local/bin/svn diff -c %s %s' % (details[0], svn_dir))
diff = f_diff.read()
f_diff.close()
mail = "%s\n%s" % (commit, diff)
send_mail(subject,mail)
[/sourcecode]
Perquisites before running the script
- Having a working copy of the svn reposity
- Running the following command once before the script:
svn log > $PATH_TO_LOG_FILE