Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
4.65% covered (danger)
4.65%
2 / 43
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
RectorConfig
4.65% covered (danger)
4.65%
2 / 43
0.00% covered (danger)
0.00%
0 / 1
26.67
0.00% covered (danger)
0.00%
0 / 1
 configure
4.65% covered (danger)
4.65%
2 / 43
0.00% covered (danger)
0.00%
0 / 1
26.67
1<?php
2
3declare(strict_types=1);
4
5/**
6 * This file is part of fast-forward/dev-tools.
7 *
8 * This source file is subject to the license bundled
9 * with this source code in the file LICENSE.
10 *
11 * @copyright Copyright (c) 2026 Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
12 * @license   https://opensource.org/licenses/MIT MIT License
13 *
14 * @see       https://github.com/php-fast-forward/dev-tools
15 * @see       https://github.com/php-fast-forward
16 * @see       https://datatracker.ietf.org/doc/html/rfc2119
17 */
18
19namespace FastForward\DevTools\Config;
20
21use Composer\InstalledVersions;
22use Ergebnis\Rector\Rules\Faker\GeneratorPropertyFetchToMethodCallRector;
23use FastForward\DevTools\Rector\AddMissingMethodPhpDocRector;
24use FastForward\DevTools\Rector\RemoveEmptyDocBlockRector;
25use Rector\Config\RectorConfig as RectorConfigInterface;
26use Rector\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector;
27use Rector\DeadCode\Rector\ClassMethod\RemoveUselessReturnTagRector;
28use Rector\Php\PhpVersionResolver\ComposerJsonPhpVersionResolver;
29use Rector\Configuration\PhpLevelSetResolver;
30use Rector\Set\ValueObject\SetList;
31
32use function Safe\getcwd;
33
34/**
35 * Provides the default Rector configuration.
36 *
37 * Consumers can use this as a starting point and extend it:
38 *
39 *     return \FastForward\DevTools\Config\RectorConfig::configure(
40 *         static function (\Rector\Config\RectorConfig $rectorConfig): void {
41 *             $rectorConfig->rules([
42 *                 // custom rules
43 *             ]);
44 *         }
45 *     );
46 *
47 * @see https://github.com/rectorphp/rector
48 */
49 class RectorConfig
50{
51    /**
52     * Creates the default Rector configuration.
53     *
54     * @param callable|null $customize optional callback to customize the configuration
55     *
56     * @return callable the configuration callback
57     */
58    public static function configure(?callable $customize = null): callable
59    {
60        return static function (RectorConfigInterface $rectorConfig) use ($customize): void {
61            $cwd = getcwd();
62
63            $rectorConfig->sets([
64                SetList::DEAD_CODE,
65                SetList::CODE_QUALITY,
66                SetList::CODING_STYLE,
67                SetList::TYPE_DECLARATION,
68                SetList::PRIVATIZATION,
69                SetList::INSTANCEOF,
70                SetList::EARLY_RETURN,
71            ]);
72            $rectorConfig->paths([$cwd]);
73            $rectorConfig->skip([
74                $cwd . '/public',
75                $cwd . '/resources',
76                $cwd . '/vendor',
77                $cwd . '/tmp',
78                RemoveUselessReturnTagRector::class,
79                RemoveUselessParamTagRector::class,
80            ]);
81            $rectorConfig->cacheDirectory($cwd . '/tmp/cache/rector');
82            $rectorConfig->importNames();
83            $rectorConfig->removeUnusedImports();
84            $rectorConfig->fileExtensions(['php']);
85            $rectorConfig->parallel(600);
86            $rectorConfig->rules([
87                GeneratorPropertyFetchToMethodCallRector::class,
88                AddMissingMethodPhpDocRector::class,
89                RemoveEmptyDocBlockRector::class,
90            ]);
91
92            $projectPhpVersion = ComposerJsonPhpVersionResolver::resolveFromCwdOrFail();
93            $phpLevelSets = PhpLevelSetResolver::resolveFromPhpVersion($projectPhpVersion);
94
95            $rectorConfig->sets($phpLevelSets);
96
97            if (InstalledVersions::isInstalled('thecodingmachine/safe', false)) {
98                $packageLocation = InstalledVersions::getInstallPath('thecodingmachine/safe');
99                $safeRectorMigrateFile = $packageLocation . '/rector-migrate.php';
100
101                if (file_exists($safeRectorMigrateFile)) {
102                    $callback = require_once $safeRectorMigrateFile;
103
104                    if (\is_callable($callback)) {
105                        $callback($rectorConfig);
106                    }
107                }
108            }
109
110            if (null !== $customize) {
111                $customize($rectorConfig);
112            }
113        };
114    }
115}