Skip to content

Commit

Permalink
Add path resolver to init command, to add konw project paths on generate
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Nov 11, 2022
1 parent f002a2f commit e56cb92
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 18 deletions.
3 changes: 3 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -817,3 +817,6 @@ parameters:
-
message: '#Cognitive complexity for "Rector\\Core\\Rector\\AbstractRector\:\:enterNode\(\)" is 11, keep it under 10#'
path: src/Rector/AbstractRector.php

# not relevant anymore
- '#Instead of "Symfony\\Component\\Finder\\SplFileInfo" class/interface use "Symplify\\SmartFileSystem\\SmartFileInfo"#'
61 changes: 43 additions & 18 deletions src/Console/Command/InitCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Nette\Utils\FileSystem;
use Nette\Utils\Strings;
use Rector\Core\Contract\Console\OutputStyleInterface;
use Rector\Core\FileSystem\InitFilePathsResolver;
use Rector\Core\Php\PhpVersionProvider;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
Expand All @@ -23,41 +24,65 @@ public function __construct(
private readonly \Symfony\Component\Filesystem\Filesystem $filesystem,
private readonly OutputStyleInterface $rectorOutputStyle,
private readonly PhpVersionProvider $phpVersionProvider,
private readonly InitFilePathsResolver $initFilePathsResolver,
) {
parent::__construct();
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$projectDirectory = getcwd();
$rectorRootFilePath = $projectDirectory . '/rector.php';

$doesFileExist = $this->filesystem->exists($rectorRootFilePath);
if ($doesFileExist) {
$this->rectorOutputStyle->note('Config file "rector.php" already exists');
} else {
$rectorPhpTemplateContents = FileSystem::read(self::TEMPLATE_PATH);

$rectorPhpTemplateContents = $this->replacePhpLevelContents($rectorPhpTemplateContents);
$rectorPhpTemplateContents = $this->replacePathsContents($rectorPhpTemplateContents, $projectDirectory);

$this->filesystem->dumpFile($rectorRootFilePath, $rectorPhpTemplateContents);
$this->rectorOutputStyle->success('"rector.php" config file was added');
}

return Command::SUCCESS;
}

protected function configure(): void
{
$this->setName('init');

$this->setDescription('Generate rector.php configuration file');
}

protected function execute(InputInterface $input, OutputInterface $output): int
private function replacePhpLevelContents(string $rectorPhpTemplateContents): string
{
$rectorRootFilePath = getcwd() . '/rector.php';
$fullPHPVersion = (string) $this->phpVersionProvider->provide();
$phpVersion = Strings::substring($fullPHPVersion, 0, 1) . Strings::substring($fullPHPVersion, 2, 1);

$doesFileExist = $this->filesystem->exists($rectorRootFilePath);
if ($doesFileExist) {
$this->rectorOutputStyle->warning('Config file "rector.php" already exists');
} else {
$this->filesystem->copy(self::TEMPLATE_PATH, $rectorRootFilePath);
return str_replace(
'LevelSetList::UP_TO_PHP_XY',
'LevelSetList::UP_TO_PHP_' . $phpVersion,
$rectorPhpTemplateContents
);
}

$fullPHPVersion = (string) $this->phpVersionProvider->provide();
$phpVersion = Strings::substring($fullPHPVersion, 0, 1) . Strings::substring($fullPHPVersion, 2, 1);
private function replacePathsContents(string $rectorPhpTemplateContents, string $projectDirectory): string
{
$projectPhpDirectories = $this->initFilePathsResolver->resolve($projectDirectory);

$fileContent = FileSystem::read($rectorRootFilePath);
$fileContent = str_replace(
'LevelSetList::UP_TO_PHP_XY',
'LevelSetList::UP_TO_PHP_' . $phpVersion,
$fileContent
);
$this->filesystem->dumpFile($rectorRootFilePath, $fileContent);
// fallback to default 'src' in case of empty one
if ($projectPhpDirectories === []) {
$projectPhpDirectories[] = 'src';
}

$this->rectorOutputStyle->success('"rector.php" config file was added');
$projectPhpDirectoriesContents = '';
foreach ($projectPhpDirectories as $projectPhpDirectory) {
$projectPhpDirectoriesContents .= ' __DIR__ . \'/' . $projectPhpDirectory . '\',' . PHP_EOL;
}

return Command::SUCCESS;
return str_replace('__PATHS__', $projectPhpDirectoriesContents, $rectorPhpTemplateContents);
}
}
54 changes: 54 additions & 0 deletions src/FileSystem/InitFilePathsResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace Rector\Core\FileSystem;

use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;

/**
* @see \Rector\Core\Tests\FileSystem\InitFilePathsResolver\InitFilePathsResolverTest
*/
final class InitFilePathsResolver
{
/**
* @return string[]
*/
public function resolve(string $projectDirectory): array
{
$rootDirectoryFinder = Finder::create()
->directories()
->depth(0)
// system files
->notPath('#(vendor|var|stubs|temp|templates|tmp|e2e|bin|build)#')
->in($projectDirectory)
->sortByName();

/** @var SplFileInfo[] $rootDirectoryFileInfos */
$rootDirectoryFileInfos = iterator_to_array($rootDirectoryFinder);

$projectDirectories = [];

foreach ($rootDirectoryFileInfos as $rootDirectoryFileInfo) {
if (! $this->hasDirectoryFileInfoPhpFiles($rootDirectoryFileInfo)) {
continue;
}

$projectDirectories[] = $rootDirectoryFileInfo->getRelativePathname();
}

return $projectDirectories;
}

private function hasDirectoryFileInfoPhpFiles(SplFileInfo $rootDirectoryFileInfo): bool
{
// is directory with PHP files?
$phpFilesFinder = Finder::create()
->files()
->in($rootDirectoryFileInfo->getPathname())
->name('*.php');

return count($phpFilesFinder) !== 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
some: value
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

echo 'hi';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

echo 'hi';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

echo 'this is a trap';
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Rector\Core\Tests\FileSystem\InitFilePathsResolver;

use PHPUnit\Framework\TestCase;
use Rector\Core\FileSystem\InitFilePathsResolver;

final class InitFilePathsResolverTest extends TestCase
{
private InitFilePathsResolver $initFilePathsResolver;

protected function setUp(): void
{
$this->initFilePathsResolver = new InitFilePathsResolver();
}

public function test(): void
{
$phpDirectoryPaths = $this->initFilePathsResolver->resolve(__DIR__ . '/Fixture/first-project');

$this->assertSame(['src', 'tests'], $phpDirectoryPaths);
}
}

0 comments on commit e56cb92

Please sign in to comment.