Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,57 @@ includes:
- vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon
```

## Automated refactoring

You have a large legacy codebase and want to use "Safe-PHP" functions through all you project? PHPStan will help you
finding these functions but changing the namespace of the functions one function at a time might be a tedious work.

Hopefully, Safe comes bundled with a "Rector" configuration file. [Rector](https://github.com/rectorphp/rector) is a command-line
tool that performs instant refactoring of your application.

First, you need to install Rector:

```bash
$ composer require --dev rector/rector ^0.3
```

Now, you simply need to run Rector with this command:

```bash
vendor/bin/rector process src/ --config vendor/thecodingmachine/safe/rector-migrate.yml
```

*Note:* do not forget to replace "src/" with the path to your source directory.

**Important:** the refactoring is only performing a "dumb" replacement of functions. It will not modify the way
"false" return values are handled. So if your code was already performing error handling, you will have to deal
with it manually.

Especially, you should look for error handling that was already performed, like:

```php
if (!mkdir($dirPath)) {
// Do something on error
}
```

This code will be refactored by Rector to:

```php
if (!\Safe\mkdir($dirPath)) {
// Do something on error
}
```

You should then (manually) refactor it to:

```php
try {
\Safe\mkdir($dirPath));
} catch (\Safe\FilesystemException $e) {
// Do something on error
}
```

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also mention --with-style option to fixup coding style


## Work in progress

Expand Down
43 changes: 38 additions & 5 deletions generator/src/FileCreator.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,19 @@ public function generatePhpFile(array $functions, string $path): void
}
}

/**
* @param Method[] $functions
* @return string[]
*/
private function getFunctionsNameList(array $functions): array
{
$functionNames = array_map(function (Method $function) {
return $function->getFunctionName();
}, $functions);
$specialCases = require __DIR__.'/../config/specialCasesFunctions.php';
return array_merge($functionNames, $specialCases);
}


/**
* This function generate a PHP file containing the list of functions we can handle.
Expand All @@ -90,11 +103,7 @@ public function generatePhpFile(array $functions, string $path): void
*/
public function generateFunctionsList(array $functions, string $path): void
{
$functionNames = array_map(function (Method $function) {
return $function->getFunctionName();
}, $functions);
$specialCases = require __DIR__.'/../config/specialCasesFunctions.php';
$functionNames = array_merge($functionNames, $specialCases);
$functionNames = $this->getFunctionsNameList($functions);
$stream = fopen($path, 'w');
if ($stream === false) {
throw new \RuntimeException('Unable to write to '.$path);
Expand All @@ -108,6 +117,30 @@ public function generateFunctionsList(array $functions, string $path): void
fclose($stream);
}

/**
* This function generate a rector yml file containing a replacer for all functions
*
* @param Method[] $functions
* @param string $path
*/
public function generateRectorFile(array $functions, string $path): void
{
$functionNames = $this->getFunctionsNameList($functions);
$stream = fopen($path, 'w');
if ($stream === false) {
throw new \RuntimeException('Unable to write to '.$path);
}
fwrite($stream, "# This rector file is replacing all core PHP functions with the equivalent \"safe\" functions
services:
Rector\Rector\Function_\FunctionReplaceRector:
\$oldFunctionToNewFunction:
");
foreach ($functionNames as $functionName) {
fwrite($stream, ' '.$functionName.": 'Safe\\".$functionName."'\n");
}
fclose($stream);
}


public function createExceptionFile(string $moduleName): void
{
Expand Down
1 change: 1 addition & 0 deletions generator/src/GenerateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
//$fileCreator->generateXlsFile($protoFunctions, __DIR__ . '/../generated/lib.xls');
$fileCreator->generatePhpFile($functions, __DIR__ . '/../../generated/');
$fileCreator->generateFunctionsList($functions, __DIR__ . '/../../generated/functionsList.php');
$fileCreator->generateRectorFile($functions, __DIR__ . '/../../rector-migrate.yml');


$modules = [];
Expand Down
Loading