Add bootstrap files option to allow including files (#5964)

This commit is contained in:
Tomas Votruba 2021-03-23 19:53:39 +01:00 committed by GitHub
parent f34a883d7d
commit 60b58421e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 9 deletions

View File

@ -9,7 +9,7 @@ Rector helps you with 2 areas - major code changes and in daily work.
- Do you have a legacy code base? Do you want to have that latest version of PHP or your favorite framework?
**Rector gets you there with instant upgrade**.
<br>
<br>
- Do you have code quality you need, but struggle to keep it with new developers in your team? Do you wish to have code-reviews for each member of your team, but don't have time for it?
→ **Add Rector to you CI and let it fix your code for you. Get [instant feedback](https://tomasvotruba.com/blog/2020/01/13/why-is-first-instant-feedback-crucial-to-developers/) after each commit.**
@ -157,12 +157,18 @@ return static function (ContainerConfigurator $containerConfigurator): void {
// paths to refactor; solid alternative to CLI arguments
$parameters->set(Option::PATHS, [__DIR__ . '/src', __DIR__ . '/tests']);
// Rector relies on autoload setup of your project; Composer autoload is included by default; to add more:
// Rector is static reflection to load code without running it - see https://phpstan.org/blog/zero-config-analysis-with-static-reflection
$parameters->set(Option::AUTOLOAD_PATHS, [
// autoload specific file
__DIR__ . '/vendor/squizlabs/php_codesniffer/autoload.php',
__DIR__ . '/file-with-functions.php',
// or full directory
__DIR__ . '/vendor/project-without-composer',
__DIR__ . '/project-without-composer',
]);
// do you need to include constants, class aliases or custom autoloader? files listed will be executed
$parameters->set(Option::BOOTSTRAP_FILES, [
__DIR__ . '/constants.php',
__DIR__ . '/project/special/autoload.php',
]);
// is your PHP version different from the one your refactor to? [default: your PHP version], uses PHP_VERSION_ID format

View File

@ -14,6 +14,9 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$parameters->set(Option::FILE_EXTENSIONS, ['php']);
$parameters->set(Option::AUTOLOAD_PATHS, []);
// these files will be executed, useful e.g. for constant definitions
$parameters->set(Option::BOOTSTRAP_FILES, []);
// FQN class importing
$parameters->set(Option::AUTO_IMPORT_NAMES, false);
$parameters->set(Option::IMPORT_SHORT_CLASSES, true);

View File

@ -87,9 +87,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(RemoveInterfacesRector::class)
->call('configure', [[
RemoveInterfacesRector::INTERFACES_TO_REMOVE => [
'League\Event\EventInterface',
]
RemoveInterfacesRector::INTERFACES_TO_REMOVE => ['League\Event\EventInterface'],
]]);
$services->set(RemoveParentRector::class)
@ -98,6 +96,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
'League\Event\AbstractEvent',
'League\Event\Event',
'League\Event\AbstractListener',
]
],
]]);
};

View File

@ -18,6 +18,11 @@ final class Option
*/
public const OPTION_AUTOLOAD_FILE = 'autoload-file';
/**
* @var string
*/
public const BOOTSTRAP_FILES = 'bootstrap_files';
/**
* @var string
*/

View File

@ -28,6 +28,8 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symplify\PackageBuilder\Console\ShellCode;
use Symplify\PackageBuilder\Parameter\ParameterProvider;
use Throwable;
final class ProcessCommand extends Command
{
@ -96,6 +98,11 @@ final class ProcessCommand extends Command
*/
private $missingRectorRulesReporter;
/**
* @var ParameterProvider
*/
private $parameterProvider;
public function __construct(
AdditionalAutoloader $additionalAutoloader,
ChangedFilesDetector $changedFilesDetector,
@ -109,7 +116,8 @@ final class ProcessCommand extends Command
SymfonyStyle $symfonyStyle,
ComposerProcessor $composerProcessor,
PhpFilesFinder $phpFilesFinder,
MissingRectorRulesReporter $missingRectorRulesReporter
MissingRectorRulesReporter $missingRectorRulesReporter,
ParameterProvider $parameterProvider
) {
$this->filesFinder = $filesFinder;
$this->additionalAutoloader = $additionalAutoloader;
@ -126,6 +134,7 @@ final class ProcessCommand extends Command
$this->missingRectorRulesReporter = $missingRectorRulesReporter;
parent::__construct();
$this->parameterProvider = $parameterProvider;
}
protected function configure(): void
@ -201,6 +210,8 @@ final class ProcessCommand extends Command
$paths = $this->configuration->getPaths();
$phpFileInfos = $this->phpFilesFinder->findInPaths($paths);
// register autoloaded and included files
$this->includeBootstrapFiles();
$this->additionalAutoloader->autoloadWithInputAndSource($input);
if ($this->configuration->isCacheDebug()) {
@ -307,4 +318,34 @@ final class ProcessCommand extends Command
$this->changedFilesDetector->invalidateFile($affectedFileInfo);
}
}
/**
* Inspired by
* @see https://github.com/phpstan/phpstan-src/commit/aad1bf888ab7b5808898ee5fe2228bb8bb4e4cf1
*/
private function includeBootstrapFiles(): void
{
$bootstrapFiles = $this->parameterProvider->provideArrayParameter(Option::BOOTSTRAP_FILES);
foreach ($bootstrapFiles as $bootstrapFile) {
if (! is_file($bootstrapFile)) {
throw new ShouldNotHappenException('Bootstrap file %s does not exist.', $bootstrapFile);
}
try {
require_once $bootstrapFile;
} catch (Throwable $throwable) {
$errorMessage = sprintf(
'"%s" thrown in "%s" on line %d while loading bootstrap file %s: %s',
get_class($throwable),
$throwable->getFile(),
$throwable->getLine(),
$bootstrapFile,
$throwable->getMessage()
);
throw new ShouldNotHappenException($errorMessage);
}
}
}
}