[DX] Add init-recipe command to create recipe config in root (#4789)

* [DX] Add init-recipe command to initlaize recipe

* update docs
This commit is contained in:
Tomas Votruba 2020-12-05 14:20:13 +01:00 committed by GitHub
parent e627304df9
commit f672eace0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 119 additions and 27 deletions

View File

@ -12,7 +12,7 @@ jobs:
-
name: 'Rector Recipe'
run: |
cp rector-recipe.php.dist rector-recipe.php
bin/rector init-recipe --ansi
bin/rector generate --ansi
name: ${{ matrix.actions.name }}

View File

@ -11,8 +11,14 @@ Don't worry, also generates a test case, which is required to contribute.
## How to Generate Rector rule in 3 steps?
1. Copy [`rector-recipe.php.dist`](/rector-recipe.php.dist) to `rector-recipe.php`
2. Change parameters in `rector-recipe.php` to meet you need
1. Initialize `rector-recipe.php` config
```bash
vendor/bin/rector init-recipe
```
2. Complete parameters in `rector-recipe.php` to design your new rule
3. Run command
```bash

View File

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace Rector\RectorGenerator\Command;
use Rector\RectorGenerator\TemplateInitializer;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symplify\PackageBuilder\Console\ShellCode;
final class InitRecipeCommand extends Command
{
/**
* @var TemplateInitializer
*/
private $templateInitializer;
public function __construct(TemplateInitializer $templateInitializer)
{
parent::__construct();
$this->templateInitializer = $templateInitializer;
}
protected function configure(): void
{
$this->setDescription('[DEV] Initialize "rector-recipe.php" config');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->templateInitializer->initialize(
__DIR__ . '/../../../../templates/rector-recipe.php.dist',
'rector-recipe.php'
);
return ShellCode::SUCCESS;
}
}

View File

@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace Rector\RectorGenerator;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symplify\SmartFileSystem\FileSystemGuard;
use Symplify\SmartFileSystem\SmartFileSystem;
final class TemplateInitializer
{
/**
* @var SymfonyStyle
*/
private $symfonyStyle;
/**
* @var SmartFileSystem
*/
private $smartFileSystem;
/**
* @var FileSystemGuard
*/
private $fileSystemGuard;
public function __construct(
SymfonyStyle $symfonyStyle,
SmartFileSystem $smartFileSystem,
FileSystemGuard $fileSystemGuard
) {
$this->symfonyStyle = $symfonyStyle;
$this->smartFileSystem = $smartFileSystem;
$this->fileSystemGuard = $fileSystemGuard;
}
public function initialize(string $templateFilePath, string $rootFileName): void
{
$this->fileSystemGuard->ensureFileExists($templateFilePath, __METHOD__);
$targetFilePath = getcwd() . '/' . $rootFileName;
$doesFileExist = $this->smartFileSystem->exists($targetFilePath);
if ($doesFileExist) {
$message = sprintf('Config file "%s" already exists', $rootFileName);
$this->symfonyStyle->warning($message);
} else {
$this->smartFileSystem->copy($templateFilePath, $targetFilePath);
$message = sprintf('"%s" config file was added', $rootFileName);
$this->symfonyStyle->success($message);
}
}
}

View File

@ -12,7 +12,6 @@ use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name;
use PhpParser\Node\Param;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

View File

@ -4,30 +4,23 @@ declare(strict_types=1);
namespace Rector\Core\Console\Command;
use Rector\RectorGenerator\TemplateInitializer;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symplify\PackageBuilder\Console\ShellCode;
use Symplify\SmartFileSystem\SmartFileSystem;
final class InitCommand extends AbstractCommand
{
/**
* @var SmartFileSystem
* @var TemplateInitializer
*/
private $smartFileSystem;
private $templateInitializer;
/**
* @var SymfonyStyle
*/
private $symfonyStyle;
public function __construct(SmartFileSystem $smartFileSystem, SymfonyStyle $symfonyStyle)
public function __construct(TemplateInitializer $templateInitializer)
{
parent::__construct();
$this->smartFileSystem = $smartFileSystem;
$this->symfonyStyle = $symfonyStyle;
$this->templateInitializer = $templateInitializer;
}
protected function configure(): void
@ -37,14 +30,7 @@ final class InitCommand extends AbstractCommand
protected function execute(InputInterface $input, OutputInterface $output): int
{
$rectorConfigFiles = $this->smartFileSystem->exists(getcwd() . '/rector.php');
if (! $rectorConfigFiles) {
$this->smartFileSystem->copy(__DIR__ . '/../../../templates/rector.php.dist', getcwd() . '/rector.php');
$this->symfonyStyle->success('"rector.php" config file has been generated successfully!');
} else {
$this->symfonyStyle->error('Config file not generated. A "rector.php" configuration file already exists');
}
$this->templateInitializer->initialize(__DIR__ . '/../../../templates/rector.php.dist', 'rector.php');
return ShellCode::SUCCESS;
}

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
namespace Rector\RuleDocGenerator\Category;
@ -14,16 +15,21 @@ final class RectorCategoryInferer implements CategoryInfererInterface
* @see https://regex101.com/r/wyW01F/1
* @var string
*/
private const RECTOR_CATEGORY_REGEX = '#Rector\\\\(?<category>\w+)\\\\#';
private const RECTOR_CATEGORY_REGEX = '#Rector\\\\(?<' . self::CATEGORY . '>\w+)\\\\#';
/**
* @var string
*/
private const CATEGORY = 'category';
public function infer(RuleDefinition $ruleDefinition): ?string
{
$matches = Strings::match($ruleDefinition->getRuleClass(), self::RECTOR_CATEGORY_REGEX);
if (! isset($matches['category'])) {
if (! isset($matches[self::CATEGORY])) {
$message = sprintf('Category for "%s" could not be resolved', $ruleDefinition->getRuleClass());
throw new ShouldNotHappenException($message);
}
return $matches['category'];
return $matches[self::CATEGORY];
}
}