mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-03 18:00:50 +00:00
[docs] Improve first-time contributors docs (#2061)
This commit is contained in:
parent
a1ac1b6fdf
commit
51e89c3f32
|
@ -1,28 +1,36 @@
|
||||||
# How to Contribute
|
# How to Contribute
|
||||||
|
|
||||||
Contributions here are more than welcomed! You can contribute to [rector-src](https://github.com/rectorphp/rector-src) repository.
|
Contributions here are more than welcomed! You can contribute to [rector-src](https://github.com/rectorphp/rector-src) repository or one of [extension packages](https://github.com/rectorphp/).
|
||||||
|
|
||||||
## Preparing Local Environment
|
## Preparing Local Environment
|
||||||
|
|
||||||
If you have PHP 8 and Composer installed locally you can use it straight away. You can validate your environment with:
|
1. Fork the [rector/rector-src](https://github.com/rectorphp/rector-src) repository and clone it
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone git@github.com:rectorphp/rector-src.git
|
||||||
|
cd rector-src
|
||||||
|
```
|
||||||
|
|
||||||
|
2. We use PHP 8.1 and composer
|
||||||
|
|
||||||
|
Verify your local environment and update dependencies:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
composer check-platform-reqs
|
composer check-platform-reqs
|
||||||
|
composer update
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively you can use Docker runtime. All you need to do is wrap every command with `docker-compose run php`, so commands will be executed inside Docker container.
|
*Note: using Docker for contributing is strongly discouraged, as it requires [extra knowledge of composer internals](https://github.com/composer/composer/issues/9368#issuecomment-718112361).*
|
||||||
|
|
||||||
For example, to download PHP dependencies:
|
Then you can start working with the code :+1:
|
||||||
|
|
||||||
```bash
|
<br>
|
||||||
docker-compose run php composer install
|
|
||||||
```
|
|
||||||
|
|
||||||
Now you can start using all scripts and work with the code.
|
Do you want to **contribute a failing test**? [This tutorial will sow you how](https://github.com/rectorphp/rector/blob/main/docs/how_to_add_test_for_rector_rule.md)
|
||||||
|
|
||||||
## Preparing Pull Request
|
## Preparing Pull Request
|
||||||
|
|
||||||
There 3 rules will highly increase chance to get your PR merged:
|
There 3 steps will make your pull-request easy to merge:
|
||||||
|
|
||||||
- **1 feature per pull-request**
|
- **1 feature per pull-request**
|
||||||
- **new features need tests**
|
- **new features need tests**
|
||||||
|
|
|
@ -8,7 +8,7 @@ Rector instantly upgrades and refactors the PHP code of your application. It ca
|
||||||
|
|
||||||
### 1. Instant Upgrades
|
### 1. Instant Upgrades
|
||||||
|
|
||||||
Rector now supports upgrades from PHP 5.3 to 8.0 and major open-source projects like [Symfony](https://github.com/rectorphp/rector-symfony), [PHPUnit](https://github.com/rectorphp/rector-phpunit), [Nette](https://github.com/rectorphp/rector-nette), [Laravel](https://github.com/rectorphp/rector-laravel), [CakePHP](https://github.com/rectorphp/rector-cakephp), [Doctrine](https://github.com/rectorphp/rector-doctrine), [PHPOffice](https://github.com/rectorphp/rector-phpoffice) and [TYPO3](https://github.com/sabbelasichon/typo3-rector) out of the box. Do you want to **be constantly on the latest PHP/framework version without effort**?
|
Rector now supports upgrades from PHP 5.3 to 8.1 and major open-source projects like [Symfony](https://github.com/rectorphp/rector-symfony), [PHPUnit](https://github.com/rectorphp/rector-phpunit), [Nette](https://github.com/rectorphp/rector-nette), [Laravel](https://github.com/rectorphp/rector-laravel), [CakePHP](https://github.com/rectorphp/rector-cakephp), [Doctrine](https://github.com/rectorphp/rector-doctrine) and [TYPO3](https://github.com/sabbelasichon/typo3-rector) out of the box. Do you want to **be constantly on the latest PHP and Framework without effort**?
|
||||||
|
|
||||||
Use Rector to handle **instant upgrades** for you.
|
Use Rector to handle **instant upgrades** for you.
|
||||||
|
|
||||||
|
@ -34,21 +34,22 @@ By [buying a book](https://leanpub.com/rector-the-power-of-automated-refactoring
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
- [Explore 450+ Rector Rules](/docs/rector_rules_overview.md)
|
- [Explore 500+ Rector Rules](/docs/rector_rules_overview.md)
|
||||||
- [Auto Import Names](/docs/auto_import_names.md)
|
|
||||||
- [How to Ignore Rule or Paths](/docs/how_to_ignore_rule_or_paths.md)
|
- [How to Ignore Rule or Paths](/docs/how_to_ignore_rule_or_paths.md)
|
||||||
- [Static Reflection and Autoload](/docs/static_reflection_and_autoload.md)
|
- [Static Reflection and Autoload](/docs/static_reflection_and_autoload.md)
|
||||||
- [How to Configure Rule](/docs/how_to_configure_rules.md)
|
- [How to Configure Rule](/docs/how_to_configure_rules.md)
|
||||||
- [Beyond PHP - Entering the realm of FileProcessors](/docs/beyond_php_file_processors.md)
|
- [Auto Import Names](/docs/auto_import_names.md)
|
||||||
|
|
||||||
### For Rule Developers and Contributors
|
### For Rule Developers and Contributors
|
||||||
|
|
||||||
|
- [How to add Test for Rector Rule](/docs/how_to_add_test_for_rector_rule.md)
|
||||||
- [How Does Rector Work?](/docs/how_it_works.md)
|
- [How Does Rector Work?](/docs/how_it_works.md)
|
||||||
- [PHP Parser Nodes](https://github.com/rectorphp/php-parser-nodes-docs/)
|
- [PHP Parser Nodes](https://github.com/rectorphp/php-parser-nodes-docs/)
|
||||||
- [How to Work with Doc Block and Comments](/docs/how_to_work_with_doc_block_and_comments.md)
|
- [How to Work with Doc Block and Comments](/docs/how_to_work_with_doc_block_and_comments.md)
|
||||||
- [How to Generate New Rector Rule](/docs/create_own_rule.md)
|
- [How to Generate New Rector Rule](/docs/create_own_rule.md)
|
||||||
- [How to add Test for Rector Rule](/docs/how_to_add_test_for_rector_rule.md)
|
|
||||||
- [How to create a custom FileProcessor](/docs/how_to_create_custom_fileprocessor.md)
|
See [the full documentation](/docs).
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
|
@ -16,7 +16,7 @@ Rector works with all class names as fully qualified by default, so it knows the
|
||||||
To import FQN like these, configure `rector.php` with:
|
To import FQN like these, configure `rector.php` with:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
|
$rectorConfig->autoImportNames();
|
||||||
```
|
```
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
@ -37,8 +37,9 @@ $parameters->set(Option::IMPORT_SHORT_CLASSES, false);
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
If you have set Option::AUTO_IMPORT_NAMES to true, rector is applying this to every analyzed file, even if no real change by a rector was applied to the file.
|
If you have set `Option::AUTO_IMPORT_NAMES` to `true`, rector is applying this to every analyzed file, even if no real change by a rector was applied to the file.
|
||||||
The reason is that a so-called post rector is responsible for this, namely the NameImportingPostRector.
|
|
||||||
|
The reason is that a so-called post-rector is responsible for this, namely the `NameImportingPostRector`.
|
||||||
If you like to apply the Option::AUTO_IMPORT_NAMES only for real changed files, you can configure this.
|
If you like to apply the Option::AUTO_IMPORT_NAMES only for real changed files, you can configure this.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
@ -65,3 +66,7 @@ Run it:
|
||||||
```bash
|
```bash
|
||||||
vendor/bin/ecs check src --fix
|
vendor/bin/ecs check src --fix
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Happy coding!
|
||||||
|
|
|
@ -9,37 +9,11 @@ When using Rector to update your own code, you will typically be using release r
|
||||||
- Install dependencies by executing `composer install`
|
- Install dependencies by executing `composer install`
|
||||||
- Tests your installation by executing `composer fix-cs` and `composer phpstan`
|
- Tests your installation by executing `composer fix-cs` and `composer phpstan`
|
||||||
- Create a new branch for your test
|
- Create a new branch for your test
|
||||||
- Add your test as described below. Note that the rector binary is located at `bin/rector` instead of the typical `vendor/bin/rector`
|
- Add your test as described below. Note that the rector binary is located at `bin/rector` instead of the typical `vendor/bin/rector`
|
||||||
- Push the branch and create a new pull request to https://github.com/rectorphp/rector-src
|
- Push the branch
|
||||||
|
- Create a new pull request to https://github.com/rectorphp/rector-src
|
||||||
|
|
||||||
Alternatively, the above may be performed on the CLI
|
<br>
|
||||||
|
|
||||||
```bash
|
|
||||||
# Authenticate
|
|
||||||
gh auth login
|
|
||||||
|
|
||||||
# Fork and clone the repository
|
|
||||||
gh repo fork https://github.com/rectorphp/rector-src
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
cd rector-src
|
|
||||||
composer install
|
|
||||||
|
|
||||||
# Test installation
|
|
||||||
composer fix-cs
|
|
||||||
composer phpstan
|
|
||||||
|
|
||||||
# Create and checkout a branch
|
|
||||||
git checkout -b your_branch_name
|
|
||||||
|
|
||||||
# Create test as described below
|
|
||||||
|
|
||||||
# Push the branch
|
|
||||||
git push -u origin your_branch_name
|
|
||||||
|
|
||||||
# create new pull request to https://github.com/rectorphp/rector-src
|
|
||||||
gh pr create --title "Your title text" --body "Your body text"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Detect the Rector Rule
|
## 2. Detect the Rector Rule
|
||||||
|
|
||||||
|
@ -57,6 +31,8 @@ Our rule in this example is: `Rector\Privatization\Rector\Class_\FinalizeClasses
|
||||||
|
|
||||||
This rule's job is to add `final` to every class that has no children and is not a Doctrine entity = everywhere it can without breaking our code.
|
This rule's job is to add `final` to every class that has no children and is not a Doctrine entity = everywhere it can without breaking our code.
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
## 3. Detect the Minimal File
|
## 3. Detect the Minimal File
|
||||||
|
|
||||||
Usually, the Rector diff output is long and contains many other errors related to other rules. It's a mess; we can't use that for a test fixture. We need to find **1 responsible line**.
|
Usually, the Rector diff output is long and contains many other errors related to other rules. It's a mess; we can't use that for a test fixture. We need to find **1 responsible line**.
|
||||||
|
@ -79,6 +55,8 @@ bin/rector process app/SomeFile.php
|
||||||
|
|
||||||
Do we have the same diff? Great!
|
Do we have the same diff? Great!
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
## 4. Find the Rector Test Case
|
## 4. Find the Rector Test Case
|
||||||
|
|
||||||
Now we need to find the test case. The test case name is rule + `Test` suffix.
|
Now we need to find the test case. The test case name is rule + `Test` suffix.
|
||||||
|
@ -89,14 +67,12 @@ Now we need to find the test case. The test case name is rule + `Test` suffix.
|
||||||
|
|
||||||
`FinalizeClassesWithoutChildrenRectorTest` (test class)
|
`FinalizeClassesWithoutChildrenRectorTest` (test class)
|
||||||
|
|
||||||
↓
|
|
||||||
|
|
||||||
`FinalizeClassesWithoutChildrenRectorTest.php` (test file)
|
|
||||||
|
|
||||||
Right here:
|
Right here:
|
||||||
|
|
||||||
![Rule Test Case](/docs/images/docs_rule_test_case.png)
|
![Rule Test Case](/docs/images/docs_rule_test_case.png)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
## 5. Add Change or No-Change Test Fixture File
|
## 5. Add Change or No-Change Test Fixture File
|
||||||
|
|
||||||
Next to the test case, there is `/Fixture` directory. It contains many test fixture files that verified the Rector rule work correctly in all possible cases.
|
Next to the test case, there is `/Fixture` directory. It contains many test fixture files that verified the Rector rule work correctly in all possible cases.
|
||||||
|
@ -105,9 +81,11 @@ Do you see *test fixture file* first time? It's a file with real-life PHP code t
|
||||||
|
|
||||||
In the `/Fixture` directory, we create our test fixture file, e.g., `add_final.php.inc`. The `.php.inc` is there on purpose, so the file is hidden from coding standard tools and static analysis.
|
In the `/Fixture` directory, we create our test fixture file, e.g., `add_final.php.inc`. The `.php.inc` is there on purpose, so the file is hidden from coding standard tools and static analysis.
|
||||||
|
|
||||||
There are 2 fixture formats.
|
<br>
|
||||||
|
|
||||||
### 1. The Code Should Change
|
There are 2 fixture formats:
|
||||||
|
|
||||||
|
### A. The Code Should Change
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
<code before>
|
<code before>
|
||||||
|
@ -115,7 +93,7 @@ There are 2 fixture formats.
|
||||||
<code after>
|
<code after>
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. The Code Should Be Skipped
|
### B. The Code Should Be Skipped
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
<code before>
|
<code before>
|
||||||
|
@ -164,3 +142,7 @@ vendor/bin/phpunit rules-tests/Privatization/Rector/Class_/FinalizeClassesWithou
|
||||||
```
|
```
|
||||||
|
|
||||||
If PHPUnit fails, you've successfully added a test case! :)
|
If PHPUnit fails, you've successfully added a test case! :)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Thank you
|
||||||
|
|
|
@ -88,4 +88,15 @@ final class RectorConfig extends ContainerConfigurator
|
||||||
$services->set($rectorClass)
|
$services->set($rectorClass)
|
||||||
->configure($configuration);
|
->configure($configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param class-string<RectorInterface> $rectorClass
|
||||||
|
*/
|
||||||
|
public function rule(string $rectorClass): void
|
||||||
|
{
|
||||||
|
Assert::isAOf($rectorClass, RectorInterface::class);
|
||||||
|
|
||||||
|
$services = $this->services();
|
||||||
|
$services->set($rectorClass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,22 +2,18 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
use Rector\Core\Configuration\Option;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Renaming\Rector\Name\RenameClassRector;
|
use Rector\Renaming\Rector\Name\RenameClassRector;
|
||||||
use Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source\FirstNamespace\SomeServiceClass as SomeServiceClassFirstNamespace;
|
use Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source\FirstNamespace\SomeServiceClass as SomeServiceClassFirstNamespace;
|
||||||
use Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source\NewClass;
|
use Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source\NewClass;
|
||||||
use Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source\OldClass;
|
use Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source\OldClass;
|
||||||
use Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source\SecondNamespace\SomeServiceClass;
|
use Rector\Tests\Renaming\Rector\Name\RenameClassRector\Source\SecondNamespace\SomeServiceClass;
|
||||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
|
||||||
|
|
||||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
return static function (RectorConfig $rectorConfig): void {
|
||||||
$parameters = $containerConfigurator->parameters();
|
$rectorConfig->autoImportNames();
|
||||||
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
|
|
||||||
|
|
||||||
$services = $containerConfigurator->services();
|
$rectorConfig->ruleWithConfiguration(RenameClassRector::class, [
|
||||||
$services->set(RenameClassRector::class)
|
OldClass::class => NewClass::class,
|
||||||
->configure([
|
SomeServiceClassFirstNamespace::class => SomeServiceClass::class,
|
||||||
OldClass::class => NewClass::class,
|
]);
|
||||||
SomeServiceClassFirstNamespace::class => SomeServiceClass::class,
|
|
||||||
]);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,24 +2,20 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
use Rector\Core\Configuration\Option;
|
use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
|
||||||
use Rector\Php74\Rector\Property\TypedPropertyRector;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\LevelSetList;
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
|
||||||
|
|
||||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
return static function (RectorConfig $rectorConfig): void {
|
||||||
// get parameters
|
$rectorConfig->paths([
|
||||||
$parameters = $containerConfigurator->parameters();
|
|
||||||
$parameters->set(Option::PATHS, [
|
|
||||||
__DIR__ . '/src'
|
__DIR__ . '/src'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Define what rule sets will be applied
|
|
||||||
$containerConfigurator->import(LevelSetList::UP_TO_PHP_XY);
|
|
||||||
|
|
||||||
// get services (needed for register a single rule)
|
|
||||||
// $services = $containerConfigurator->services();
|
|
||||||
|
|
||||||
// register a single rule
|
// register a single rule
|
||||||
// $services->set(TypedPropertyRector::class);
|
$rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
|
||||||
|
|
||||||
|
// define sets of rules
|
||||||
|
// $rectorConfig->sets([
|
||||||
|
// LevelSetList::UP_TO_PHP_XY
|
||||||
|
// ]);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user