Instant Upgrades and Automated Refactoring of any PHP 5.3+ code
Go to file
2019-11-08 14:42:29 +01:00
.github add rector version to bug report 2019-10-08 17:07:43 +01:00
bin add SetOptinosResolver and ConfigResolver 2019-10-30 12:17:26 +01:00
ci move ci scripts to from /bin to /ci 2019-10-30 11:56:21 +01:00
config Update rule with proper syntax of ReturnArrayClassMethodToYieldRector 2019-11-06 23:18:45 +01:00
docs update docs 2019-11-07 12:00:39 +01:00
packages fixup! fix double import of functio names 2019-11-08 14:42:29 +01:00
src misc 2019-11-05 22:44:42 +01:00
stubs apply PSR-12 2019-10-13 08:09:08 +02:00
tests use yieldFilesFromDirectory() in tests instead of explicid fixture naming 2019-11-05 18:02:26 +01:00
utils add test case to PregReplaceEModifierRector 2019-11-05 23:07:39 +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 make composer scripts Windows compatible 2019-11-07 12:29:53 +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-10-24 12:09:18 +02:00
CODE_OF_CONDUCT.md Use HTTPS instead of HTTP 2018-02-14 07:23:09 -02:00
composer.json make composer scripts Windows compatible 2019-11-07 12:29:53 +01:00
create-rector.yaml.dist rename level to set to prevent confusion of duplicate 2019-08-29 22:50:37 +02:00
Dockerfile Added stub directory to Docker composer build phase 2019-09-04 14:21:22 +02:00
ecs-after-rector.yaml do not override printing files with previous stmts if possible 2019-05-23 22:07:25 +02:00
ecs.yaml adding line_ending parameter to enforce standard behavious on windows 2019-11-07 18:34:44 +01:00
LICENSE Update LICENSE year forever 2018-01-02 20:27:07 -02:00
phpstan.neon fix implode of string/string 2019-11-05 13:35:04 +01:00
phpunit.xml small tests refactoring 2019-10-05 11:04:00 +02:00
README.md README: add headlines 2019-11-08 13:08:42 +01:00
rector-ci.yaml run all sets 2019-11-05 15:17:41 +01:00
rector.yaml use yieldFilesFromDirectory() in tests instead of explicid fixture naming 2019-11-05 18:02:26 +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.

Install

composer require rector/rector --dev

Did you have conflicts during composer require or on run?

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

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

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
imports:
    - { resource: 'vendor/rector/rector/config/set/code-quality/code-quality.yaml' }
    - { resource: 'vendor/rector/rector/config/set/php/php71.yaml' }
    - { resource: 'vendor/rector/rector/config/set/php/php72.yaml' }
    - { resource: 'vendor/rector/rector/config/set/php/php73.yaml' }

If you use Rector in Docker, you can use absolute path, e.g. /rector/config/set/php/php71.yaml

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
    

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: