Skip to content

Commit

Permalink
Result cache does not get invalidated when only ignoreErrors changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Nov 19, 2020
1 parent ec69b39 commit ef84d94
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 60 deletions.
3 changes: 0 additions & 3 deletions conf/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ parametersSchema:

# internal parameters only for DerivativeContainerFactory
additionalConfigFiles: listOf(string())
allCustomConfigFiles: listOf(string())
analysedPaths: listOf(string())
composerAutoloaderProjectPaths: listOf(string())
analysedPathsFromConfig: listOf(string())
Expand Down Expand Up @@ -392,7 +391,6 @@ services:
arguments:
cacheFilePath: %tmpDir%/resultCache.php
tempResultCachePath: %tempResultCachePath%
allCustomConfigFiles: %allCustomConfigFiles%
analysedPaths: %analysedPaths%
composerAutoloaderProjectPaths: %composerAutoloaderProjectPaths%
stubFiles: %stubFiles%
Expand Down Expand Up @@ -467,7 +465,6 @@ services:
analysedPaths: %analysedPaths%
composerAutoloaderProjectPaths: %composerAutoloaderProjectPaths%
analysedPathsFromConfig: %analysedPathsFromConfig%
allCustomConfigFiles: %allCustomConfigFiles%
usedLevel: %usedLevel%

-
Expand Down
52 changes: 24 additions & 28 deletions src/Analyser/ResultCache/ResultCacheManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ class ResultCacheManager

private string $tempResultCachePath;

/** @var string[] */
private array $allCustomConfigFiles;

/** @var string[] */
private array $analysedPaths;

