저자: Fabien Potencier (fabien@symfony.com)
 /**
  * Resolves risky allowed flag.
  */
 private function resolveRiskyAllowed()
 {
     if (null !== $this->options['allow-risky']) {
         $this->allowRisky = 'yes' === $this->options['allow-risky'];
         return;
     }
     $this->allowRisky = $this->config->getRiskyAllowed();
 }
예제 #2
0
 /**
  * Returns fixers.
  *
  * @return FixerInterface[] An array of FixerInterface
  */
 public function getFixers()
 {
     if (null === $this->fixers) {
         $fixerFactory = new FixerFactory();
         $fixerFactory->registerBuiltInFixers();
         $fixerFactory->registerCustomFixers($this->getConfig()->getCustomFixers());
         $this->fixers = $fixerFactory->useRuleSet($this->getRuleSet())->setWhitespacesConfig(new WhitespacesFixerConfig($this->config->getIndent(), $this->config->getLineEnding()))->getFixers();
         if (false === $this->getRiskyAllowed()) {
             $riskyFixers = array_map(function (FixerInterface $fixer) {
                 return $fixer->getName();
             }, array_filter($this->fixers, function (FixerInterface $fixer) {
                 return $fixer->isRisky();
             }));
             if (count($riskyFixers)) {
                 throw new InvalidConfigurationException(sprintf('The rules contain risky fixers (%s), but they are not allowed to run. Perhaps you forget to use --allow-risky option?', implode(', ', $riskyFixers)));
             }
         }
     }
     return $this->fixers;
 }
예제 #3
0
 private function fixFile(\SplFileInfo $file, LintingResultInterface $lintingResult)
 {
     $name = $this->getFileRelativePathname($file);
     try {
         $lintingResult->check();
     } catch (LintingException $e) {
         $this->dispatchEvent(FixerFileProcessedEvent::NAME, FixerFileProcessedEvent::create()->setStatus(FixerFileProcessedEvent::STATUS_INVALID));
         $this->errorsManager->report(new Error(Error::TYPE_INVALID, $name));
         return;
     }
     $fixers = $this->config->getFixers();
     $old = file_get_contents($file->getRealPath());
     $tokens = Tokens::fromCode($old);
     $oldHash = $tokens->getCodeHash();
     $newHash = $oldHash;
     $new = $old;
     $appliedFixers = array();
     try {
         foreach ($fixers as $fixer) {
             if (!$fixer->supports($file) || !$fixer->isCandidate($tokens)) {
                 continue;
             }
             $fixer->fix($file, $tokens);
             if ($tokens->isChanged()) {
                 $tokens->clearEmptyTokens();
                 $tokens->clearChanged();
                 $appliedFixers[] = $fixer->getName();
             }
         }
     } catch (\Exception $e) {
         $this->processException($name);
         return;
     } catch (\ParseError $e) {
         $this->dispatchEvent(FixerFileProcessedEvent::NAME, FixerFileProcessedEvent::create()->setStatus(FixerFileProcessedEvent::STATUS_LINT));
         $this->errorsManager->report(new Error(Error::TYPE_LINT, $name));
         return;
     } catch (\Throwable $e) {
         $this->processException($name);
         return;
     }
     $fixInfo = null;
     if (!empty($appliedFixers)) {
         $new = $tokens->generateCode();
         $newHash = $tokens->getCodeHash();
     }
     // We need to check if content was changed and then applied changes.
     // But we can't simple check $appliedFixers, because one fixer may revert
     // work of other and both of them will mark collection as changed.
     // Therefore we need to check if code hashes changed.
     if ($oldHash !== $newHash) {
         try {
             $this->linter->lintSource($new)->check();
         } catch (LintingException $e) {
             $this->dispatchEvent(FixerFileProcessedEvent::NAME, FixerFileProcessedEvent::create()->setStatus(FixerFileProcessedEvent::STATUS_LINT));
             $this->errorsManager->report(new Error(Error::TYPE_LINT, $name));
             return;
         }
         if (!$this->isDryRun) {
             if (false === @file_put_contents($file->getRealPath(), $new)) {
                 $error = error_get_last();
                 if (null !== $error) {
                     throw new IOException(sprintf('Failed to write file "%s", "%s".', $file->getRealPath(), $error['message']), 0, null, $file->getRealPath());
                 }
                 throw new IOException(sprintf('Failed to write file "%s".', $file->getRealPath()), 0, null, $file->getRealPath());
             }
         }
         $fixInfo = array('appliedFixers' => $appliedFixers, 'diff' => $this->differ->diff($old, $new));
     }
     $this->cacheManager->setFile($name, $new);
     $this->dispatchEvent(FixerFileProcessedEvent::NAME, FixerFileProcessedEvent::create()->setStatus($fixInfo ? FixerFileProcessedEvent::STATUS_FIXED : FixerFileProcessedEvent::STATUS_NO_CHANGES));
     return $fixInfo;
 }
예제 #4
0
 /**
  * Fixes all files for the given finder.
  *
  * @param ConfigInterface $config A ConfigInterface instance
  * @param bool            $dryRun Whether to simulate the changes or not
  * @param bool            $diff   Whether to provide diff
  *
  * @return array
  */
 public function fix(ConfigInterface $config, $dryRun = false, $diff = false)
 {
     $changed = array();
     $fixers = $config->getFixers();
     $this->stopwatch->openSection();
     $fileCacheManager = new FileCacheManager($config->usingCache(), $config->getCacheFile(), $config->getRules());
     foreach ($config->getFinder() as $file) {
         if ($file->isDir() || $file->isLink()) {
             continue;
         }
         $name = $this->getFileRelativePathname($file);
         $this->stopwatch->start($name);
         if ($fixInfo = $this->fixFile($file, $fixers, $dryRun, $diff, $fileCacheManager)) {
             $changed[$name] = $fixInfo;
         }
         $this->stopwatch->stop($name);
     }
     $this->stopwatch->stopSection('fixFile');
     return $changed;
 }
예제 #5
0
 /**
  * Fixes all files for the given finder.
  *
  * @param ConfigInterface $config A ConfigInterface instance
  * @param bool            $dryRun Whether to simulate the changes or not
  * @param bool            $diff   Whether to provide diff
  *
  * @return array
  */
 public function fix(ConfigInterface $config, $dryRun = false, $diff = false)
 {
     $changed = array();
     $fixers = $config->getFixers();
     $this->stopwatch->openSection();
     $fileCacheManager = new FileCacheManager($config->usingCache(), $config->getCacheFile(), $config->getRules());
     $finder = $config->getFinder();
     $finderIterator = $finder instanceof \IteratorAggregate ? $finder->getIterator() : $finder;
     foreach (new UniqueFileIterator($finderIterator) as $file) {
         $name = $this->getFileRelativePathname($file);
         $this->stopwatch->start($name);
         if ($fixInfo = $this->fixFile($file, $fixers, $dryRun, $diff, $fileCacheManager)) {
             $changed[$name] = $fixInfo;
         }
         $this->stopwatch->stop($name);
     }
     $this->stopwatch->stopSection('fixFile');
     return $changed;
 }