Skip to content

Instantly share code, notes, and snippets.

@omnicolor
Created February 6, 2012 16:19
Show Gist options
  • Save omnicolor/1753066 to your computer and use it in GitHub Desktop.
Save omnicolor/1753066 to your computer and use it in GitHub Desktop.
Pre-commit SVN script to run unit tests
#!/usr/local/bin/php
<?php
/**
* Pre-commit Subversion script that runs unit tests.
* @author Omni Adams <[email protected]>
* @copyright 2010 Digital Darkness
*/
/**
* Path to the ant binary.
*/
define('ANT', '/usr/bin/ant');
/**
* Path to the patch binary.
*/
define('PATCH', '/usr/bin/patch');
/**
* Path to the php binary.
*/
define('PHP', '/usr/local/bin/php');
/**
* Path to the svn binary.
*/
define('SVN', '/usr/bin/svn');
/**
* Path to svnlook binary.
*/
define('SVNLOOK', '/usr/bin/svnlook');
/**
* Divider to inject into error messages.
*/
define('DIVIDER',
'********************************************************************************');
/**
* Run unit tests for the repository.
*
* If any unit tests fail, write the failure information
* to standard error and return true.
* @param string $transaction SVN transaction ID.
* @param string $repository Full path to the repository.
* @return boolen True if there was an error.
*/
function runUnitTests($transaction, $repository) {
// Check out the latest from the repository into a
// temporary directory.
$fullRepoUrl = 'file:///' . $repository . '/trunk';
$workingDirectory = '/tmp/svn-precommit/'
. $transaction;
mkdir($workingDirectory, 0700, true);
exec(SVN . ' co "' . $fullRepoUrl . '" '
. $workingDirectory);
// Pull a patch of files changed from the transaction.
$diffCommand = SVNLOOK . ' diff -t "' . $transaction
. '" "' . $repository . '"';
$diffOutput = array();
exec($diffCommand, $diffOutput);
$diff = implode(PHP_EOL, $diffOutput);
file_put_contents($workingDirectory . '/patch',
$diff);
// Apply the patch to a fresh copy of the repository.
chdir($workingDirectory);
exec(PATCH . ' < ' . $workingDirectory . '/patch');
// Run the test target.
$output = array();
exec(ANT . ' test 2> /dev/null', $output);
$output = implode(PHP_EOL, $output);
if (false === strpos($output, 'FAILURES')) {
// Build passed!
return false;
}
// Clean up the output a little bit before displaying
// it to the user.
$output = str_replace(array(' [exec]',
$workingDirectory), '', $output);
$output = PHP_EOL . DIVIDER . PHP_EOL . PHP_EOL
. 'Unit tests failed. Fix the unit tests before '
. 'submitting.' . PHP_EOL . PHP_EOL . $output;
file_put_contents('php://stderr', $output);
return true;
}
$repository = $_SERVER['argv'][1];
$transaction = $_SERVER['argv'][2];
if (runUnitTests($transaction, $repository)) {
exit(1);
}
exit(0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment