Created
January 11, 2011 04:34
-
-
Save asuth/774026 to your computer and use it in GitHub Desktop.
improvement to https://www.firehed.net/lint-check-all-php-files-syntax-validation so that it doesn't re-lint all your files
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
#!/opt/local/bin/php | |
<?php | |
// https://www.firehed.net/lint-check-all-php-files-syntax-validation | |
// with some modifications | |
// =========== | |
// = Globals = | |
// =========== | |
$count = 0; // total files checked | |
$changed = array(); | |
$errors = array(); | |
$options = setOptions(array( | |
'quiet' => false, | |
'recurse' => false, | |
)); | |
$start = microtime(true); | |
// include the md5 of this file so | |
// a new cache is used when we change the file | |
$cache_path = __DIR__.'/php-lint-cache.'.md5_file(__FILE__).'.cache'; | |
// this cache file saves md5-checksums of files | |
// so we don't have to re-lint already verified files | |
if (file_exists($cache_path)) | |
require $cache_path; | |
else | |
$md5_cache_old = array(); | |
if ($options['quiet']) { | |
ob_start(); | |
} | |
// ============= | |
// = Scan path = | |
// ============= | |
$files = getPipedFiles(); | |
$path = $_SERVER['PWD']; // Default to execution directory | |
echo "Running PHP Lint:\n"; | |
// Piped files present | |
if ($files) { | |
foreach ($files as $file) { | |
checkFile("$path/$file"); | |
} | |
} | |
// Use arguments | |
else { | |
if ($_SERVER['argc'] > 1) { | |
$last = end($_SERVER['argv']); | |
if (substr($last, 0, 1) != '-') { | |
$path = $last; // snag last argument, if it wasn't an option switch | |
} | |
} | |
if (is_dir($path)) { | |
checkDirectoryContents($path); | |
} | |
elseif (is_file($path)) { | |
checkFile($path); | |
} | |
else { | |
echo "$path is not a file or directory.\n"; | |
showHelp() AND exit(1); | |
} | |
} | |
if ($options['quiet']) { | |
ob_end_clean(); | |
} | |
$time = microtime(true) - $start; | |
echo "\n$count total files checked, ".count($changed)." changed files, ".count($errors).' errors; took '.number_format($time, 3).' seconds'; | |
if ($changed) | |
echo "\nChanged php files:\n\t", implode($changed, "\n\t"); | |
if ($errors) | |
echo "\n*********************\nFiles with ERRORS:\n\t", implode($errors, "\n\t")."\n*********************"; | |
else | |
echo "\nNO ERRORS"; | |
echo "\n"; | |
file_put_contents($cache_path, "<?php \$md5_cache_old = ".var_export($md5_cache_new, true)." ?>"); | |
if (empty($errors)) | |
exit(0); // exit successfully | |
else | |
exit(1); // exit unsuccessfully | |
function checkDirectoryContents($dir) { | |
global $options, $i, $errors, $count; | |
$contents = scandir($dir); | |
foreach($contents as $content) { | |
if ( $content == '.' || | |
$content == '..') { | |
continue; | |
} | |
$path = "$dir/$content"; | |
// Recurse into directories | |
if (is_dir($path) && $options['recurse']) { | |
checkDirectoryContents($path); | |
} // if is_dir | |
else { | |
// Skip non-php files | |
if (substr($path, -4) != '.php') { | |
continue; | |
} | |
checkFile($path); | |
} // !is_dir | |
} // foreach | |
} // function checkDirectoryContents | |
function checkFile($path) { | |
global $count, $errors, $md5_cache_old, $md5_cache_new, $changed; | |
if (($count % 80 == 0)) { | |
echo "\n"; | |
} | |
$md5 = md5_file($path); | |
// check md5_cache to see if we've already linted this file | |
if (isset($md5_cache_old[$md5])) : | |
$error = $md5_cache_old[$md5]; | |
else : | |
exec('php -l ' . escapeshellarg( $path ) . ' 2> /dev/null', $output, $return); | |
if ($return === 0) : // php -l gives a 0 error code if everything went well | |
$error = false; | |
else : | |
array_shift($output); // first line is always blank | |
array_pop($output); // the last line is always "Errors parsing httpdocs/test.php" | |
$error = implode("\n", $output); | |
endif; | |
$changed[] = $path; | |
endif; | |
$md5_cache_new[$md5] = $error; | |
if ($error) { | |
$errors[] = $error; | |
echo 'E'; | |
} else { | |
echo "."; | |
} | |
$count++; | |
} | |
function getPipedFiles() { | |
$files = array(); | |
stream_set_blocking(STDIN,FALSE); | |
while ($line = trim(fgets(STDIN))) { | |
$files[] = $line; | |
} | |
return $files; | |
} | |
function setOptions($options) { | |
$args = array_keys(getopt('qRh', array('quiet', 'recursive', 'help'))); | |
foreach ($args as $arg) { | |
switch ($arg) { | |
case 'q': | |
case 'quiet': | |
$options['quiet'] = true; | |
break; | |
case 'R': | |
case 'recursive': | |
$options['recurse'] = true; | |
break; | |
case 'h': | |
case 'help': | |
default: | |
showHelp() AND exit(0); | |
} // Switch | |
} // Foreach args | |
return $options; | |
} // function setOptions | |
function showHelp() { | |
echo <<<HELP | |
usage: lint [-qR] [path] | |
options: | |
-q, --quiet: disable verbose output | |
-R, --recursive: recurse into subdirectories | |
-h, --help: display this help screen | |
HELP; | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment