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

Fix #3367 - ensure --diff works after second run, not third

This commit is contained in:
Brown 2020-06-05 12:09:38 -04:00
parent 8638fdc733
commit 438eb17e58
6 changed files with 1741 additions and 21 deletions

View File

@ -256,6 +256,8 @@ class ProjectAnalyzer
$this->threads = $threads; $this->threads = $threads;
$this->config = $config; $this->config = $config;
$this->clearCacheDirectoryIfConfigOrComposerLockfileChanged();
$this->codebase = new Codebase( $this->codebase = new Codebase(
$config, $config,
$providers, $providers,
@ -281,17 +283,38 @@ class ProjectAnalyzer
$this->addProjectFile($file_path); $this->addProjectFile($file_path);
} }
if ($this->project_cache_provider && $this->project_cache_provider->hasLockfileChanged()) { self::$instance = $this;
}
private function clearCacheDirectoryIfConfigOrComposerLockfileChanged() : void
{
if ($this->project_cache_provider
&& $this->project_cache_provider->hasLockfileChanged()
) {
$this->progress->debug( $this->progress->debug(
'Composer lockfile change detected, clearing cache' . "\n" 'Composer lockfile change detected, clearing cache' . "\n"
); );
Config::removeCacheDirectory($config->getCacheDirectory()); Config::removeCacheDirectory($this->config->getCacheDirectory());
if ($this->file_reference_provider->cache) {
$this->file_reference_provider->cache->hasConfigChanged();
}
$this->project_cache_provider->updateComposerLockHash(); $this->project_cache_provider->updateComposerLockHash();
} } elseif ($this->file_reference_provider->cache
&& $this->file_reference_provider->cache->hasConfigChanged()
) {
$this->progress->debug(
'Config change detected, clearing cache' . "\n"
);
self::$instance = $this; Config::removeCacheDirectory($this->config->getCacheDirectory());
if ($this->project_cache_provider) {
$this->project_cache_provider->hasLockfileChanged();
}
}
} }
/** /**

View File

@ -41,16 +41,16 @@ class FileReferenceCacheProvider
*/ */
private $config; private $config;
/**
* @var bool
*/
public $config_changed;
public function __construct(Config $config) public function __construct(Config $config)
{ {
$this->config = $config; $this->config = $config;
$this->config_changed = $config->hash !== $this->getConfigHashCache(); }
$this->setConfigHashCache($config->hash);
public function hasConfigChanged() : bool
{
$has_changed = $this->config->hash !== $this->getConfigHashCache();
$this->setConfigHashCache($this->config->hash);
return $has_changed;
} }
/** /**
@ -62,7 +62,7 @@ class FileReferenceCacheProvider
{ {
$cache_directory = $this->config->getCacheDirectory(); $cache_directory = $this->config->getCacheDirectory();
if (!$cache_directory || $this->config_changed) { if (!$cache_directory) {
return null; return null;
} }
@ -90,7 +90,7 @@ class FileReferenceCacheProvider
{ {
$cache_directory = $this->config->getCacheDirectory(); $cache_directory = $this->config->getCacheDirectory();
if (!$cache_directory || $this->config_changed) { if (!$cache_directory) {
return null; return null;
} }
@ -549,7 +549,6 @@ class FileReferenceCacheProvider
if ($cache_directory if ($cache_directory
&& file_exists($analyzed_methods_cache_location) && file_exists($analyzed_methods_cache_location)
&& !$this->config_changed
) { ) {
/** @var array<string, array<string, int>> */ /** @var array<string, array<string, int>> */
return unserialize(file_get_contents($analyzed_methods_cache_location)); return unserialize(file_get_contents($analyzed_methods_cache_location));
@ -590,7 +589,6 @@ class FileReferenceCacheProvider
if ($cache_directory if ($cache_directory
&& file_exists($file_maps_cache_location) && file_exists($file_maps_cache_location)
&& !$this->config_changed
) { ) {
/** /**
* @var array<string, FileMapType> * @var array<string, FileMapType>
@ -633,7 +631,6 @@ class FileReferenceCacheProvider
if ($cache_directory if ($cache_directory
&& file_exists($type_coverage_cache_location) && file_exists($type_coverage_cache_location)
&& !$this->config_changed
) { ) {
/** @var array<string, array{int, int}> */ /** @var array<string, array{int, int}> */
$type_coverage_cache = unserialize(file_get_contents($type_coverage_cache_location)); $type_coverage_cache = unserialize(file_get_contents($type_coverage_cache_location));
@ -676,7 +673,7 @@ class FileReferenceCacheProvider
&& file_exists($config_hash_cache_location) && file_exists($config_hash_cache_location)
) { ) {
/** @var string */ /** @var string */
$file_maps_cache = unserialize(file_get_contents($config_hash_cache_location)); $file_maps_cache = file_get_contents($config_hash_cache_location);
return $file_maps_cache; return $file_maps_cache;
} }
@ -700,7 +697,7 @@ class FileReferenceCacheProvider
file_put_contents( file_put_contents(
$config_hash_cache_location, $config_hash_cache_location,
serialize($hash) $hash
); );
} }
} }

View File

@ -48,6 +48,7 @@ class PsalmEndToEndTest extends TestCase
mkdir(self::$tmpDir . '/src'); mkdir(self::$tmpDir . '/src');
copy(__DIR__ . '/../fixtures/DummyProjectWithErrors/composer.json', self::$tmpDir . '/composer.json'); copy(__DIR__ . '/../fixtures/DummyProjectWithErrors/composer.json', self::$tmpDir . '/composer.json');
copy(__DIR__ . '/../fixtures/DummyProjectWithErrors/composer.lock', self::$tmpDir . '/composer.lock');
(new Process(['composer', 'install', '--no-plugins'], self::$tmpDir))->mustRun(); (new Process(['composer', 'install', '--no-plugins'], self::$tmpDir))->mustRun();
} }
@ -65,6 +66,14 @@ class PsalmEndToEndTest extends TestCase
parent::setUp(); parent::setUp();
} }
public function tearDown(): void
{
if (\file_exists(self::$tmpDir . '/cache')) {
self::recursiveRemoveDirectory(self::$tmpDir . '/cache');
}
parent::tearDown();
}
public function testHelpReturnsMessage(): void public function testHelpReturnsMessage(): void
{ {
$this->assertStringContainsString('Usage:', $this->runPsalm(['--help'], self::$tmpDir)['STDOUT']); $this->assertStringContainsString('Usage:', $this->runPsalm(['--help'], self::$tmpDir)['STDOUT']);
@ -110,6 +119,27 @@ class PsalmEndToEndTest extends TestCase
$this->assertSame(1, $result['CODE']); $this->assertSame(1, $result['CODE']);
} }
public function testPsalmDiff(): void
{
$this->runPsalmInit(1);
$result = $this->runPsalm(['--diff', '-m'], self::$tmpDir, true);
$this->assertStringContainsString('InvalidReturnType', $result['STDOUT']);
$this->assertStringContainsString('InvalidReturnStatement', $result['STDOUT']);
$this->assertStringContainsString('2 errors', $result['STDOUT']);
$this->assertStringContainsString('E', $result['STDERR']);
$this->assertSame(1, $result['CODE']);
$result = $this->runPsalm(['--diff', '-m'], self::$tmpDir, true);
$this->assertStringContainsString('InvalidReturnType', $result['STDOUT']);
$this->assertStringContainsString('InvalidReturnStatement', $result['STDOUT']);
$this->assertStringContainsString('2 errors', $result['STDOUT']);
$this->assertStringNotContainsString('E', $result['STDERR']);
$this->assertSame(1, $result['CODE']);
}
public function testLegacyConfigWithoutresolveFromConfigFile(): void public function testLegacyConfigWithoutresolveFromConfigFile(): void
{ {
$this->runPsalmInit(1); $this->runPsalmInit(1);
@ -137,7 +167,18 @@ class PsalmEndToEndTest extends TestCase
$args[] = 'src'; $args[] = 'src';
$args[] = (string) $level; $args[] = (string) $level;
} }
return $this->runPsalm($args, self::$tmpDir, false, false);
$ret = $this->runPsalm($args, self::$tmpDir, false, false);
$psalm_config_contents = file_get_contents(self::$tmpDir . '/psalm.xml');
$psalm_config_contents = \str_replace(
'errorLevel="1"',
'errorLevel="1" cacheDirectory="' . self::$tmpDir . '/cache"',
$psalm_config_contents
);
file_put_contents(self::$tmpDir . '/psalm.xml', $psalm_config_contents);
return $ret;
} }
/** from comment by itay at itgoldman dot com at /** from comment by itay at itgoldman dot com at

View File

@ -57,7 +57,6 @@ class FakeFileReferenceCacheProvider extends \Psalm\Internal\Provider\FileRefere
public function __construct() public function __construct()
{ {
$this->config_changed = false;
} }
/** /**

View File

@ -2,7 +2,9 @@
"name": "acme/sample-project", "name": "acme/sample-project",
"description": "A sample project to be used when testing Psalm", "description": "A sample project to be used when testing Psalm",
"type": "project", "type": "project",
"require": {}, "require": {
"vimeo/psalm": "^3.11"
},
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Acme\\SampleProject\\": "src/" "Acme\\SampleProject\\": "src/"

1658
tests/fixtures/DummyProjectWithErrors/composer.lock generated vendored Normal file

File diff suppressed because it is too large Load Diff