diff --git a/README.md b/README.md
index ca0a931..ed61242 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ You can install the package using [Composer](https://getcomposer.org):
```bash
composer require dragon-code/codestyler --dev
-composer config scripts.style "vendor/bin/pint --parallel"
+composer config scripts.style "vendor/bin/rector && vendor/bin/pint --parallel"
```
It is also possible to establish dependence in the global area of visibility:
@@ -44,6 +44,7 @@ and `biome.json` file for [Biome Linter](https://biomejs.dev):
"scripts": {
"post-update-cmd": [
"vendor/bin/codestyle pint 8.4",
+ "vendor/bin/codestyle rector laravel",
"vendor/bin/codestyle editorconfig",
"vendor/bin/codestyle npm",
"composer normalize"
@@ -59,6 +60,7 @@ When using a globally established dependence, the call must be replaced with the
"scripts": {
"post-update-cmd": [
"codestyle pint 8.4",
+ "codestyle rector laravel",
"codestyle editorconfig",
"codestyle npm",
"composer normalize"
@@ -100,6 +102,35 @@ The linter is invoked by a console command:
composer style
```
+### Rector
+
+[`Rector`](https://getrector.com) is uses as the code rector for PHP.
+
+The Rector is invoked by a console command:
+
+```bash
+composer style
+```
+
+To do this, make sure the file is in the root of the project.
+You can also automate this process by adding a call to the file copy function in the `scripts.post-update-cmd`
+section of the `composer.json` file.
+
+```JSON
+{
+ "scripts": {
+ "post-update-cmd": [
+ "vendor/bin/codestyle rector laravel"
+ ]
+ }
+}
+```
+
+Available presets:
+
+- `laravel`
+- `default`
+
### Node Linter
[Biome](https://biomejs.dev) is used as the linter for JS, CSS and JSON.
@@ -183,11 +214,15 @@ After completing all the steps, the `composer.json` file will have the following
"scripts": {
"post-update-cmd": [
"vendor/bin/codestyle pint 8.4",
+ "vendor/bin/codestyle rector laravel",
"vendor/bin/codestyle editorconfig",
"vendor/bin/codestyle npm",
"composer normalize"
],
- "style": "vendor/bin/pint --parallel"
+ "style": [
+ "vendor/bin/pint --parallel",
+ "vendor/bin/rector"
+ ]
}
}
```
diff --git a/bin/codestyle b/bin/codestyle
index 20c1d92..c043f04 100644
--- a/bin/codestyle
+++ b/bin/codestyle
@@ -6,6 +6,7 @@ declare(strict_types=1);
use DragonCode\Codestyler\Console\EditorConfigCommand;
use DragonCode\Codestyler\Console\NpmCommand;
use DragonCode\Codestyler\Console\PintCommand;
+use DragonCode\Codestyler\Console\RectorCommand;
use Symfony\Component\Console\Application;
if (PHP_SAPI !== 'cli' || (PHP_MAJOR_VERSION < 8 && PHP_MINOR_VERSION < 2)) {
@@ -44,6 +45,7 @@ $application = new Application('The Dragon Code: Styler', '6.x');
$application->add(new EditorConfigCommand);
$application->add(new PintCommand);
+$application->add(new RectorCommand);
$application->add(new NpmCommand);
$application->run();
diff --git a/composer.json b/composer.json
index a250d1a..d02def9 100644
--- a/composer.json
+++ b/composer.json
@@ -43,6 +43,7 @@
"require": {
"php": "^8.2",
"ext-json": "*",
+ "driftingly/rector-laravel": "^2.1",
"ergebnis/composer-normalize": "^2.48",
"laravel/pint": "^1.24",
"symfony/console": "^7.3"
@@ -74,6 +75,9 @@
"php bin/codestyle pint 8.2",
"composer normalize"
],
- "style": "vendor/bin/pint ./bin/codestyle ./src/ ./tests"
+ "style": [
+ "vendor/bin/rector",
+ "vendor/bin/pint ./bin/codestyle ./src/ ./tests"
+ ]
}
}
diff --git a/presets/rector/default.php b/presets/rector/default.php
new file mode 100644
index 0000000..3a5af63
--- /dev/null
+++ b/presets/rector/default.php
@@ -0,0 +1,44 @@
+ array_filter($paths, fn (string $path): bool => realpath($path) !== false);
+
+return RectorConfig::configure()
+ ->withPaths(
+ $paths([
+ 'app',
+ 'config',
+ 'database',
+ 'public/index.php',
+ 'resources',
+ 'src',
+ 'tests',
+ ])
+ )
+ ->withFileExtensions(['php'])
+ ->withParallel()
+ ->withPreparedSets(
+ deadCode : true,
+ typeDeclarations: true,
+ )
+ ->withPhpSets()
+ ->withImportNames(
+ removeUnusedImports: true,
+ )
+ ->withComposerBased(
+ phpunit: true
+ )
+ ->withAttributesSets(
+ phpunit: true,
+ )
+ ->withConfiguredRule(RemoveDumpDataDeadCodeRector::class, [
+ 'dd',
+ 'dump',
+ 'var_dump',
+ 'print_r',
+ 'echo',
+ ]);
diff --git a/presets/rector/laravel.php b/presets/rector/laravel.php
new file mode 100644
index 0000000..8b1c3ed
--- /dev/null
+++ b/presets/rector/laravel.php
@@ -0,0 +1,77 @@
+ array_filter($paths, fn (string $path): bool => realpath($path) !== false);
+
+return RectorConfig::configure()
+ ->withPaths(
+ $paths([
+ 'app',
+ 'bin',
+ 'bootstrap',
+ 'config',
+ 'database',
+ 'lang',
+ 'operations',
+ 'public/index.php',
+ 'resources',
+ 'routes',
+ 'src',
+ 'tests',
+ ])
+ )
+ ->withSkip(
+ $paths(['bootstrap/cache'])
+ )
+ ->withFileExtensions(['php'])
+ ->withParallel()
+ ->withPreparedSets(
+ deadCode : true,
+ typeDeclarations: true,
+ )
+ ->withPhpSets()
+ ->withSetProviders(LaravelSetProvider::class)
+ ->withImportNames(
+ removeUnusedImports: true,
+ )
+ ->withComposerBased(
+ phpunit: true,
+ laravel: true
+ )
+ ->withAttributesSets(
+ phpunit: true,
+ )
+ ->withSets([
+ LaravelSetList::LARAVEL_COLLECTION,
+ LaravelSetList::LARAVEL_FACADE_ALIASES_TO_FULL_NAMES,
+ LaravelSetList::LARAVEL_TESTING,
+ ])
+ ->withConfiguredRule(RemoveDumpDataDeadCodeRector::class, [
+ 'dd',
+ 'dump',
+ 'var_dump',
+ 'print_r',
+ 'echo',
+ ])
+ ->withConfiguredRule(WhereToWhereLikeRector::class, [
+ WhereToWhereLikeRector::USING_POSTGRES_DRIVER => true,
+ ])
+ ->withRules([
+ RemoveModelPropertyFromFactoriesRector::class,
+ UseComponentPropertyWithinCommandsRector::class,
+ TypeHintTappableCallRector::class,
+ EloquentWhereRelationTypeHintingParameterRector::class,
+ EloquentWhereTypeHintClosureParameterRector::class,
+ ]);
diff --git a/rector.php b/rector.php
new file mode 100644
index 0000000..b29b004
--- /dev/null
+++ b/rector.php
@@ -0,0 +1,15 @@
+withPaths([
+ 'bin',
+ 'presets',
+ 'src',
+ 'rector.php',
+]);
diff --git a/src/Console/RectorCommand.php b/src/Console/RectorCommand.php
new file mode 100644
index 0000000..4db79ea
--- /dev/null
+++ b/src/Console/RectorCommand.php
@@ -0,0 +1,64 @@
+setName('rector')
+ ->setDescription('Publishes presets for the Rector')
+ ->addArgument('preset', InputArgument::REQUIRED, 'The name of the preset')
+ ->addOption('path', 'p', InputOption::VALUE_OPTIONAL, 'Path to publish files', realpath('.'));
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int
+ {
+ $version = $input->getArgument('preset');
+ $path = $input->getOption('path');
+
+ if (! $this->validateVersion($version)) {
+ $output->writeln("Preset \"$version\" not found for Rector.");
+
+ return static::FAILURE;
+ }
+
+ if (! $this->validateDirectory($path)) {
+ $output->writeln("Directory \"$path\" not found.");
+
+ return static::FAILURE;
+ }
+
+ copy($this->presetPath($version), $path . '/rector.php');
+
+ $output->writeln("Preset \"$version\" published successfully.");
+
+ return static::SUCCESS;
+ }
+
+ protected function validateVersion(string $version): bool
+ {
+ return file_exists(
+ $this->presetPath($version)
+ );
+ }
+
+ protected function validateDirectory(string $path): bool
+ {
+ return file_exists($path) && is_dir($path);
+ }
+
+ protected function presetPath(string $version): string
+ {
+ return __DIR__ . "/../../presets/rector/$version.php";
+ }
+}