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:
parent
68ec49d991
commit
d8d26a3f40
14
bin/psalm
14
bin/psalm
@ -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)) {
|
||||
|
@ -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 = [];
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user