mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-17 21:38:22 +01:00
[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:
parent
e627304df9
commit
f672eace0e
2
.github/workflows/code_analysis_no_dev.yaml
vendored
2
.github/workflows/code_analysis_no_dev.yaml
vendored
@ -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 }}
|
||||
|
@ -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
|
||||
|
41
packages/rector-generator/src/Command/InitRecipeCommand.php
Normal file
41
packages/rector-generator/src/Command/InitRecipeCommand.php
Normal 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;
|
||||
}
|
||||
}
|
54
packages/rector-generator/src/TemplateInitializer.php
Normal file
54
packages/rector-generator/src/TemplateInitializer.php
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user