123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- <?php
- /*
- * This file is part of the PHP CS utility.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
- namespace Symfony\CS;
- use Symfony\Component\Filesystem\Exception\IOException;
- /**
- * Class supports caching information about state of fixing files.
- *
- * Cache is supported only for phar version and version installed via composer.
- *
- * File will be processed by PHP CS Fixer only if any of the following conditions is fulfilled:
- * - cache is not available,
- * - fixer version changed,
- * - fixers list is changed,
- * - file is new,
- * - file changed.
- *
- * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
- */
- class FileCacheManager
- {
- const CACHE_FILE = '.php_cs.cache';
- private $dir;
- private $isEnabled;
- private $fixers;
- private $newHashes = array();
- private $oldHashes = array();
- public function __construct($isEnabled, $dir, array $fixers)
- {
- $this->isEnabled = $isEnabled;
- $this->dir = null !== $dir ? $dir.DIRECTORY_SEPARATOR : '';
- $this->fixers = array_map(function (FixerInterface $f) {
- return $f->getName();
- }, $fixers);
- sort($this->fixers);
- $this->readFromFile();
- }
- public function __destruct()
- {
- $this->saveToFile();
- }
- public function needFixing($file, $fileContent)
- {
- if (!$this->isCacheAvailable()) {
- return true;
- }
- if (!isset($this->oldHashes[$file])) {
- return true;
- }
- if ($this->oldHashes[$file] !== $this->calcHash($fileContent)) {
- return true;
- }
- // file do not change - keep hash in new collection
- $this->newHashes[$file] = $this->oldHashes[$file];
- return false;
- }
- public function setFile($file, $fileContent)
- {
- if (!$this->isCacheAvailable()) {
- return;
- }
- $this->newHashes[$file] = $this->calcHash($fileContent);
- }
- private function calcHash($content)
- {
- return crc32($content);
- }
- private function isCacheAvailable()
- {
- static $result;
- if (null === $result) {
- $result = $this->isEnabled && (ToolInfo::isInstalledAsPhar() || ToolInfo::isInstalledByComposer());
- }
- return $result;
- }
- private function isCacheStale($cacheVersion, $fixers)
- {
- if (!$this->isCacheAvailable()) {
- return true;
- }
- return ToolInfo::getVersion() !== $cacheVersion || $this->fixers !== $fixers;
- }
- private function readFromFile()
- {
- if (!$this->isCacheAvailable()) {
- return;
- }
- if (!file_exists($this->dir.self::CACHE_FILE)) {
- return;
- }
- $content = file_get_contents($this->dir.self::CACHE_FILE);
- $data = unserialize($content);
- // BC for old cache without fixers list
- if (!isset($data['fixers'])) {
- $data['fixers'] = null;
- }
- // Set hashes only if the cache is fresh, otherwise we need to parse all files
- if (!$this->isCacheStale($data['version'], $data['fixers'])) {
- $this->oldHashes = $data['hashes'];
- }
- }
- private function saveToFile()
- {
- if (!$this->isCacheAvailable()) {
- return;
- }
- $data = serialize(
- array(
- 'version' => ToolInfo::getVersion(),
- 'fixers' => $this->fixers,
- 'hashes' => $this->newHashes,
- )
- );
- if (false === @file_put_contents($this->dir.self::CACHE_FILE, $data, LOCK_EX)) {
- throw new IOException(sprintf('Failed to write file "%s".', $this->cacheFile), 0, null, $this->cacheFile);
- }
- }
- }
|