Expand All @@ -49,7 +46,6 @@ class ResultCacheManager
* @param ExportedNodeFetcher $exportedNodeFetcher
* @param string $cacheFilePath
* @param string $tempResultCachePath
* @param string[] $allCustomConfigFiles
* @param string[] $analysedPaths
* @param string[] $composerAutoloaderProjectPaths
* @param string[] $stubFiles
Expand All @@ -61,7 +57,6 @@ public function __construct(
ExportedNodeFetcher $exportedNodeFetcher,
string $cacheFilePath,
string $tempResultCachePath,
array $allCustomConfigFiles,
array $analysedPaths,
array $composerAutoloaderProjectPaths,
array $stubFiles,
Expand All @@ -73,7 +68,6 @@ public function __construct(
$this->exportedNodeFetcher = $exportedNodeFetcher;
$this->cacheFilePath = $cacheFilePath;
$this->tempResultCachePath = $tempResultCachePath;
$this->allCustomConfigFiles = $allCustomConfigFiles;
$this->analysedPaths = $analysedPaths;
$this->composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths;
$this->stubFiles = $stubFiles;
Expand All @@ -84,10 +78,11 @@ public function __construct(

/**
* @param string[] $allAnalysedFiles
* @param mixed[]|null $projectConfigArray
* @param bool $debug
* @return ResultCache
*/
public function restore(array $allAnalysedFiles, bool $debug, bool $onlyFiles, Output $output, ?string $resultCacheName = null): ResultCache
public function restore(array $allAnalysedFiles, bool $debug, bool $onlyFiles, ?array $projectConfigArray, Output $output, ?string $resultCacheName = null): ResultCache
{
if ($debug) {
if ($output->isDebug()) {
Expand Down Expand Up @@ -134,7 +129,7 @@ public function restore(array $allAnalysedFiles, bool $debug, bool $onlyFiles, O
return new ResultCache($allAnalysedFiles, true, time(), [], [], []);
}

if ($data['meta'] !== $this->getMeta()) {
if ($data['meta'] !== $this->getMeta($projectConfigArray)) {
if ($output->isDebug()) {
$output->writeLineFormatted('Result cache not used because the metadata do not match.');
}
Expand Down Expand Up @@ -257,19 +252,20 @@ private function exportedNodesChanged(string $analysedFile, array $cachedFileExp
/**
* @param AnalyserResult $analyserResult
* @param ResultCache $resultCache
* @param mixed[]|null $projectConfigArray
* @param bool|string $save
* @return ResultCacheProcessResult
* @throws \PHPStan\ShouldNotHappenException
*/
public function process(AnalyserResult $analyserResult, ResultCache $resultCache, Output $output, bool $onlyFiles, $save): ResultCacheProcessResult
public function process(AnalyserResult $analyserResult, ResultCache $resultCache, Output $output, bool $onlyFiles, ?array $projectConfigArray, $save): ResultCacheProcessResult
{
$internalErrors = $analyserResult->getInternalErrors();
$freshErrorsByFile = [];
foreach ($analyserResult->getErrors() as $error) {
$freshErrorsByFile[$error->getFilePath()][] = $error;
}

$doSave = function (array $errorsByFile, ?array $dependencies, array $exportedNodes, ?string $resultCacheName) use ($internalErrors, $resultCache, $output, $onlyFiles): bool {
$doSave = function (array $errorsByFile, ?array $dependencies, array $exportedNodes, ?string $resultCacheName) use ($internalErrors, $resultCache, $output, $onlyFiles, $projectConfigArray): bool {
if ($onlyFiles) {
if ($output->isDebug()) {
$output->writeLineFormatted('Result cache was not saved because only files were passed as analysed paths.');
Expand Down Expand Up @@ -304,7 +300,7 @@ public function process(AnalyserResult $analyserResult, ResultCache $resultCache
}
}

$this->save($resultCache->getLastFullAnalysisTime(), $resultCacheName, $errorsByFile, $dependencies, $exportedNodes);
$this->save($resultCache->getLastFullAnalysisTime(), $resultCacheName, $errorsByFile, $dependencies, $exportedNodes, $projectConfigArray);

if ($output->isDebug()) {
$output->writeLineFormatted('Result cache is saved.');
Expand Down Expand Up @@ -438,13 +434,15 @@ private function mergeExportedNodes(ResultCache $resultCache, array $freshExport
* @param array<string, array<Error>> $errors
* @param array<string, array<string>> $dependencies
* @param array<string, array<ExportedNode>> $exportedNodes
* @param mixed[]|null $projectConfigArray
*/
private function save(
int $lastFullAnalysisTime,
?string $resultCacheName,
array $errors,
array $dependencies,
array $exportedNodes
array $exportedNodes,
?array $projectConfigArray
): void
{
$invertedDependencies = [];
Expand Down Expand Up @@ -510,7 +508,7 @@ private function save(
sprintf(
$template,
var_export($lastFullAnalysisTime, true),
var_export($this->getMeta(), true),
var_export($this->getMeta($projectConfigArray), true),
var_export($errors, true),
var_export($invertedDependencies, true),
var_export($exportedNodes, true)
Expand All @@ -519,20 +517,31 @@ private function save(
}

/**
* @param mixed[]|null $projectConfigArray
* @return mixed[]
*/
private function getMeta(): array
private function getMeta(?array $projectConfigArray): array
{
$extensions = array_values(array_filter(get_loaded_extensions(), static function (string $extension): bool {
return $extension !== 'xdebug';
}));
sort($extensions);

if ($projectConfigArray !== null) {
unset($projectConfigArray['parameters']['ignoreErrors']);
unset($projectConfigArray['parameters']['tipsOfTheDay']);
unset($projectConfigArray['parameters']['parallel']);
unset($projectConfigArray['parameters']['internalErrorsCountLimit']);
unset($projectConfigArray['parameters']['cache']);
unset($projectConfigArray['parameters']['reportUnmatchedIgnoredErrors']);
unset($projectConfigArray['parameters']['memoryLimitFile']);
}

return [
'cacheVersion' => self::CACHE_VERSION,
'phpstanVersion' => $this->getPhpStanVersion(),
'phpVersion' => PHP_VERSION_ID,
'configFiles' => $this->getConfigFiles(),
'projectConfig' => $projectConfigArray,
'analysedPaths' => $this->analysedPaths,
'composerLocks' => $this->getComposerLocks(),
'cliAutoloadFile' => $this->cliAutoloadFile,
Expand All @@ -542,19 +551,6 @@ private function getMeta(): array
];
}

/**
* @return array<string, string>
*/
private function getConfigFiles(): array
{
$configFiles = [];
foreach ($this->allCustomConfigFiles as $configFile) {
$configFiles[$configFile] = $this->getFileHash($configFile);
}

return $configFiles;
}

private function getFileHash(string $path): string
{
if (array_key_exists($path, $this->fileReplacements)) {
Expand Down
6 changes: 4 additions & 2 deletions src/Command/AnalyseApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public function __construct(
* @param bool $defaultLevelUsed
* @param bool $debug
* @param string|null $projectConfigFile
* @param mixed[]|null $projectConfigArray
* @return AnalysisResult
*/
public function analyse(
Expand All @@ -59,6 +60,7 @@ public function analyse(
bool $defaultLevelUsed,
bool $debug,
?string $projectConfigFile,
?array $projectConfigArray,
InputInterface $input
): AnalysisResult
{
Expand Down Expand Up @@ -93,7 +95,7 @@ public function analyse(
$errorOutput->writeLineFormatted('Result cache was not saved because of ignoredErrorHelperResult errors.');
}
} else {
$resultCache = $resultCacheManager->restore($files, $debug, $onlyFiles, $errorOutput);
$resultCache = $resultCacheManager->restore($files, $debug, $onlyFiles, $projectConfigArray, $errorOutput);
$intermediateAnalyserResult = $this->runAnalyser(
$resultCache->getFilesToAnalyse(),
$files,
Expand All @@ -103,7 +105,7 @@ public function analyse(
$errorOutput,
$input
);
$resultCacheResult = $resultCacheManager->process($intermediateAnalyserResult, $resultCache, $errorOutput, $onlyFiles, true);
$resultCacheResult = $resultCacheManager->process($intermediateAnalyserResult, $resultCache, $errorOutput, $onlyFiles, $projectConfigArray, true);
$analyserResult = $resultCacheResult->getAnalyserResult();
$internalErrors = $analyserResult->getInternalErrors();
$errors = $ignoredErrorHelperResult->process($analyserResult->getErrors(), $onlyFiles, $files, count($internalErrors) > 0 || $analyserResult->hasReachedInternalErrorsCountLimit());
Expand Down
1 change: 1 addition & 0 deletions src/Command/AnalyseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$inceptionResult->isDefaultLevelUsed(),
$debug,
$inceptionResult->getProjectConfigFile(),
$inceptionResult->getProjectConfigArray(),
$input
);

Expand Down
17 changes: 3 additions & 14 deletions src/Command/CommandHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ public static function begin(

$analysedPathsFromConfig = [];
$containerFactory = new ContainerFactory($currentWorkingDirectory);
$projectConfig = null;
if ($projectConfigFile !== null) {
if (!is_file($projectConfigFile)) {
$errorOutput->writeLineFormatted(sprintf('Project config file at path %s does not exist.', $projectConfigFile));
Expand Down Expand Up @@ -233,21 +234,8 @@ public static function begin(
$createDir($tmpDir);
}

if ($projectConfigFile !== null) {
$allCustomConfigFiles = self::getConfigFiles(
$currentWorkingDirectoryFileHelper,
new NeonAdapter(),
new PhpAdapter(),
$projectConfigFile,
$loaderParameters,
$generateBaselineFile
);
} else {
$allCustomConfigFiles = [];
}

try {
$container = $containerFactory->create($tmpDir, $additionalConfigFiles, $paths, $composerAutoloaderProjectPaths, $analysedPathsFromConfig, $allCustomConfigFiles, $level ?? self::DEFAULT_LEVEL, $generateBaselineFile, $autoloadFile, $singleReflectionFile);
$container = $containerFactory->create($tmpDir, $additionalConfigFiles, $paths, $composerAutoloaderProjectPaths, $analysedPathsFromConfig, $level ?? self::DEFAULT_LEVEL, $generateBaselineFile, $autoloadFile, $singleReflectionFile);
} catch (\Nette\DI\InvalidConfigurationException | \Nette\Utils\AssertionException $e) {
$errorOutput->writeLineFormatted('<error>Invalid configuration:</error>');
$errorOutput->writeLineFormatted($e->getMessage());
Expand Down Expand Up @@ -414,6 +402,7 @@ public static function begin(
$defaultLevelUsed,
$memoryLimitFile,
$projectConfigFile,
$projectConfig,
$generateBaselineFile
);
}
Expand Down
7 changes: 5 additions & 2 deletions src/Command/FixerApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ private function reanalyseWithTmpFile(
{
$resultCacheManager = $this->resultCacheManagerFactory->create([$insteadOfFile => $tmpFile]);
[$inceptionFiles] = $inceptionResult->getFiles();
$resultCache = $resultCacheManager->restore($inceptionFiles, false, false, $inceptionResult->getErrorOutput());
$resultCache = $resultCacheManager->restore($inceptionFiles, false, false, $inceptionResult->getProjectConfigArray(), $inceptionResult->getErrorOutput());
$schedule = $this->scheduler->scheduleWork($this->cpuCoreCounter->getNumberOfCpuCores(), $resultCache->getFilesToAnalyse());

$process = new ProcessPromise($loop, $fixerSuggestionId, ProcessHelper::getWorkerCommand(
Expand Down Expand Up @@ -506,15 +506,18 @@ private function reanalyseAfterFileChanges(
throw new \PHPStan\ShouldNotHappenException();
}

$projectConfigArray = $inceptionResult->getProjectConfigArray();

$resultCacheManager = $this->resultCacheManagerFactory->create([]);
[$inceptionFiles, $isOnlyFiles] = $inceptionResult->getFiles();
$resultCache = $resultCacheManager->restore($inceptionFiles, false, false, $inceptionResult->getErrorOutput(), $fixerSuggestionId);
$resultCache = $resultCacheManager->restore($inceptionFiles, false, false, $projectConfigArray, $inceptionResult->getErrorOutput(), $fixerSuggestionId);
if (count($resultCache->getFilesToAnalyse()) === 0) {
$result = $resultCacheManager->process(
new AnalyserResult([], [], [], [], false),
$resultCache,
$inceptionResult->getErrorOutput(),
false,
$projectConfigArray,
true
)->getAnalyserResult();
$intermediateErrors = $ignoredErrorHelperResult->process(
Expand Down
4 changes: 3 additions & 1 deletion src/Command/FixerWorkerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}
/** @var ResultCacheManager $resultCacheManager */
$resultCacheManager = $container->getByType(ResultCacheManagerFactory::class)->create($fileReplacements);
$projectConfigArray = $inceptionResult->getProjectConfigArray();
[$inceptionFiles, $isOnlyFiles] = $inceptionResult->getFiles();
$resultCache = $resultCacheManager->restore($inceptionFiles, false, false, $inceptionResult->getErrorOutput(), $restoreResultCache);
$resultCache = $resultCacheManager->restore($inceptionFiles, false, false, $projectConfigArray, $inceptionResult->getErrorOutput(), $restoreResultCache);

$intermediateAnalyserResult = $analyserRunner->runAnalyser(
$resultCache->getFilesToAnalyse(),
Expand All @@ -161,6 +162,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$resultCache,
$inceptionResult->getErrorOutput(),
false,
$projectConfigArray,
is_string($saveResultCache) ? $saveResultCache : $saveResultCache === null
)->getAnalyserResult();

Expand Down
14 changes: 14 additions & 0 deletions src/Command/InceptionResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class InceptionResult

private ?string $projectConfigFile;

/** @var mixed[]|null */
private ?array $projectConfigArray;

private ?string $generateBaselineFile;

/**
Expand All @@ -34,6 +37,7 @@ class InceptionResult
* @param bool $isDefaultLevelUsed
* @param string $memoryLimitFile
* @param string|null $projectConfigFile
* @param mixed[] $projectConfigArray
* @param string|null $generateBaselineFile
*/
public function __construct(
Expand All @@ -44,6 +48,7 @@ public function __construct(
bool $isDefaultLevelUsed,
string $memoryLimitFile,
?string $projectConfigFile,
?array $projectConfigArray,
?string $generateBaselineFile
)
{
Expand All @@ -54,6 +59,7 @@ public function __construct(
$this->isDefaultLevelUsed = $isDefaultLevelUsed;
$this->memoryLimitFile = $memoryLimitFile;
$this->projectConfigFile = $projectConfigFile;
$this->projectConfigArray = $projectConfigArray;
$this->generateBaselineFile = $generateBaselineFile;
}

Expand Down Expand Up @@ -92,6 +98,14 @@ public function getProjectConfigFile(): ?string
return $this->projectConfigFile;
}

/**
* @return mixed[]|null
*/
public function getProjectConfigArray(): ?array
{
return $this->projectConfigArray;
}

public function getGenerateBaselineFile(): ?string
{
return $this->generateBaselineFile;
Expand Down
3 changes: 0 additions & 3 deletions src/DependencyInjection/ContainerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ public function __construct(string $currentWorkingDirectory)
* @param string[] $analysedPaths
* @param string[] $composerAutoloaderProjectPaths
* @param string[] $analysedPathsFromConfig
* @param string[] $allCustomConfigFiles
* @param string $usedLevel
* @param string|null $generateBaselineFile
* @param string|null $cliAutoloadFile
Expand All @@ -59,7 +58,6 @@ public function create(
array $analysedPaths,
array $composerAutoloaderProjectPaths = [],
array $analysedPathsFromConfig = [],
array $allCustomConfigFiles = [],
string $usedLevel = CommandHelper::DEFAULT_LEVEL,
?string $generateBaselineFile = null,
?string $cliAutoloadFile = null,
Expand Down Expand Up @@ -87,7 +85,6 @@ public function create(
'analysedPaths' => $analysedPaths,
'composerAutoloaderProjectPaths' => $composerAutoloaderProjectPaths,
'analysedPathsFromConfig' => $analysedPathsFromConfig,
'allCustomConfigFiles' => $allCustomConfigFiles,
'usedLevel' => $usedLevel,
'cliAutoloadFile' => $cliAutoloadFile,
'fixerTmpDir' => sys_get_temp_dir() . '/phpstan-fixer',
Expand Down
Loading

0 comments on commit ef84d94

Please sign in to comment.