Saturday, February 7, 2009

Creating a post-commit hook in PHP

In my earlier pots, I elaborated how to create a pre-commit svn hook in PHP, for avoiding commits without adding comments.

Here I am going to elaborate step by step, to make a post-commit svn hook, for sending emails to all the members who are concerned with the application, when its committed.

Objective :

To create a post-commit hook in PHP, such that when any commit is done, a mail is sent to all members whose email id is configured in the system.

Step-by-step Execution :
1. Create a svn application directory.

Ex: Create a svn repository for the application router,

Command: svnadmin create /usr/local/svn/router (The path can be changed)

2) In the directory, /usr/local/svn/router/hooks/ rename the file post-commit.tmpl to post-commit.

Add the following lines of codes to it, with assumption that php interpreter is present at /usr/bin/php

#!/usr/bin/php
$REPOS=$argv[1];
$REV=$argv[2];

$application=end(explode("/",$REPOS));
$author=`/usr/bin/svnlook author -r $REV $REPOS`;
$comment_added=`/usr/bin/svnlook log -r $REV $REPOS`;

$domain='@anydomain.com';
$from=trim($author).trim($domain);
$subject="SVN Commit Notification for $application";
$message="Committed by :"."\n".$author;
$message.="\n\n"."Commit comments :"."\n". $comment_added;

$file_path = $REPOS.'/hooks/email.txt';
$email_array=explode(",",file_get_contents($file_path));

$headers = 'From: '.$from."\r\n".'Date: '.date('r')."\r\n".'MIME-Version: 1.0'."\r\n".'Content-transfer-encoding: 8bit'."\r\n".'Content-type: text/plain; charset=iso-8859-1'."\r\n";

foreach($email_array as $ea)
{
$return_mail = mail($ea,$subject,$message,$headers);
}
?>

You need to add a file email.txt in the /usr/local/svn/hooks/ directory which contains a comma separated list of email ids, without any spaces and new lines.
Ex: first@anydomain.com,second@anydomain.com,third@anydomain.com

Checkout the repository, in your local directory, make some modification and try now to commit, without providing any comment.

After committing the code an email will be send to all email ids, in the email.txt file.

A few details :
In the post-commit hook, svn passes 2 parameters to it, namely repository name and revision number. We can make use of these parameters, to send information as required, in the mail.

Creating a pre-commit svn hook in PHP

SVN is used for varied reasons. We can jump back, having a versioned backup, share-coding with others – its really awesome.

But then the complexities grows, when we have multiple users, accessing the same repository, which includes proper commenting when the commit is done or mail need to be sent to all the members affected with that particular application and etc..etc...

To ease out these particular complexities, svn provides many hooks which we can add/modify in the svn directory.The complete details about the hooks can be found at http://svnbook.red-bean.com/en/1.1/ch05s02.html

Objective :

To create a pre-commit hook in PHP, such that no commit made without adding any comments.

Step-by-step execution :

1. Create a svn application directory.

Ex: Create a svn repository for the application router,

Command: svnadmin create /usr/local/svn/router

2) In the directory, /usr/local/svn/router/hooks/ rename the file pre-commit.tmpl to pre-commit.

Add the following lines of codes to it.

#!/usr/bin/php
$REPOS=$argv[1];
$TXN=$argv[2];
$log=trim(`/usr/bin/svnlook log -t $TXN $REPOS`);
if(empty($log))
{
fwrite(STDERR,"Empty log messages are not allowed, Please provide a proper log message");
exit(1);
}
exit(0);
?>

Checkout the repository, in your local directory, make some modification and try now to commit, without providing any comment.

An error message will be thrown and the commit will fail.

A few details:

Whenever COMMIT is done, svn passes two parameters to the pre-commit executable, one is repository name and other is transaction id. You can view, whats being added in the log, by svnlook command. For options available with svnlook, just type in svnlook help. Now if the log message is empty, an error will be thrown and the it must be directed to STDERR.