Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions src/Caching/Detector/ChangedFilesDetector.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Rector\Caching\Config\FileHashComputer;
use Rector\Caching\Enum\CacheKey;
use Rector\Configuration\Parameter\SimpleParameterProvider;
use Rector\FileSystem\FilePathHelper;
use Rector\Util\FileHasher;

/**
Expand All @@ -28,7 +29,8 @@ final class ChangedFilesDetector
public function __construct(
private readonly FileHashComputer $fileHashComputer,
private readonly Cache $cache,
private readonly FileHasher $fileHasher
private readonly FileHasher $fileHasher,
private readonly FilePathHelper $filePathHelper
) {
}

Expand Down Expand Up @@ -70,7 +72,7 @@ public function hasFileChanged(string $filePath): bool
// a scoped (--only) run reuses the full-run cache: a file left clean by all rules stays
// clean under a single rule too, and the content is still compared below
if ($cachedValue === null && $this->scopeSuffix !== '') {
$unscopedCacheKey = $this->fileHasher->hash($this->resolvePath($filePath));
$unscopedCacheKey = $this->fileHasher->hash($this->cacheKeyPath($filePath));
$cachedValue = $this->cache->load($unscopedCacheKey, CacheKey::FILE_HASH_KEY);
}

Expand Down Expand Up @@ -117,7 +119,20 @@ private function resolvePath(string $filePath): string

private function getFilePathCacheKey(string $filePath): string
{
return $this->fileHasher->hash($this->resolvePath($filePath) . $this->scopeSuffix);
return $this->fileHasher->hash($this->cacheKeyPath($filePath) . $this->scopeSuffix);
}

/**
* The path a cache key is built from: relative to the project, never absolute.
*
* An absolute path ties the whole cache to one location on disk, so the same project
* checked out twice - a git worktree, a CI checkout, a container mount - shares nothing.
* Relative keys let a cache travel with the project. Paths outside the project keep
* their `../` prefix and stay just as stable, because the anchor does not move either.
*/
private function cacheKeyPath(string $filePath): string
{
return $this->filePathHelper->relativePath($this->resolvePath($filePath));
}

private function hashFile(string $filePath): string
Expand Down
Loading