2017-10-30 14:33:09 +01:00
|
|
|
# Rector - Reconstruct your Legacy Code to Modern Codebase
|
2017-07-15 19:20:20 +02:00
|
|
|
|
2017-09-21 12:40:27 +02:00
|
|
|
[![Build Status](https://img.shields.io/travis/RectorPHP/Rector/master.svg?style=flat-square)](https://travis-ci.org/RectorPHP/Rector)
|
|
|
|
[![Coverage Status](https://img.shields.io/coveralls/RectorPHP/Rector/master.svg?style=flat-square)](https://coveralls.io/github/RectorPHP/Rector?branch=master)
|
2017-07-15 19:20:20 +02:00
|
|
|
|
2017-10-30 15:44:00 +01:00
|
|
|
This tool will **upgrade your application** for you, with focus on open-source projetcs.
|
2017-07-15 19:20:20 +02:00
|
|
|
|
2017-10-30 15:44:00 +01:00
|
|
|
![Symfony](docs/symfony.png)
|
|
|
|
![Nette](docs/nette.png)
|
|
|
|
![PHPUnit](docs/phpunit.jpg)
|
|
|
|
![Roave](docs/roave.jpg)
|
|
|
|
![PHP_CodeSniffer](docs/codesniffer.jpg)
|
2017-08-20 17:40:19 +02:00
|
|
|
|
2017-07-15 19:20:20 +02:00
|
|
|
|
|
|
|
## Install
|
|
|
|
|
|
|
|
```bash
|
|
|
|
composer require rector/rector --dev
|
|
|
|
```
|
|
|
|
|
2017-10-30 14:33:09 +01:00
|
|
|
## How To Reconstruct your Code?
|
|
|
|
|
|
|
|
### A. Prepared Sets
|
|
|
|
|
2017-10-30 15:44:00 +01:00
|
|
|
Fetaured open-source projects have **prepared sets**. You'll find them in [`/src/config/level`](/src/config/level).
|
2017-10-30 14:33:09 +01:00
|
|
|
|
|
|
|
E.g. Do you need to upgrade to Nette 2.4?
|
2017-09-23 23:51:04 +02:00
|
|
|
|
2017-10-30 14:33:09 +01:00
|
|
|
1. Run rector on your `/src` directory
|
2017-09-23 23:51:04 +02:00
|
|
|
|
2017-10-30 14:33:09 +01:00
|
|
|
```bash
|
|
|
|
vendor/bin/rector process src --config vendor/bin/rector/src/config/level/nette/nette24.yml
|
2017-09-23 23:51:04 +02:00
|
|
|
```
|
2017-10-30 14:33:09 +01:00
|
|
|
|
|
|
|
Too long? Try `--level` shortcut:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
vendor/bin/rector process src --level nette24
|
2017-09-23 23:51:04 +02:00
|
|
|
```
|
|
|
|
|
2017-10-30 14:33:09 +01:00
|
|
|
2. Check the Git
|
2017-09-23 23:51:04 +02:00
|
|
|
|
|
|
|
```
|
2017-10-30 14:33:09 +01:00
|
|
|
git diff
|
2017-09-23 23:51:04 +02:00
|
|
|
```
|
|
|
|
|
2017-10-30 14:33:09 +01:00
|
|
|
|
|
|
|
### B. Custom Sets
|
2017-09-27 23:58:14 +02:00
|
|
|
|
|
|
|
1. Create `rector.yml` with desired Rectors
|
|
|
|
|
|
|
|
```yml
|
|
|
|
rectors:
|
2017-09-28 16:21:20 +02:00
|
|
|
- Rector\Rector\Contrib\Nette\Application\InjectPropertyRector
|
2017-09-27 23:58:14 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
2. Run rector on your `/src` directory
|
2017-07-15 19:20:20 +02:00
|
|
|
|
|
|
|
```bash
|
2017-09-27 23:58:14 +02:00
|
|
|
vendor/bin/rector process src
|
|
|
|
```
|
|
|
|
|
|
|
|
3. Check the Git
|
|
|
|
|
|
|
|
```
|
|
|
|
git diff
|
2017-07-15 19:20:20 +02:00
|
|
|
```
|
|
|
|
|
2017-08-21 12:12:51 +02:00
|
|
|
|
2017-09-09 20:44:44 +02:00
|
|
|
### 6 Steps to Add New Rector
|
2017-08-21 12:12:51 +02:00
|
|
|
|
|
|
|
Just extend `Rector\Rector\AbstractRector`.
|
2017-09-09 20:44:44 +02:00
|
|
|
It will prepare **2 methods** processing the node.
|
2017-08-21 12:12:51 +02:00
|
|
|
|
|
|
|
```php
|
|
|
|
public function isCandidate(Node $node): bool
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public function refactor(Node $node): ?Node
|
|
|
|
{
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
2. Put it under `namespace Rector\Contrib\<set>;` namespace
|
|
|
|
|
|
|
|
```php
|
|
|
|
<?php declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace Rector\Contrib\Symfony;
|
2017-10-30 14:33:09 +01:00
|
|
|
|
2017-08-21 12:12:51 +02:00
|
|
|
use Rector\Rector\AbstractRector;
|
|
|
|
|
|
|
|
final class MyRector extends AbstractRector
|
|
|
|
{
|
|
|
|
// ...
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
3. Add a Test Case
|
|
|
|
|
2017-09-09 20:44:44 +02:00
|
|
|
4. Add to specific level, e.g. [`/src/config/level/nette/nette24.yml`](/src/config/level/nette/nette24.yml)
|
|
|
|
|
|
|
|
5. Submit PR
|
2017-10-30 14:33:09 +01:00
|
|
|
|
|
|
|
6. :+1:
|
2017-08-21 12:12:51 +02:00
|
|
|
|
|
|
|
|
2017-10-07 10:58:54 +02:00
|
|
|
### Simpler setup with Dynamic Rectors
|
|
|
|
|
|
|
|
You don't have to always write PHP code. Many projects change only classes or method names, so it would be too much work for a simple task.
|
|
|
|
|
|
|
|
Instead you can use prepared **Dynamic Rectors** directly in `*.yml` config:
|
|
|
|
|
|
|
|
You can:
|
|
|
|
|
|
|
|
- **replace class name**
|
|
|
|
|
|
|
|
```yml
|
|
|
|
# phpunit60.yml
|
|
|
|
rectors:
|
|
|
|
Rector\Rector\Dynamic\ClassReplacerRector:
|
|
|
|
# old class: new class
|
|
|
|
'PHPUnit_Framework_TestCase': 'PHPUnit\Framework\TestCase'
|
|
|
|
```
|
|
|
|
|
2017-10-07 22:34:30 +02:00
|
|
|
- **replace part of namespace**
|
|
|
|
|
|
|
|
```yml
|
|
|
|
# better-reflection20.yml
|
|
|
|
rectors:
|
|
|
|
Rector\Rector\Dynamic\NamespaceReplacerRector:
|
|
|
|
'BetterReflection': 'Roave\BetterReflection'
|
|
|
|
```
|
|
|
|
|
2017-10-16 22:06:59 +02:00
|
|
|
- **change method name**
|
2017-10-07 10:58:54 +02:00
|
|
|
|
|
|
|
```yml
|
|
|
|
# nette24.yml
|
|
|
|
rectors:
|
|
|
|
Rector\Rector\Dynamic\MethodNameReplacerRector:
|
|
|
|
# class:
|
2017-10-20 18:04:52 +02:00
|
|
|
# old method: new method
|
2017-10-07 10:58:54 +02:00
|
|
|
'Nette\Utils\Html':
|
|
|
|
'add': 'addHtml'
|
2017-10-30 14:33:09 +01:00
|
|
|
|
2017-10-20 18:04:52 +02:00
|
|
|
# or in case of static methods calls
|
2017-10-30 14:33:09 +01:00
|
|
|
|
2017-10-20 18:04:52 +02:00
|
|
|
# class:
|
2017-10-30 14:33:09 +01:00
|
|
|
# old method: [new class, new method]
|
2017-10-20 18:04:52 +02:00
|
|
|
'Nette\Bridges\FormsLatte\FormMacros':
|
|
|
|
'renderFormBegin': ['Nette\Bridges\FormsLatte\Runtime', 'renderFormBegin']
|
2017-10-07 10:58:54 +02:00
|
|
|
```
|
|
|
|
|
2017-10-22 00:04:15 +02:00
|
|
|
- **change property name**
|
|
|
|
|
|
|
|
```yml
|
|
|
|
# php-parser40.yml
|
|
|
|
rectors:
|
|
|
|
Rector\Rector\Dynamic\PropertyNameReplacerRector:
|
|
|
|
# class:
|
|
|
|
# old property: new property
|
|
|
|
'PhpParser\Node\Param':
|
|
|
|
'name': 'var'
|
|
|
|
```
|
|
|
|
|
2017-10-20 20:35:04 +02:00
|
|
|
- **change class constant name**
|
|
|
|
|
|
|
|
```yml
|
|
|
|
# symfony30.yml
|
|
|
|
rectors:
|
|
|
|
Rector\Rector\Dynamic\ClassConstantReplacerRector:
|
|
|
|
# class:
|
|
|
|
# OLD_CONSTANT: NEW_CONSTANT
|
|
|
|
'Symfony\Component\Form\FormEvents':
|
|
|
|
'PRE_BIND': 'PRE_SUBMIT'
|
|
|
|
'BIND': 'SUBMIT'
|
|
|
|
'POST_BIND': 'POST_SUBMIT'
|
|
|
|
```
|
|
|
|
|
2017-10-22 16:51:13 +02:00
|
|
|
- **change parameters typehint according to parent type**
|
2017-10-21 18:30:45 +02:00
|
|
|
|
|
|
|
```yml
|
|
|
|
# php-parser40.yml
|
|
|
|
rectors:
|
|
|
|
Rector\Rector\Dynamic\ParentTypehintedArgumentRector:
|
|
|
|
# class:
|
|
|
|
# method:
|
|
|
|
# parameter: typehting
|
|
|
|
'PhpParser\Parser':
|
|
|
|
'parse':
|
|
|
|
'code': 'string'
|
|
|
|
```
|
|
|
|
|
2017-10-29 23:25:57 +01:00
|
|
|
- **remove unused argument**
|
2017-10-29 22:12:30 +01:00
|
|
|
|
|
|
|
```yml
|
|
|
|
Rector\Rector\Dynamic\ArgumentRemoverRector:
|
|
|
|
# class
|
|
|
|
# method
|
|
|
|
# arguments to remove
|
|
|
|
'Doctrine\ORM\Persisters\Entity\AbstractEntityInheritancePersister':
|
|
|
|
'getSelectJoinColumnSQL':
|
|
|
|
- 'className'
|
|
|
|
```
|
2017-10-30 14:33:09 +01:00
|
|
|
|
2017-10-16 22:06:59 +02:00
|
|
|
- or **replace underscore naming `_` with namespaces `\`**
|
|
|
|
|
|
|
|
```yml
|
|
|
|
rectors:
|
|
|
|
Rector\Roector\Dynamic\PseudoNamespaceToNamespaceRector:
|
|
|
|
# old namespace prefix
|
|
|
|
- 'PHPUnit_'
|
|
|
|
```
|
2017-10-07 10:58:54 +02:00
|
|
|
|
|
|
|
|
2017-10-15 11:07:53 +02:00
|
|
|
### Advanced Operations
|
|
|
|
|
|
|
|
- [Service Name to Type Provider](/docs/ServiceNameToTypeProvider.md)
|
|
|
|
|
|
|
|
|
2017-07-15 19:20:20 +02:00
|
|
|
### How to Contribute
|
|
|
|
|
|
|
|
Just follow 3 rules:
|
|
|
|
|
|
|
|
- **1 feature per pull-request**
|
2017-08-21 12:12:51 +02:00
|
|
|
- **New feature needs tests**
|
2017-07-15 19:20:20 +02:00
|
|
|
- Tests, coding standard and PHPStan **checks must pass**
|
|
|
|
|
|
|
|
```bash
|
|
|
|
composer all
|
|
|
|
```
|
|
|
|
|
2017-08-21 12:12:51 +02:00
|
|
|
Don you need to fix coding standards? Run:
|
2017-07-15 19:20:20 +02:00
|
|
|
|
|
|
|
```bash
|
2017-08-21 12:12:51 +02:00
|
|
|
composer fix-cs
|
2017-07-15 19:20:20 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
We would be happy to merge your feature then.
|
2017-10-30 14:33:09 +01:00
|
|
|
|
|
|
|
|
|
|
|
### How to use on PHP < 7.1
|
|
|
|
|
|
|
|
You must have separated environment with PHP 7.1 (for example in Docker container). When you have it then run following command:
|
|
|
|
|
|
|
|
```
|
|
|
|
composer create-project rector/rector path-to-rector
|
|
|
|
```
|
|
|
|
|
|
|
|
When do you have it then you can run all commands like
|
|
|
|
|
|
|
|
```
|
|
|
|
path-to-rector/bin/rector process /var/www/old-project --config path-to-rector/src/config/level/nette/nette24.yml
|
|
|
|
# or for short
|
|
|
|
path-to-rector/bin/rector process /var/www/old-project --level nette24
|
|
|
|
```
|