PHP allows you to run its command line executable with a -l flag to catch any syntax errors in your code. Very simple, but can really help catch some stupid errors. Yes, they should definitely be caught by a code review, but code reviewers should also be able to assume that the code actually runs.
So here's a Subversion pre-commit hook that will run PHP lint on all PHP files and reject the commit if any of them fail.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/php | |
<?php | |
/** | |
* Pre-commit Subversion script. | |
* | |
* @author Omni Adams <omni@digitaldarkness.com> | |
*/ | |
/** | |
* Path to the awk binary. | |
*/ | |
define('AWK', '/usr/bin/awk'); | |
/** | |
* Path to the grep binary. | |
*/ | |
define('GREP', '/bin/grep'); | |
/** | |
* Path to the php binary. | |
*/ | |
define('PHP', '/usr/local/bin/php'); | |
/** | |
* Path to svnlook binary. | |
*/ | |
define('SVNLOOK', '/usr/bin/svnlook'); | |
/** | |
* Divider to inject into error messages to pretty them up. | |
*/ | |
define('DIVIDER', | |
'********************************************************************************'); | |
/** | |
* Run PHP lint on every PHP file that changed. | |
* | |
* If any of the PHP files in the current transaction have lint errors, writes | |
* an error message to standard error and returns true. | |
* @param string $transaction SVN transaction ID. | |
* @param string $repository Full path to the repository. | |
* @return boolean True if there was an error. | |
*/ | |
function runPhpLint($transaction, $repository) { | |
$errors = false; | |
$changedCommand = SVNLOOK . ' changed -t "' | |
. $transaction . '" "' | |
. $repository . '" ' | |
. '| ' . GREP . ' "^[UA]" ' | |
. '| ' . GREP . ' "\\.php$" ' | |
. '| ' . AWK . ' \'{print $2}\''; | |
exec($changedCommand, $changedOutput); | |
foreach ($changedOutput as $file) { | |
$lint = array(); | |
$lintCommand = SVNLOOK . ' cat -t "' | |
. $transaction . '" "' | |
. $repository . '" "' . $file . '" ' | |
. '| ' . PHP . ' -l'; | |
exec($lintCommand, $lint); | |
if ('No syntax errors detected in -' == $lint[0]) { | |
// Lint returns text on good files, | |
// don't write that to standard | |
// error or consider it an error. | |
continue; | |
} | |
$message = PHP_EOL . DIVIDER . PHP_EOL . PHP_EOL | |
. $file . ' contains PHP error(s):' . PHP_EOL; | |
foreach ($lint as $line) { | |
// PHP lint includes some blank lines in its output. | |
if ('' == $line) { | |
continue; | |
} | |
// PHP lint tells us where the error is, | |
// which because we pass it in by piping it | |
// to standard in, doesn't tell us anything. | |
if ('Errors parsing -' == $line) { | |
continue; | |
} | |
$message .= "\t" . $line . PHP_EOL; | |
} | |
file_put_contents('php://stderr', $message . PHP_EOL); | |
$errors = true; | |
} | |
return $errors; | |
} | |
if (runPhpLint($transaction, $repository)) { | |
exit(1); | |
} | |
exit(0); |
No comments:
Post a Comment