Instant Upgrades and Automated Refactoring of any PHP 5.3+ code
Go to file
2019-11-24 16:28:11 +01:00
.github hide Github funding support - waits for Czech Republic 2019-11-10 17:31:32 +01:00
bin use new Symplify 7 2019-11-23 18:49:27 +01:00
ci fix space fixer 2019-11-16 09:45:14 +01:00
config use new Symplify 7 2019-11-23 18:49:27 +01:00
docs fix space fixer 2019-11-16 09:45:14 +01:00
packages [Php 70] Fix this call on static for PHPUnit non-assert (#2349) 2019-11-23 21:19:39 +01:00
src Updated docblock 2019-11-24 16:04:43 +01:00
stubs [PHPUnit][Symfony] Add jakzal-injetor Rector 2019-11-18 16:21:11 +01:00
tests Add git diff intersection 2019-11-23 22:14:17 +01:00
utils decoupling 2019-11-24 16:28:11 +01:00
.coveralls.yml travis: add coverage 2018-10-28 18:47:21 +01:00
.dockerignore Ignore not required files in docker build 2019-10-28 15:55:53 +01:00
.editorconfig improve attributes, add .editorconfig 2018-12-13 17:23:24 +01:00
.gitattributes Colorify neon files 2019-07-14 12:07:34 +02:00
.gitignore report old and new table 2019-08-31 12:49:10 +02:00
.phpstorm.meta.php Rewrite of expression to previous statement 2019-10-27 17:50:26 +01:00
.travis.yml travis: drop PHP 7.1 2019-11-23 19:02:56 +01:00
BACKERS.md add paypal backers 2019-10-15 16:19:39 +02:00
changelog-linker.yaml init CHANGELOG for 0.4.11 2019-04-13 15:16:49 +02:00
CHANGELOG.md update CHANGELOG 2019-11-23 23:02:56 +01:00
CODE_OF_CONDUCT.md Use HTTPS instead of HTTP 2018-02-14 07:23:09 -02:00
composer.json decoupling 2019-11-24 16:28:11 +01:00
Dockerfile Added stub directory to Docker composer build phase 2019-09-04 14:21:22 +02:00
ecs-after-rector.yaml README: add ecs set mention 2019-11-08 18:02:29 +01:00
ecs.yaml travis: drop PHP 7.1 2019-11-23 19:02:56 +01:00
LICENSE Update LICENSE year forever 2018-01-02 20:27:07 -02:00
phpstan.neon use new Symplify 7 2019-11-23 18:49:27 +01:00
phpunit.xml small tests refactoring 2019-10-05 11:04:00 +02:00
README.md rename must-match-git-diff to shorter and easier to write match-git-diff 2019-11-24 01:00:46 +01:00
rector-ci.yaml add paths parameter 2019-11-10 18:45:01 +01:00
rector.yaml Open create command to public 2019-11-24 16:28:11 +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 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

Did you have conflicts during composer require or on run?

Running Rector

A. 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'

B. 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'

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 imported by default every time Rector performs a change, so you don't have to do it manually/after each run. You can disable it by:

# rector.yaml
parameters:
    auto_import_names: 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.

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: