SVN's Post-commit Script in PHP

I was kinda bored yesterday. And was poking around the SVN hooks scripts. When i noticed the post-commit script i was using was written in Python. Nothing wrong with that. I just wondered how hard it would be to do the same in PHP. So i came up with a little test. Which at this moment lacks error checking and just looks plain ugly. But it does the job. and i only needed a working PHP CLI executable to make it work.

First we set the email address and the location of svnlook.

#!/usr/bin/php
<?php
error_reporting(E_ALL | E_STRICT); 
    
$address = 'some email address';
$svnlook = '/usr/bin/svnlook';

Use the argv array to get to the commandline parameters and build up a SVN statement to get some basic info.

$repository = $_SERVER['argv'][1];
$revision = $_SERVER['argv'][2];

$cmdInfo = "${svnlook} info ${repository} -r ${revision}";

$output = array();
exec($cmdInfo, $output);

$author = $output[0];
$date = $output[1];
$comment = $output[3];

Now let’s get the changes made in this revisions.

$output = array();
$cmdChanges ="${svnlook} diff ${repository} -r ${revision}";
exec($cmdChanges, $output);

Once we have the diff contents we can loop through the lines and use some simple regex to highlight the changes. I’ve added a bit more code to add pre tags for a better visual effect.

$patch = '<pre class="codeBlock">';
$lineCount = count($output);
for ($x=0; $x<=$lineCount; $x++) {

  if ($x > 0 && strstr($output[$x], 'Modified:')) {
    $patch .= '</pre><pre class="codeBlock">';
  }

  $textColor = 'normal';
  if (preg_match('/^\+/', $output[$x])) {
    $textColor = 'positive';
  }
  else if (preg_match('/^-/', $output[$x])) {
    $textColor = 'negative';
  }

  $patch .= '<span class="' . $textColor . '">' . htmlentities($output[$x]) . "</span><br>";

  if ($x == $lineCount) {
    $patch .= "</pre>";
  }
}

Now we can build the body for the email that will be generated.

$body .= "Author : " . $author . "<br>";
$body .= "Date : " . $date . "<br>";
$body .= "Comment : " . $comment . "<br><br>";

$body .= $patch;

Add a MIME header so my mail client displays it properly. And send it of through the build in mail() function.

$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

$bodyHTML = file_get_contents("/path/to/some/HTML/template");
$bodyHTML = str_replace('{EMAIL}', $body, $bodyHTML);

mail($address, 'SVN post-commit', $bodyHTML, $headers);
comments powered by Disqus