1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Add more robust in-psalm check

This commit is contained in:
Matthew Brown 2016-10-07 00:58:08 -04:00
parent 68ec49d991
commit d8d26a3f40
4 changed files with 85 additions and 31 deletions

View File

@ -19,7 +19,7 @@ ini_set('display_startup_errors', 1);
ini_set('memory_limit', '2048M');
// get options from command line
$options = getopt('f:m:', ['debug', 'config:', 'monochrome', 'show-info:','diff:']);
$options = getopt('f:m:', ['debug', 'config:', 'monochrome', 'show-info:','diff']);
// get vars from options
$debug = array_key_exists('debug', $options);
@ -29,15 +29,7 @@ $use_color = !array_key_exists('monochrome', $options);
$show_info = isset($options['show-info'])
? $options['show-info'] !== 'false' && $options['show-info'] !== '0'
: true;
$diff_files = isset($options['diff'])
? array_filter(
array_map(
function($file) {
return realpath($file);
},
explode(' ', $options['diff'])
)
) : [];
$is_diff = isset($options['diff']);
// set the cache directory for the file checker
FileChecker::setCacheDir('/var/tmp/php-parser');
@ -53,7 +45,7 @@ ProjectChecker::$show_info = $show_info;
$time = microtime(true);
if ($path_to_check === null) {
ProjectChecker::check($debug, $diff_files);
ProjectChecker::check($debug, $is_diff);
}
elseif ($path_to_check) {
if (is_dir($path_to_check)) {

View File

@ -41,6 +41,9 @@ class FileChecker implements StatementsSource
public static $show_notices = true;
const REFERENCE_CACHE_NAME = 'references';
const GOOD_RUN_NAME = 'good_run';
protected static $last_good_run = null;
/**
* A lookup table used for getting all the files that reference a class
@ -496,6 +499,29 @@ class FileChecker implements StatementsSource
return isset(self::$file_references[$file]['i']) ? self::$file_references[$file]['i'] : [];
}
public static function canDiffFiles()
{
return self::$cache_dir && file_exists(self::$cache_dir . '/' . self::GOOD_RUN_NAME);
}
public static function hasFileChanged($file)
{
if (self::$last_good_run === null) {
self::$last_good_run = filemtime(self::$cache_dir . '/' . self::GOOD_RUN_NAME);
}
return filemtime($file) > self::$last_good_run;
}
public static function goodRun()
{
if (self::$cache_dir) {
$cache_location = self::$cache_dir . '/' . self::GOOD_RUN_NAME;
touch($cache_location);
}
}
public static function clearCache()
{
self::$file_checkers = [];

View File

@ -29,25 +29,37 @@ class ProjectChecker
*/
public static $show_info = true;
public static function check($debug = false, array $diff_files = [])
public static function check($debug = false, $is_diff = false)
{
if (!self::$config) {
self::$config = self::getConfigForPath(getcwd());
}
$file_list = [];
$diff_files = null;
if ($is_diff && FileChecker::loadReferenceCache() && FileChecker::canDiffFiles()) {
$diff_files = [];
if ($diff_files && FileChecker::loadReferenceCache()) {
$file_list = self::getReferencedFilesFromDiff($diff_files);
self::checkDiffFilesWithConfig($file_list, self::$config, $debug);
}
else {
foreach (self::$config->getIncludeDirs() as $dir_name) {
self::checkDirWithConfig($dir_name, self::$config, $debug, $file_list);
$diff_files = array_merge($diff_files, self::getDiffFilesInDir($dir_name, self::$config));
}
}
IssueBuffer::finish();
if ($diff_files === null || count($diff_files) > 200) {
foreach (self::$config->getIncludeDirs() as $dir_name) {
self::checkDirWithConfig($dir_name, self::$config, $debug);
}
}
else {
if ($debug) {
echo count($diff_files) . ' changed files' . PHP_EOL;
}
$file_list = self::getReferencedFilesFromDiff($diff_files);
self::checkDiffFilesWithConfig($file_list, self::$config, $debug);
}
IssueBuffer::finish(true);
}
public static function checkDir($dir_name, $debug = false)
@ -64,7 +76,7 @@ class ProjectChecker
IssueBuffer::finish();
}
protected static function checkDirWithConfig($dir_name, Config $config, $debug, array $file_list = [])
protected static function checkDirWithConfig($dir_name, Config $config, $debug)
{
$file_extensions = $config->getFileExtensions();
$filetype_handlers = $config->getFiletypeHandlers();
@ -85,15 +97,6 @@ class ProjectChecker
echo 'Checking ' . $file_name . PHP_EOL;
}
if ($file_list) {
if (in_array($file_name, $file_list)) {
echo 'Checking affected file ' . $file_name . PHP_EOL;
}
else {
continue;
}
}
if (isset($filetype_handlers[$extension])) {
/** @var FileChecker */
$file_checker = new $filetype_handlers[$extension]($file_name);
@ -110,6 +113,35 @@ class ProjectChecker
}
}
protected static function getDiffFilesInDir($dir_name, Config $config)
{
$file_extensions = $config->getFileExtensions();
$filetype_handlers = $config->getFiletypeHandlers();
/** @var RecursiveDirectoryIterator */
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir_name));
$iterator->rewind();
$diff_files = [];
while ($iterator->valid()) {
if (!$iterator->isDot()) {
$extension = $iterator->getExtension();
if (in_array($extension, $file_extensions)) {
$file_name = $iterator->getRealPath();
if (FileChecker::hasFileChanged($file_name)) {
$diff_files[] = $file_name;
}
}
}
$iterator->next();
}
return $diff_files;
}
protected static function checkDiffFilesWithConfig(array $file_list = [], Config $config, $debug)
{
$file_extensions = $config->getFileExtensions();

View File

@ -64,12 +64,16 @@ class IssueBuffer
return true;
}
public static function finish()
public static function finish($is_full = false)
{
Checker\FileChecker::updateReferenceCache();
if (count(self::$errors)) {
exit(1);
}
if ($is_full) {
Checker\FileChecker::goodRun();
}
}
}