Merge pull request #636 from rectorphp/parameter-guard

Add ParameterGuide
This commit is contained in:
Tomáš Votruba 2018-09-26 14:55:08 +03:00 committed by GitHub
commit 606edd7f45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 142 additions and 23 deletions

View File

@ -56,14 +56,12 @@ Or make use of `rector.yml` config:
```yaml
# rector.yml
parameters:
autoload_files:
autoload_paths:
- '%kernel.project_dir%/vendor/squizlabs/php_codesniffer/autoload.php'
autoload_directories:
- '%kernel.project_dir%/vendor/project-without-composer'
```
You can also exclude files or directories - use regex or [fnmatch](http://php.net/manual/en/function.fnmatch.php):
You can also **exclude files or directories** - use regex or [fnmatch](http://php.net/manual/en/function.fnmatch.php):
```yaml
# rector.yml

View File

@ -41,6 +41,7 @@
"Rector\\Symfony\\": "packages/Symfony/src",
"Rector\\CakePHP\\": "packages/CakePHP/src",
"Rector\\Silverstripe\\": "packages/Silverstripe/src",
"Rector\\ParameterGuider\\": "packages/ParameterGuider/src",
"Rector\\Sensio\\": "packages/Sensio/src",
"Rector\\Sylius\\": "packages/Sylius/src",
"Rector\\PHPUnit\\": "packages/PHPUnit/src",

View File

@ -0,0 +1,7 @@
services:
_defaults:
autowire: true
public: true
Rector\ParameterGuider\:
resource: '../src'

View File

@ -0,0 +1,9 @@
<?php declare(strict_types=1);
namespace Rector\ParameterGuider\Exception;
use Exception;
final class ParameterTypoException extends Exception
{
}

View File

@ -0,0 +1,54 @@
<?php declare(strict_types=1);
namespace Rector\ParameterGuider;
use Nette\Utils\Strings;
use Rector\ParameterGuider\Exception\ParameterTypoException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use function Safe\sprintf;
/**
* This class makes sure there are no typos in parameter names,
* and if so, it will suggest the correct parameter name.
*/
final class ParameterGuider
{
/**
* @var string[]
*/
private static $parametersWithMissplacedNames = [
// correct paremter => regex catching invalid values
'exclude_paths' => '#exclude(d)?_(path(s)?|dir(s)?|file(s)?)#',
'autoload_paths' => '#autoload(d)?_(path(s)?|dir(s)?|file(s)?)#',
];
public function processParameters(ParameterBagInterface $parameterBag): void
{
$parameterNames = array_keys($parameterBag->all());
foreach ($parameterNames as $parameterName) {
foreach (self::$parametersWithMissplacedNames as $correctParameterName => $missplacedNamePattern) {
if ($parameterName === $correctParameterName) {
continue;
}
if (Strings::match($parameterName, $missplacedNamePattern)) {
$this->throwException($parameterName, $correctParameterName);
}
if (levenshtein($correctParameterName, $parameterName) < 2) {
$this->throwException($parameterName, $correctParameterName);
}
}
}
}
private function throwException(string $providedParameterName, string $correctParameterName): void
{
throw new ParameterTypoException(sprintf(
'Parameter "parameters > %s" does not exist. Use "parameters > %s" instead.',
$providedParameterName,
$correctParameterName
));
}
}

View File

@ -0,0 +1,18 @@
<?php declare(strict_types=1);
namespace Rector\ParameterGuider\Tests;
use PHPUnit\Framework\TestCase;
use Rector\DependencyInjection\ContainerFactory;
use Rector\ParameterGuider\Exception\ParameterTypoException;
final class ParameterGuiderTest extends TestCase
{
public function test(): void
{
// the validation is triggered on command run
$this->expectException(ParameterTypoException::class);
(new ContainerFactory())->createWithConfigFiles([__DIR__ . '/config.yml']);
}
}

View File

@ -0,0 +1,3 @@
parameters:
exclude_files:
- 'some_file'

View File

@ -7,6 +7,7 @@ use Rector\Configuration\Option;
use Rector\FileSystem\FileGuard;
use Rector\Utils\FilesystemTweaker;
use Symfony\Component\Console\Input\InputInterface;
use Symplify\PackageBuilder\FileSystem\FileSystem;
/**
* Should it pass autoload files/directories to PHPStan analyzer?
@ -21,12 +22,7 @@ final class AdditionalAutoloader
/**
* @var string[]
*/
private $autoloadFiles = [];
/**
* @var string[]
*/
private $autoloadDirectories = [];
private $autoloadPaths = [];
/**
* @var FilesystemTweaker
@ -39,21 +35,25 @@ final class AdditionalAutoloader
private $excludePaths = [];
/**
* @param string[] $autoloadFiles
* @param string[] $autoloadDirectories
* @var FileSystem
*/
private $fileSystem;
/**
* @param string[] $autoloadPaths
* @param string[] $excludePaths
*/
public function __construct(
array $autoloadFiles,
array $autoloadDirectories,
FileGuard $fileGuard,
FilesystemTweaker $filesystemTweaker,
FileSystem $fileSystem,
array $autoloadPaths,
array $excludePaths
) {
$this->autoloadFiles = $autoloadFiles;
$this->autoloadDirectories = $autoloadDirectories;
$this->fileGuard = $fileGuard;
$this->filesystemTweaker = $filesystemTweaker;
$this->fileSystem = $fileSystem;
$this->autoloadPaths = $autoloadPaths;
$this->excludePaths = $excludePaths;
}
@ -62,9 +62,11 @@ final class AdditionalAutoloader
*/
public function autoloadWithInputAndSource(InputInterface $input, array $source): void
{
[$autoloadFiles, $autoloadDirectories] = $this->fileSystem->separateFilesAndDirectories($this->autoloadPaths);
$this->autoloadFileFromInput($input);
$this->autoloadDirectories($this->autoloadDirectories);
$this->autoloadFiles($this->autoloadFiles);
$this->autoloadDirectories($autoloadDirectories);
$this->autoloadFiles($autoloadFiles);
[$files, $directories] = $this->filesystemTweaker->splitSourceToDirectoriesAndFiles($source);
$this->autoloadFiles($files);

View File

@ -264,7 +264,7 @@ final class ProcessCommand extends Command
}
$message = sprintf(
'Analyze error: %s Try to include your files in "parameters > autoload_files" or "parameters > autoload_directories".%sSee https://github.com/rectorphp/rector#extra-autoloading',
'Analyze error: %s Try to include your files in "parameters > autoload_paths".%sSee https://github.com/rectorphp/rector#extra-autoloading',
$analysedCodeException->getMessage(),
PHP_EOL
);

View File

@ -3,10 +3,22 @@
namespace Rector\DependencyInjection;
use Psr\Container\ContainerInterface;
use Rector\ParameterGuider\ParameterGuider;
use Symfony\Component\DependencyInjection\Container;
use function Safe\putenv;
final class ContainerFactory
{
/**
* @var ParameterGuider
*/
private $parameterGuider;
public function __construct()
{
$this->parameterGuider = new ParameterGuider();
}
public function create(): ContainerInterface
{
$appKernel = new RectorKernel();
@ -14,7 +26,12 @@ final class ContainerFactory
// this is require to keep CLI verbosity independent on AppKernel dev/prod mode
putenv('SHELL_VERBOSITY=0');
return $appKernel->getContainer();
/** @var Container $container */
$container = $appKernel->getContainer();
$this->parameterGuider->processParameters($container->getParameterBag());
return $container;
}
/**
@ -27,6 +44,11 @@ final class ContainerFactory
// this is require to keep CLI verbosity independent on AppKernel dev/prod mode
putenv('SHELL_VERBOSITY=0');
return $appKernel->getContainer();
/** @var Container $container */
$container = $appKernel->getContainer();
$this->parameterGuider->processParameters($container->getParameterBag());
return $container;
}
}

View File

@ -1,9 +1,10 @@
imports:
- { resource: '../../packages/**/src/config/config.yml' }
# new config location
- { resource: '../../packages/**/config/config.yml' }
- { resource: 'services.yml' }
- { resource: 'external-services.yml' }
parameters:
exclude_paths: []
autoload_directories: []
autoload_files: []
autoload_paths: []

View File

@ -27,3 +27,4 @@ services:
alias: Symfony\Component\Console\Output\ConsoleOutput
Symplify\PackageBuilder\Parameter\ParameterProvider: ~
Symplify\PackageBuilder\FileSystem\FileSystem: ~

View File

@ -9,3 +9,6 @@ services:
# extra services
Rector\Symfony\Rector\Form\Helper\FormTypeStringToTypeProvider: ~
Symfony\Component\Console\Application:
alias: 'Rector\Console\Application'