rector/packages/Caching/Detector/ChangedFilesDetector.php

139 lines
3.8 KiB
PHP
Raw Normal View History

2020-04-01 01:55:44 +00:00
<?php
declare(strict_types=1);
namespace Rector\Caching\Detector;
2020-04-01 01:55:44 +00:00
use Nette\Caching\Cache;
2020-04-01 01:55:44 +00:00
use Nette\Utils\Strings;
use Rector\Caching\Config\FileHashComputer;
use Symplify\SmartFileSystem\SmartFileInfo;
/**
* Inspired by https://github.com/symplify/symplify/pull/90/files#diff-72041b2e1029a08930e13d79d298ef11
* @see \Rector\Caching\Tests\Detector\ChangedFilesDetectorTest
2020-04-01 01:55:44 +00:00
*/
final class ChangedFilesDetector
{
/**
* @var string
*/
private const CONFIGURATION_HASH_KEY = 'configuration_hash';
/**
* @var FileHashComputer
2020-04-01 01:55:44 +00:00
*/
private $fileHashComputer;
2020-04-01 01:55:44 +00:00
/**
* @var Cache
2020-04-01 01:55:44 +00:00
*/
private $cache;
2020-04-01 01:55:44 +00:00
public function __construct(FileHashComputer $fileHashComputer, Cache $cache)
2020-04-01 01:55:44 +00:00
{
$this->fileHashComputer = $fileHashComputer;
$this->cache = $cache;
2020-04-01 01:55:44 +00:00
}
/**
* @param string[] $dependentFiles
*/
public function addFileWithDependencies(SmartFileInfo $smartFileInfo, array $dependentFiles): void
{
$fileInfoCacheKey = $this->getFileInfoCacheKey($smartFileInfo);
$hash = $this->hashFile($smartFileInfo);
$this->cache->save($fileInfoCacheKey, $hash);
$this->cache->save($fileInfoCacheKey . '_files', $dependentFiles);
2020-04-01 01:55:44 +00:00
}
public function hasFileChanged(SmartFileInfo $smartFileInfo): bool
{
$currentFileHash = $this->hashFile($smartFileInfo);
$fileInfoCacheKey = $this->getFileInfoCacheKey($smartFileInfo);
$cachedValue = $this->cache->load($fileInfoCacheKey);
return $currentFileHash !== $cachedValue;
2020-04-01 01:55:44 +00:00
}
public function invalidateFile(SmartFileInfo $smartFileInfo): void
{
$fileInfoCacheKey = $this->getFileInfoCacheKey($smartFileInfo);
$this->cache->remove($fileInfoCacheKey);
2020-04-01 01:55:44 +00:00
}
public function clear(): void
{
$this->cache->clean([
Cache::ALL => true,
]);
2020-04-01 01:55:44 +00:00
}
/**
* @return SmartFileInfo[]
*/
public function getDependentFileInfos(SmartFileInfo $fileInfo): array
{
$fileInfoCacheKey = $this->getFileInfoCacheKey($fileInfo);
$cacheValue = $this->cache->load($fileInfoCacheKey . '_files');
if ($cacheValue === null) {
2020-04-01 01:55:44 +00:00
return [];
}
$dependentFileInfos = [];
$dependentFiles = $cacheValue;
2020-04-01 01:55:44 +00:00
foreach ($dependentFiles as $dependentFile) {
if (! file_exists($dependentFile)) {
continue;
}
$dependentFileInfos[] = new SmartFileInfo($dependentFile);
}
return $dependentFileInfos;
}
/**
* @api
*/
2020-07-21 11:42:17 +00:00
public function setFirstResolvedConfigFileInfo(SmartFileInfo $fileInfo): void
2020-04-01 01:55:44 +00:00
{
// the first config is core to all → if it was changed, just invalidate it
2020-07-21 11:42:17 +00:00
$configHash = $this->fileHashComputer->compute($fileInfo);
$this->storeConfigurationDataHash($fileInfo, $configHash);
2020-04-01 01:55:44 +00:00
}
private function getFileInfoCacheKey(SmartFileInfo $smartFileInfo): string
{
return sha1($smartFileInfo->getRealPath());
}
2020-04-01 01:55:44 +00:00
private function hashFile(SmartFileInfo $smartFileInfo): string
{
return (string) sha1_file($smartFileInfo->getRealPath());
2020-04-01 01:55:44 +00:00
}
2020-07-21 11:42:17 +00:00
private function storeConfigurationDataHash(SmartFileInfo $fileInfo, string $configurationHash): void
2020-04-01 01:55:44 +00:00
{
2020-07-21 11:42:17 +00:00
$key = self::CONFIGURATION_HASH_KEY . '_' . Strings::webalize($fileInfo->getRealPath());
2020-04-01 01:55:44 +00:00
$this->invalidateCacheIfConfigurationChanged($key, $configurationHash);
$this->cache->save($key, $configurationHash);
2020-04-01 01:55:44 +00:00
}
private function invalidateCacheIfConfigurationChanged(string $key, string $configurationHash): void
{
$oldCachedValue = $this->cache->load($key);
if ($oldCachedValue === $configurationHash) {
return;
2020-04-01 01:55:44 +00:00
}
// should be unique per getcwd()
$this->clear();
2020-04-01 01:55:44 +00:00
}
}