2020-04-01 01:55:44 +00:00
|
|
|
<?php
|
|
|
|
|
2021-05-09 20:15:43 +00:00
|
|
|
declare (strict_types=1);
|
2022-06-06 17:12:56 +00:00
|
|
|
namespace Rector\Caching\Detector;
|
2020-04-01 01:55:44 +00:00
|
|
|
|
2022-08-02 06:46:18 +00:00
|
|
|
use RectorPrefix202208\Nette\Utils\Strings;
|
2022-06-06 17:12:56 +00:00
|
|
|
use Rector\Caching\Cache;
|
|
|
|
use Rector\Caching\Config\FileHashComputer;
|
|
|
|
use Rector\Caching\Enum\CacheKey;
|
2022-08-29 14:03:46 +00:00
|
|
|
use Symplify\SmartFileSystem\SmartFileInfo;
|
2020-04-01 01:55:44 +00:00
|
|
|
/**
|
|
|
|
* Inspired by https://github.com/symplify/symplify/pull/90/files#diff-72041b2e1029a08930e13d79d298ef11
|
2021-06-11 11:03:31 +00:00
|
|
|
*
|
|
|
|
* @see \Rector\Tests\Caching\Detector\ChangedFilesDetectorTest
|
2020-04-01 01:55:44 +00:00
|
|
|
*/
|
|
|
|
final class ChangedFilesDetector
|
|
|
|
{
|
|
|
|
/**
|
2021-12-04 12:47:17 +00:00
|
|
|
* @readonly
|
2021-05-10 23:39:21 +00:00
|
|
|
* @var \Rector\Caching\Config\FileHashComputer
|
2020-04-01 01:55:44 +00:00
|
|
|
*/
|
2021-03-18 01:11:54 +00:00
|
|
|
private $fileHashComputer;
|
2020-04-01 01:55:44 +00:00
|
|
|
/**
|
2021-12-04 12:47:17 +00:00
|
|
|
* @readonly
|
2021-06-11 11:03:31 +00:00
|
|
|
* @var \Rector\Caching\Cache
|
2020-04-01 01:55:44 +00:00
|
|
|
*/
|
2021-03-18 01:11:54 +00:00
|
|
|
private $cache;
|
2022-06-07 08:22:29 +00:00
|
|
|
public function __construct(FileHashComputer $fileHashComputer, Cache $cache)
|
2020-04-01 01:55:44 +00:00
|
|
|
{
|
|
|
|
$this->fileHashComputer = $fileHashComputer;
|
2021-03-18 01:11:54 +00:00
|
|
|
$this->cache = $cache;
|
2020-04-01 01:55:44 +00:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @param string[] $dependentFiles
|
|
|
|
*/
|
2022-06-07 08:22:29 +00:00
|
|
|
public function addFileWithDependencies(SmartFileInfo $smartFileInfo, array $dependentFiles) : void
|
2020-04-01 01:55:44 +00:00
|
|
|
{
|
|
|
|
$fileInfoCacheKey = $this->getFileInfoCacheKey($smartFileInfo);
|
|
|
|
$hash = $this->hashFile($smartFileInfo);
|
2022-06-07 08:22:29 +00:00
|
|
|
$this->cache->save($fileInfoCacheKey, CacheKey::FILE_HASH_KEY, $hash);
|
|
|
|
$this->cache->save($fileInfoCacheKey . '_files', CacheKey::DEPENDENT_FILES_KEY, $dependentFiles);
|
2020-04-01 01:55:44 +00:00
|
|
|
}
|
2022-06-07 08:22:29 +00:00
|
|
|
public function hasFileChanged(SmartFileInfo $smartFileInfo) : bool
|
2020-04-01 01:55:44 +00:00
|
|
|
{
|
|
|
|
$currentFileHash = $this->hashFile($smartFileInfo);
|
|
|
|
$fileInfoCacheKey = $this->getFileInfoCacheKey($smartFileInfo);
|
2022-06-07 08:22:29 +00:00
|
|
|
$cachedValue = $this->cache->load($fileInfoCacheKey, CacheKey::FILE_HASH_KEY);
|
2021-03-18 01:11:54 +00:00
|
|
|
return $currentFileHash !== $cachedValue;
|
2020-04-01 01:55:44 +00:00
|
|
|
}
|
2022-06-07 08:22:29 +00:00
|
|
|
public function invalidateFile(SmartFileInfo $smartFileInfo) : void
|
2020-04-01 01:55:44 +00:00
|
|
|
{
|
|
|
|
$fileInfoCacheKey = $this->getFileInfoCacheKey($smartFileInfo);
|
2021-06-11 11:03:31 +00:00
|
|
|
$this->cache->clean($fileInfoCacheKey);
|
2020-04-01 01:55:44 +00:00
|
|
|
}
|
2021-05-09 20:15:43 +00:00
|
|
|
public function clear() : void
|
2020-04-01 01:55:44 +00:00
|
|
|
{
|
2021-06-11 11:03:31 +00:00
|
|
|
$this->cache->clear();
|
2020-04-01 01:55:44 +00:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @return SmartFileInfo[]
|
|
|
|
*/
|
2022-06-07 08:22:29 +00:00
|
|
|
public function getDependentFileInfos(SmartFileInfo $fileInfo) : array
|
2020-04-01 01:55:44 +00:00
|
|
|
{
|
|
|
|
$fileInfoCacheKey = $this->getFileInfoCacheKey($fileInfo);
|
2022-06-07 08:22:29 +00:00
|
|
|
$cacheValue = $this->cache->load($fileInfoCacheKey . '_files', CacheKey::DEPENDENT_FILES_KEY);
|
2021-03-18 01:11:54 +00:00
|
|
|
if ($cacheValue === null) {
|
2020-04-01 01:55:44 +00:00
|
|
|
return [];
|
|
|
|
}
|
|
|
|
$dependentFileInfos = [];
|
2021-03-18 01:11:54 +00:00
|
|
|
$dependentFiles = $cacheValue;
|
2020-04-01 01:55:44 +00:00
|
|
|
foreach ($dependentFiles as $dependentFile) {
|
2021-05-09 20:15:43 +00:00
|
|
|
if (!\file_exists($dependentFile)) {
|
2020-04-01 01:55:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
2022-06-07 08:22:29 +00:00
|
|
|
$dependentFileInfos[] = new SmartFileInfo($dependentFile);
|
2020-04-01 01:55:44 +00:00
|
|
|
}
|
|
|
|
return $dependentFileInfos;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @api
|
|
|
|
*/
|
2021-11-01 14:32:25 +00:00
|
|
|
public function setFirstResolvedConfigFileInfo(string $filePath) : void
|
2020-04-01 01:55:44 +00:00
|
|
|
{
|
|
|
|
// the first config is core to all → if it was changed, just invalidate it
|
2021-11-01 14:32:25 +00:00
|
|
|
$configHash = $this->fileHashComputer->compute($filePath);
|
|
|
|
$this->storeConfigurationDataHash($filePath, $configHash);
|
2020-04-01 01:55:44 +00:00
|
|
|
}
|
2022-06-07 08:22:29 +00:00
|
|
|
private function getFileInfoCacheKey(SmartFileInfo $smartFileInfo) : string
|
2020-04-26 00:57:47 +00:00
|
|
|
{
|
2021-05-09 20:15:43 +00:00
|
|
|
return \sha1($smartFileInfo->getRealPath());
|
2020-04-26 00:57:47 +00:00
|
|
|
}
|
2022-06-07 08:22:29 +00:00
|
|
|
private function hashFile(SmartFileInfo $smartFileInfo) : string
|
2020-04-01 01:55:44 +00:00
|
|
|
{
|
2021-05-09 20:15:43 +00:00
|
|
|
return (string) \sha1_file($smartFileInfo->getRealPath());
|
2020-04-01 01:55:44 +00:00
|
|
|
}
|
2021-11-01 14:32:25 +00:00
|
|
|
private function storeConfigurationDataHash(string $filePath, string $configurationHash) : void
|
2020-04-01 01:55:44 +00:00
|
|
|
{
|
2022-06-07 08:22:29 +00:00
|
|
|
$key = CacheKey::CONFIGURATION_HASH_KEY . '_' . Strings::webalize($filePath);
|
2020-04-01 01:55:44 +00:00
|
|
|
$this->invalidateCacheIfConfigurationChanged($key, $configurationHash);
|
2022-06-07 08:22:29 +00:00
|
|
|
$this->cache->save($key, CacheKey::CONFIGURATION_HASH_KEY, $configurationHash);
|
2020-04-01 01:55:44 +00:00
|
|
|
}
|
2021-05-09 20:15:43 +00:00
|
|
|
private function invalidateCacheIfConfigurationChanged(string $key, string $configurationHash) : void
|
2020-04-01 01:55:44 +00:00
|
|
|
{
|
2022-06-07 08:22:29 +00:00
|
|
|
$oldCachedValue = $this->cache->load($key, CacheKey::CONFIGURATION_HASH_KEY);
|
2022-01-03 05:20:02 +00:00
|
|
|
if ($oldCachedValue === null) {
|
|
|
|
return;
|
|
|
|
}
|
2021-03-18 01:11:54 +00:00
|
|
|
if ($oldCachedValue === $configurationHash) {
|
|
|
|
return;
|
2020-04-01 01:55:44 +00:00
|
|
|
}
|
2021-03-18 01:11:54 +00:00
|
|
|
// should be unique per getcwd()
|
|
|
|
$this->clear();
|
2020-04-01 01:55:44 +00:00
|
|
|
}
|
|
|
|
}
|