Skip to content

Commit fe4da23

Browse files
authored
Merge pull request #40 from moufmouf/rector
Adding rector file generation for automatic refactoring
2 parents 0ab9192 + 3a4f883 commit fe4da23

File tree

4 files changed

+1150
-5
lines changed

4 files changed

+1150
-5
lines changed

README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,57 @@ includes:
100100
- vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon
101101
```
102102
103+
## Automated refactoring
104+
105+
You have a large legacy codebase and want to use "Safe-PHP" functions through all you project? PHPStan will help you
106+
finding these functions but changing the namespace of the functions one function at a time might be a tedious work.
107+
108+
Hopefully, Safe comes bundled with a "Rector" configuration file. [Rector](https://github.com/rectorphp/rector) is a command-line
109+
tool that performs instant refactoring of your application.
110+
111+
First, you need to install Rector:
112+
113+
```bash
114+
$ composer require --dev rector/rector ^0.3
115+
```
116+
117+
Now, you simply need to run Rector with this command:
118+
119+
```bash
120+
vendor/bin/rector process src/ --config vendor/thecodingmachine/safe/rector-migrate.yml
121+
```
122+
123+
*Note:* do not forget to replace "src/" with the path to your source directory.
124+
125+
**Important:** the refactoring is only performing a "dumb" replacement of functions. It will not modify the way
126+
"false" return values are handled. So if your code was already performing error handling, you will have to deal
127+
with it manually.
128+
129+
Especially, you should look for error handling that was already performed, like:
130+
131+
```php
132+
if (!mkdir($dirPath)) {
133+
// Do something on error
134+
}
135+
```
136+
137+
This code will be refactored by Rector to:
138+
139+
```php
140+
if (!\Safe\mkdir($dirPath)) {
141+
// Do something on error
142+
}
143+
```
144+
145+
You should then (manually) refactor it to:
146+
147+
```php
148+
try {
149+
\Safe\mkdir($dirPath));
150+
} catch (\Safe\FilesystemException $e) {
151+
// Do something on error
152+
}
153+
```
103154

104155
## Work in progress
105156

generator/src/FileCreator.php

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,19 @@ public function generatePhpFile(array $functions, string $path): void
8181
}
8282
}
8383

84+
/**
85+
* @param Method[] $functions
86+
* @return string[]
87+
*/
88+
private function getFunctionsNameList(array $functions): array
89+
{
90+
$functionNames = array_map(function (Method $function) {
91+
return $function->getFunctionName();
92+
}, $functions);
93+
$specialCases = require __DIR__.'/../config/specialCasesFunctions.php';
94+
return array_merge($functionNames, $specialCases);
95+
}
96+
8497

8598
/**
8699
* This function generate a PHP file containing the list of functions we can handle.
@@ -90,11 +103,7 @@ public function generatePhpFile(array $functions, string $path): void
90103
*/
91104
public function generateFunctionsList(array $functions, string $path): void
92105
{
93-
$functionNames = array_map(function (Method $function) {
94-
return $function->getFunctionName();
95-
}, $functions);
96-
$specialCases = require __DIR__.'/../config/specialCasesFunctions.php';
97-
$functionNames = array_merge($functionNames, $specialCases);
106+
$functionNames = $this->getFunctionsNameList($functions);
98107
$stream = fopen($path, 'w');
99108
if ($stream === false) {
100109
throw new \RuntimeException('Unable to write to '.$path);
@@ -108,6 +117,30 @@ public function generateFunctionsList(array $functions, string $path): void
108117
fclose($stream);
109118
}
110119

120+
/**
121+
* This function generate a rector yml file containing a replacer for all functions
122+
*
123+
* @param Method[] $functions
124+
* @param string $path
125+
*/
126+
public function generateRectorFile(array $functions, string $path): void
127+
{
128+
$functionNames = $this->getFunctionsNameList($functions);
129+
$stream = fopen($path, 'w');
130+
if ($stream === false) {
131+
throw new \RuntimeException('Unable to write to '.$path);
132+
}
133+
fwrite($stream, "# This rector file is replacing all core PHP functions with the equivalent \"safe\" functions
134+
services:
135+
Rector\Rector\Function_\FunctionReplaceRector:
136+
\$oldFunctionToNewFunction:
137+
");
138+
foreach ($functionNames as $functionName) {
139+
fwrite($stream, ' '.$functionName.": 'Safe\\".$functionName."'\n");
140+
}
141+
fclose($stream);
142+
}
143+
111144

112145
public function createExceptionFile(string $moduleName): void
113146
{

generator/src/GenerateCommand.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
3939
//$fileCreator->generateXlsFile($protoFunctions, __DIR__ . '/../generated/lib.xls');
4040
$fileCreator->generatePhpFile($functions, __DIR__ . '/../../generated/');
4141
$fileCreator->generateFunctionsList($functions, __DIR__ . '/../../generated/functionsList.php');
42+
$fileCreator->generateRectorFile($functions, __DIR__ . '/../../rector-migrate.yml');
4243

4344

4445
$modules = [];

0 commit comments

Comments
 (0)