Instant Upgrades and Automated Refactoring of any PHP 5.3+ code
Go to file
2020-01-12 22:42:38 +01:00
.github test doctrine/orm 2020-01-12 11:26:27 +01:00
bin load just once experiment 2019-12-09 00:57:44 +01:00
ci remove confusing RectorServiceParametersShifter 2019-12-23 02:29:02 +01:00
compiler remove var-dumper from rector.phar 2020-01-11 00:53:51 +01:00
config Add PHPStanAttributeTypeSyncer 2020-01-12 21:42:19 +01:00
docs [CakePHP] Add ImplicitShortClassNameUseStatementRector 2020-01-11 22:14:25 +01:00
helpers Add PHPStanAttributeTypeSyncer 2020-01-12 21:42:19 +01:00
packages remove old manual nodes 2020-01-12 22:42:38 +01:00
src fix pattern miss matching (#2639) 2020-01-11 11:10:55 +01:00
stubs [DoctrineGemoToKnplabs] Add LoggableBehaviorRector 2020-01-07 14:29:54 +01:00
tests fix cs & bump to Symplify 7.2 2020-01-06 14:44:07 +01:00
utils remove old manual nodes 2020-01-12 22:42:38 +01:00
.coveralls.yml travis: add coverage 2018-10-28 18:47:21 +01:00
.dockerignore use Github Actions to compile and publish prefixed rector.phar, coverage and the rest 2020-01-11 16:31:06 +01:00
.editorconfig improve attributes, add .editorconfig 2018-12-13 17:23:24 +01:00
.gitattributes use Github Actions to compile and publish prefixed rector.phar, coverage and the rest 2020-01-11 16:31:06 +01:00
.gitignore Add ScanFatalErrors command 2019-12-24 16:06:06 +01:00
.phpstorm.meta.php Rewrite of expression to previous statement 2019-10-27 17:50:26 +01:00
BACKERS.md [SOLID] Add ChangeIfElseValueAssignToEarlyReturnRector 2020-01-06 01:42:15 +01:00
changelog-linker.yaml init CHANGELOG for 0.4.11 2019-04-13 15:16:49 +02:00
CHANGELOG.md update CHANGELOG for v0.6.8 2020-01-08 14:45:06 +01:00
CODE_OF_CONDUCT.md Use HTTPS instead of HTTP 2018-02-14 07:23:09 -02:00
composer.json Add PHPStanAttributeTypeSyncer 2020-01-12 21:42:19 +01:00
Dockerfile chore: use php 7.4 cli 2019-12-04 11:21:48 +00:00
ecs-after-rector.yaml use explicit null in yaml 2020-01-05 20:00:32 +01:00
ecs.yaml Add PHPStanAttributeTypeSyncer 2020-01-12 21:42:19 +01:00
LICENSE Update LICENSE year forever 2018-01-02 20:27:07 -02:00
phpstan.neon [Php70] add a rector to pass only variables as arguments by reference 2020-01-10 15:37:08 +01:00
phpunit.xml travis: cut down coverage time from 33 mins to 3 with phpdbg 2020-01-06 12:45:28 +01:00
README.md use Github Actions to compile and publish prefixed rector.phar, coverage and the rest 2020-01-11 16:31:06 +01:00
rector-ci.yaml add paths parameter 2019-11-10 18:45:01 +01:00
rector.yaml [SOLID] Add ChangeIfElseValueAssignToEarlyReturnRector 2020-01-06 01:42:15 +01:00

Rector - Upgrade Your Legacy App to a Modern Codebase

Rector is a reconstructor tool - it does instant upgrades and instant refactoring of your code. Why refactor manually if Rector can handle 80% for you?

Build Status Github Actions Coverage Status Downloads

Rector-showcase


Sponsors

Rector grows faster with your help, the more you help the more work it saves you. Check out Rector's Patreon. One-time donation is welcomed through PayPal.

Thank you:


Open-Source First

Rector instantly upgrades and instantly refactors the PHP code of your application. It supports all modern versions of PHP and many open-source projects:




What Can Rector Do for You?

...look at the overview of all available Rectors with before/after diffs and configuration examples. You can use them to build your own sets.

How to Apply Coding Standards?

The AST libraries that Rector uses aren't well-suited for coding standards, so it's better to let coding standard tools do that.

Don't have a coding standard tool for your project? Consider adding EasyCodingStandard, PHP CS Fixer or PHP_CodeSniffer.

Tip: If you have EasyCodingStandard, you can start your set with ecs-after-rector.yaml.

Install

composer require rector/rector --dev

Do you have conflicts during composer require or on run?

Do you need different PHP version than Rector supports?

Running Rector

A. Get Started

Try the demo and get familiar with rector

B. Prepared Sets

Featured open-source projects have prepared sets. You can find them in /config/set or by running:

vendor/bin/rector sets

Let's say you pick the symfony40 set and you want to upgrade your /src directory:

# show a list of known changes in Symfony 4.0
vendor/bin/rector process src --set symfony40 --dry-run
# apply upgrades to your code
vendor/bin/rector process src --set symfony40

Some sets, such as code-quality can be used on a regular basis. You can include them in your rector.yaml to run them by default:

# rector.yaml
parameters:
    sets:
        - 'code-quality'
        - 'php71'
        - 'php72'
        - 'php73'

C. Custom Sets

  1. Create a rector.yaml config file with your desired Rectors:

    services:
        Rector\Rector\Architecture\DependencyInjection\AnnotatedPropertyInjectToConstructorInjectionRector:
            $annotation: "inject"
    
  2. Run Rector on your /src directory:

    vendor/bin/rector process src --dry-run
    # apply
    vendor/bin/rector process src
    

Features

Extra Autoloading

Rector relies on project and autoloading of its classes. To specify your own autoload file, use --autoload-file option:

vendor/bin/rector process ../project --autoload-file ../project/vendor/autoload.php

Or use a rector.yaml config file:

# rector.yaml
parameters:
    autoload_paths:
        - 'vendor/squizlabs/php_codesniffer/autoload.php'
        - 'vendor/project-without-composer'

Exclude Paths and Rectors

You can also exclude files or directories (with regex or fnmatch):

# rector.yaml
parameters:
    exclude_paths:
        - '*/src/*/Tests/*'

You can use a whole ruleset, except one rule:

# rector.yaml
parameters:
    exclude_rectors:
        - 'Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector'

Do you want to skip just specific line with specific rule?

Use @noRector \FQN name annotation:

class SomeClass
{
    /**
     * @noRector \Rector\DeadCode\Rector\ClassMethod\RemoveEmptyClassMethodRector
     */
    public function foo()
    {
        /** @noRector \Rector\DeadCode\Rector\Plus\RemoveDeadZeroAndOneOperationRector */
        round(1 + 0);
    }
}

Provide PHP Version

By default Rector uses the language features matching your system version of PHP. You can configure it for a different PHP version:

# rector.yaml
parameters:
    php_version_features: '7.2' # your version is 7.3

Paths

If you're annoyed by repeating paths in arguments, you can move them to config instead:

# rector.yaml
parameters:
    paths:
        - 'src'
        - 'tests'

Import Use Statements

FQN classes are not imported by default. If you don't to do do it manually after every Rector run, enable it by:

# rector.yaml
parameters:
    auto_import_names: true

You can also fine-tune how these imports are processed:

# rector.yaml
parameters:
    # this will not import root namespace classes, like \DateTime or \Exception
    import_short_classes: false

    # this will not import classes used in PHP DocBlocks, like in /** @var \Some\Class */
    import_doc_blocks: false

Limit Execution to Changed Files

Execution can be limited to changed files using the process option --match-git-diff. This option will filter the files included by the configuration, creating an intersection with the files listed in git diff.

vendor/bin/rector process src --match-git-diff

This option is useful in CI with pull-requests that only change few files.

Symfony Container

To work with some Symfony rules, you now need to link your container XML file

# rector.yaml
parameters:
    # path to load services from
    symfony_container_xml_path: 'var/cache/dev/AppKernelDevDebugContainer.xml'

3 Steps to Create Your Own Rector

First, make sure it's not covered by any existing Rectors.

Let's say we want to change method calls from set* to change*.

 $user = new User();
-$user->setPassword('123456');
+$user->changePassword('123456');

1. Create a New Rector and Implement Methods

Create a class that extends Rector\Rector\AbstractRector. It will inherit useful methods e.g. to check node type and name. See the source (or type $this-> in an IDE) for a list of available methods.

<?php

declare(strict_types=1);

namespace App\Rector;

use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Identifier;
use PhpParser\Node\Expr\MethodCall;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;

final class MyFirstRector extends AbstractRector
{
    public function getDefinition(): RectorDefinition
    {
        // what does this do?
        // minimalistic before/after sample - to explain in code
        return new RectorDefinition('Change method calls from set* to change*.', [
            new CodeSample('$user->setPassword("123456");', '$user->changePassword("123456");')
        ]);
    }

    /**
     * @return string[]
     */
    public function getNodeTypes(): array
    {
        // what node types we look for?
        // pick any node from https://github.com/rectorphp/rector/blob/master/docs/NodesOverview.md
        return [MethodCall::class];
    }

    /**
     * @param MethodCall $node - we can add "MethodCall" type here, because only this node is in "getNodeTypes()"
     */
    public function refactor(Node $node): ?Node
    {
        // we only care about "set*" method names
        if (! $this->isName($node, 'set*')) {
            // return null to skip it
            return null;
        }

        $methodCallName = $this->getName($node);
        $newMethodCallName = Strings::replace($methodCallName, '#^set#', 'change');

        $node->name = new Identifier($newMethodCallName);

        // return $node if you modified it
        return $node;
    }
}

2. Register It

# rector.yaml
services:
    App\Rector\MyFirstRector: ~

3. Let Rector Refactor Your Code

# see the diff first
vendor/bin/rector process src --dry-run

# if it's ok, apply
vendor/bin/rector process src

That's it!

More Detailed Documentation

How to Contribute

Just follow 3 rules:

  • 1 feature per pull-request

  • New features need tests

  • Tests, coding standards and PHPStan checks must pass:

    composer complete-check
    

    Do you need to fix coding standards? Run:

    composer fix-cs
    

We would be happy to accept PRs that follow these guidelines.

Run Rector in Docker

You can run Rector on your project using Docker:

docker run -v $(pwd):/project rector/rector:latest process /project/src --set symfony40 --dry-run

# Note that a volume is mounted from `pwd` (the current directory) into `/project` which can be accessed later.

Using rector.yaml:

docker run -v $(pwd):/project rector/rector:latest process /project/app --config /project/rector.yaml --autoload-file /project/vendor/autoload.php --dry-run

Community Packages

Do you use Rector to upgrade your code? Add it here: