mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-30 03:47:53 +01:00
Apply FinderSanitizer to make sure all files exists and have content [closes #655]
This commit is contained in:
parent
cb651ec8fb
commit
a8ef98e2b5
@ -3,9 +3,9 @@
|
||||
namespace Rector\FileSystemRector\Contract;
|
||||
|
||||
use Rector\Contract\Rector\RectorInterface;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||
|
||||
interface FileSystemRectorInterface extends RectorInterface
|
||||
{
|
||||
public function refactor(SplFileInfo $fileInfo): void;
|
||||
public function refactor(SmartFileInfo $smartFileInfo): void;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace Rector\FileSystemRector;
|
||||
|
||||
use Rector\FileSystemRector\Contract\FileSystemRectorInterface;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||
|
||||
final class FileSystemFileProcessor
|
||||
{
|
||||
@ -28,10 +28,10 @@ final class FileSystemFileProcessor
|
||||
return $this->fileSystemRectors;
|
||||
}
|
||||
|
||||
public function processFileInfo(SplFileInfo $fileInfo): void
|
||||
public function processFileInfo(SmartFileInfo $smartFileInfo): void
|
||||
{
|
||||
foreach ($this->fileSystemRectors as $fileSystemRector) {
|
||||
$fileSystemRector->refactor($fileInfo);
|
||||
$fileSystemRector->refactor($smartFileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace Rector\YamlRector;
|
||||
|
||||
use Rector\YamlRector\Contract\YamlRectorInterface;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||
|
||||
final class YamlFileProcessor
|
||||
{
|
||||
@ -28,9 +28,9 @@ final class YamlFileProcessor
|
||||
return $this->yamlRectors;
|
||||
}
|
||||
|
||||
public function processFileInfo(SplFileInfo $splFileInfo): string
|
||||
public function processFileInfo(SmartFileInfo $smartFileInfo): string
|
||||
{
|
||||
$content = $splFileInfo->getContents();
|
||||
$content = $smartFileInfo->getContents();
|
||||
|
||||
foreach ($this->yamlRectors as $yamlRector) {
|
||||
$content = $yamlRector->refactor($content);
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
namespace Rector\Application;
|
||||
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||
|
||||
final class Error
|
||||
{
|
||||
/**
|
||||
* @var SplFileInfo
|
||||
* @var SmartFileInfo
|
||||
*/
|
||||
private $fileInfo;
|
||||
|
||||
@ -21,14 +21,14 @@ final class Error
|
||||
*/
|
||||
private $line;
|
||||
|
||||
public function __construct(SplFileInfo $fileInfo, string $message, ?int $line)
|
||||
public function __construct(SmartFileInfo $smartFileInfo, string $message, ?int $line)
|
||||
{
|
||||
$this->fileInfo = $fileInfo;
|
||||
$this->fileInfo = $smartFileInfo;
|
||||
$this->message = $message;
|
||||
$this->line = $line;
|
||||
}
|
||||
|
||||
public function getFileInfo(): SplFileInfo
|
||||
public function getFileInfo(): SmartFileInfo
|
||||
{
|
||||
return $this->fileInfo;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use Rector\NodeTraverser\RectorNodeTraverser;
|
||||
use Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator;
|
||||
use Rector\Parser\Parser;
|
||||
use Rector\Printer\FormatPerservingPrinter;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||
|
||||
final class FileProcessor
|
||||
{
|
||||
@ -51,19 +51,19 @@ final class FileProcessor
|
||||
$this->nodeScopeAndMetadataDecorator = $nodeScopeAndMetadataDecorator;
|
||||
}
|
||||
|
||||
public function processFile(SplFileInfo $fileInfo): string
|
||||
public function processFile(SmartFileInfo $smartFileInfo): string
|
||||
{
|
||||
[$newStmts, $oldStmts, $oldTokens] = $this->parseAndTraverseFileInfoToNodes($fileInfo);
|
||||
[$newStmts, $oldStmts, $oldTokens] = $this->parseAndTraverseFileInfoToNodes($smartFileInfo);
|
||||
|
||||
return $this->formatPerservingPrinter->printToFile($fileInfo, $newStmts, $oldStmts, $oldTokens);
|
||||
return $this->formatPerservingPrinter->printToFile($smartFileInfo, $newStmts, $oldStmts, $oldTokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://github.com/nikic/PHP-Parser/issues/344#issuecomment-298162516.
|
||||
*/
|
||||
public function processFileToString(SplFileInfo $fileInfo): string
|
||||
public function processFileToString(SmartFileInfo $smartFileInfo): string
|
||||
{
|
||||
[$newStmts, $oldStmts, $oldTokens] = $this->parseAndTraverseFileInfoToNodes($fileInfo);
|
||||
[$newStmts, $oldStmts, $oldTokens] = $this->parseAndTraverseFileInfoToNodes($smartFileInfo);
|
||||
|
||||
return $this->formatPerservingPrinter->printToString($newStmts, $oldStmts, $oldTokens);
|
||||
}
|
||||
@ -71,12 +71,15 @@ final class FileProcessor
|
||||
/**
|
||||
* @return Node[][]|mixed[]
|
||||
*/
|
||||
private function parseAndTraverseFileInfoToNodes(SplFileInfo $fileInfo): array
|
||||
private function parseAndTraverseFileInfoToNodes(SmartFileInfo $smartFileInfo): array
|
||||
{
|
||||
$oldStmts = $this->parser->parseFile($fileInfo->getRealPath());
|
||||
$oldStmts = $this->parser->parseFile($smartFileInfo->getRealPath());
|
||||
$oldTokens = $this->lexer->getTokens();
|
||||
|
||||
$newStmts = $this->nodeScopeAndMetadataDecorator->decorateNodesFromFile($oldStmts, $fileInfo->getRealPath());
|
||||
$newStmts = $this->nodeScopeAndMetadataDecorator->decorateNodesFromFile(
|
||||
$oldStmts,
|
||||
$smartFileInfo->getRealPath()
|
||||
);
|
||||
$newStmts = $this->rectorNodeTraverser->traverse($newStmts);
|
||||
|
||||
return [$newStmts, $oldStmts, $oldTokens];
|
||||
|
@ -22,9 +22,9 @@ use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Symplify\PackageBuilder\Console\Command\CommandNaming;
|
||||
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||
use Throwable;
|
||||
use function Safe\sprintf;
|
||||
@ -210,7 +210,7 @@ final class ProcessCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SplFileInfo[] $fileInfos
|
||||
* @param SmartFileInfo[] $fileInfos
|
||||
*/
|
||||
private function processFileInfos(array $fileInfos, bool $shouldHideAutoloadErrors): void
|
||||
{
|
||||
@ -226,7 +226,7 @@ final class ProcessCommand extends Command
|
||||
$this->consoleStyle->newLine(2);
|
||||
}
|
||||
|
||||
private function processFileInfo(SplFileInfo $fileInfo, bool $shouldHideAutoloadErrors): void
|
||||
private function processFileInfo(SmartFileInfo $fileInfo, bool $shouldHideAutoloadErrors): void
|
||||
{
|
||||
try {
|
||||
if ($fileInfo->getExtension() === 'php') {
|
||||
@ -253,7 +253,7 @@ final class ProcessCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
private function processFile(SplFileInfo $fileInfo): void
|
||||
private function processFile(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$oldContent = $fileInfo->getContents();
|
||||
|
||||
@ -273,7 +273,7 @@ final class ProcessCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
private function processYamlFile(SplFileInfo $fileInfo): void
|
||||
private function processYamlFile(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$oldContent = $fileInfo->getContents();
|
||||
|
||||
@ -295,7 +295,7 @@ final class ProcessCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
private function processFileSystemFile(SplFileInfo $fileInfo): void
|
||||
private function processFileSystemFile(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->fileSystemFileProcessor->processFileInfo($fileInfo);
|
||||
}
|
||||
|
@ -3,17 +3,18 @@
|
||||
namespace Rector\Exception\Application;
|
||||
|
||||
use Exception;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||
use Throwable;
|
||||
use function Safe\sprintf;
|
||||
|
||||
final class FileProcessingException extends Exception
|
||||
{
|
||||
public function __construct(SplFileInfo $fileInfo, Throwable $throwable)
|
||||
public function __construct(SmartFileInfo $smartFileInfo, Throwable $throwable)
|
||||
{
|
||||
$message = sprintf(
|
||||
'Processing file "%s" failed. ' . PHP_EOL . PHP_EOL . '%s',
|
||||
$fileInfo->getRealPath(),
|
||||
'Processing file "%s" failed. %s%s',
|
||||
$smartFileInfo->getRealPath(),
|
||||
PHP_EOL . PHP_EOL,
|
||||
$throwable
|
||||
);
|
||||
|
||||
|
@ -6,12 +6,13 @@ use Nette\Utils\Strings;
|
||||
use Rector\Utils\FilesystemTweaker;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Symplify\PackageBuilder\FileSystem\FinderSanitizer;
|
||||
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||
|
||||
final class FilesFinder
|
||||
{
|
||||
/**
|
||||
* @var SplFileInfo[][]
|
||||
* @var SmartFileInfo[][]
|
||||
*/
|
||||
private $fileInfosBySourceAndSuffixes = [];
|
||||
|
||||
@ -25,19 +26,28 @@ final class FilesFinder
|
||||
*/
|
||||
private $filesystemTweaker;
|
||||
|
||||
/**
|
||||
* @var FinderSanitizer
|
||||
*/
|
||||
private $finderSanitizer;
|
||||
|
||||
/**
|
||||
* @param string[] $excludePaths
|
||||
*/
|
||||
public function __construct(array $excludePaths, FilesystemTweaker $filesystemTweaker)
|
||||
{
|
||||
public function __construct(
|
||||
array $excludePaths,
|
||||
FilesystemTweaker $filesystemTweaker,
|
||||
FinderSanitizer $finderSanitizer
|
||||
) {
|
||||
$this->excludePaths = $excludePaths;
|
||||
$this->filesystemTweaker = $filesystemTweaker;
|
||||
$this->finderSanitizer = $finderSanitizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $source
|
||||
* @param string[] $suffixes
|
||||
* @return SplFileInfo[]
|
||||
* @return SmartFileInfo[]
|
||||
*/
|
||||
public function findInDirectoriesAndFiles(array $source, array $suffixes): array
|
||||
{
|
||||
@ -48,20 +58,20 @@ final class FilesFinder
|
||||
|
||||
[$files, $directories] = $this->filesystemTweaker->splitSourceToDirectoriesAndFiles($source);
|
||||
|
||||
$splFileInfos = [];
|
||||
$smartFileInfos = [];
|
||||
foreach ($files as $file) {
|
||||
$splFileInfos[] = new SmartFileInfo($file);
|
||||
$smartFileInfos[] = new SmartFileInfo($file);
|
||||
}
|
||||
|
||||
$splFileInfos = array_merge($splFileInfos, $this->findInDirectories($directories, $suffixes));
|
||||
$smartFileInfos = array_merge($smartFileInfos, $this->findInDirectories($directories, $suffixes));
|
||||
|
||||
return $this->fileInfosBySourceAndSuffixes[$cacheKey] = $splFileInfos;
|
||||
return $this->fileInfosBySourceAndSuffixes[$cacheKey] = $smartFileInfos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $directories
|
||||
* @param string[] $suffixes
|
||||
* @return SplFileInfo[]
|
||||
* @return SmartFileInfo[]
|
||||
*/
|
||||
private function findInDirectories(array $directories, array $suffixes): array
|
||||
{
|
||||
@ -85,7 +95,7 @@ final class FilesFinder
|
||||
|
||||
$this->addFilterWithExcludedPaths($finder);
|
||||
|
||||
return iterator_to_array($finder->getIterator());
|
||||
return $this->finderSanitizer->sanitize($finder);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
namespace Rector\Printer;
|
||||
|
||||
use Nette\Utils\FileSystem;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\PrettyPrinter\Standard;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use function Safe\file_put_contents;
|
||||
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||
|
||||
final class FormatPerservingPrinter
|
||||
{
|
||||
@ -24,11 +24,11 @@ final class FormatPerservingPrinter
|
||||
* @param Node[] $oldStmts
|
||||
* @param Node[] $oldTokens
|
||||
*/
|
||||
public function printToFile(SplFileInfo $fileInfo, array $newStmts, array $oldStmts, array $oldTokens): string
|
||||
public function printToFile(SmartFileInfo $fileInfo, array $newStmts, array $oldStmts, array $oldTokens): string
|
||||
{
|
||||
$newContent = $this->printToString($newStmts, $oldStmts, $oldTokens);
|
||||
|
||||
file_put_contents($fileInfo->getRealPath(), $newContent);
|
||||
FileSystem::write($fileInfo->getRealPath(), $newContent);
|
||||
|
||||
return $newContent;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
use Rector\Utils\BetterNodeFinder;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||
|
||||
final class MultipleClassFileToPsr4ClassesRector implements FileSystemRectorInterface
|
||||
{
|
||||
@ -112,17 +112,20 @@ CODE_SAMPLE
|
||||
);
|
||||
}
|
||||
|
||||
public function refactor(SplFileInfo $fileInfo): void
|
||||
public function refactor(SmartFileInfo $smartFileInfo): void
|
||||
{
|
||||
$oldStmts = $this->parser->parseFile($fileInfo->getRealPath());
|
||||
$oldStmts = $this->parser->parseFile($smartFileInfo->getRealPath());
|
||||
|
||||
// needed for format preserving
|
||||
$newStmts = $this->nodeScopeAndMetadataDecorator->decorateNodesFromFile($oldStmts, $fileInfo->getRealPath());
|
||||
$newStmts = $this->nodeScopeAndMetadataDecorator->decorateNodesFromFile(
|
||||
$oldStmts,
|
||||
$smartFileInfo->getRealPath()
|
||||
);
|
||||
|
||||
/** @var Namespace_[] $namespaceNodes */
|
||||
$namespaceNodes = $this->betterNodeFinder->findInstanceOf($newStmts, Namespace_::class);
|
||||
|
||||
if ($this->shouldSkip($fileInfo, $newStmts, $namespaceNodes)) {
|
||||
if ($this->shouldSkip($smartFileInfo, $newStmts, $namespaceNodes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -144,7 +147,7 @@ CODE_SAMPLE
|
||||
// reindex from 0, for the printer
|
||||
$newStmt->stmts = array_values($newStmt->stmts);
|
||||
|
||||
$fileDestination = $this->createClassFileDestination($classNode, $fileInfo);
|
||||
$fileDestination = $this->createClassFileDestination($classNode, $smartFileInfo);
|
||||
|
||||
$fileContent = $this->formatPerservingPrinter->printToString(
|
||||
$newStmtsSet,
|
||||
@ -158,9 +161,9 @@ CODE_SAMPLE
|
||||
}
|
||||
}
|
||||
|
||||
private function createClassFileDestination(Class_ $classNode, SplFileInfo $fileInfo): string
|
||||
private function createClassFileDestination(Class_ $classNode, SmartFileInfo $smartFileInfo): string
|
||||
{
|
||||
$currentDirectory = dirname($fileInfo->getRealPath());
|
||||
$currentDirectory = dirname($smartFileInfo->getRealPath());
|
||||
|
||||
return $currentDirectory . DIRECTORY_SEPARATOR . (string) $classNode->name . '.php';
|
||||
}
|
||||
@ -194,7 +197,7 @@ CODE_SAMPLE
|
||||
* @param Node[] $nodes
|
||||
* @param Namespace_[] $namespaceNodes
|
||||
*/
|
||||
private function shouldSkip(SplFileInfo $fileInfo, array $nodes, array $namespaceNodes): bool
|
||||
private function shouldSkip(SmartFileInfo $smartFileInfo, array $nodes, array $namespaceNodes): bool
|
||||
{
|
||||
// process only namespaced file
|
||||
if (! $namespaceNodes) {
|
||||
@ -215,7 +218,7 @@ CODE_SAMPLE
|
||||
|
||||
if (count($nonAnonymousClassNodes) === 1) {
|
||||
$nonAnonymousClassNode = $nonAnonymousClassNodes[0];
|
||||
if ((string) $nonAnonymousClassNode->name === $fileInfo->getFilename()) {
|
||||
if ((string) $nonAnonymousClassNode->name === $smartFileInfo->getFilename()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ services:
|
||||
alias: Symfony\Component\Console\Output\ConsoleOutput
|
||||
|
||||
Symplify\PackageBuilder\FileSystem\FileSystem: ~
|
||||
Symplify\PackageBuilder\FileSystem\FinderSanitizer: ~
|
||||
|
||||
# parameters
|
||||
Symplify\PackageBuilder\Parameter\ParameterProvider: ~
|
||||
|
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
echo 'Hi';
|
@ -0,0 +1 @@
|
||||
key: value
|
@ -0,0 +1 @@
|
||||
key: value
|
@ -5,7 +5,7 @@ namespace Rector\Tests\FileSystem\FilesFinder;
|
||||
use Iterator;
|
||||
use Rector\FileSystem\FilesFinder;
|
||||
use Rector\Tests\AbstractContainerAwareTestCase;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||
use function Safe\sort;
|
||||
|
||||
final class FilesFinderTest extends AbstractContainerAwareTestCase
|
||||
@ -28,7 +28,7 @@ final class FilesFinderTest extends AbstractContainerAwareTestCase
|
||||
$foundFiles = $this->filesFinder->findInDirectoriesAndFiles([__DIR__ . '/FilesFinderSource'], [$suffix]);
|
||||
$this->assertCount($count, $foundFiles);
|
||||
|
||||
/** @var SplFileInfo $foundFile */
|
||||
/** @var SmartFileInfo $foundFile */
|
||||
$foundFile = array_pop($foundFiles);
|
||||
$this->assertSame($expectedFileName, $foundFile->getBasename());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user