diff --git a/bin/rector.php b/bin/rector.php index 532970222d8..93ac35ec2d3 100755 --- a/bin/rector.php +++ b/bin/rector.php @@ -116,10 +116,8 @@ public function loadIfExistsAndNotLoadedYet(string $filePath): void if (file_exists(__DIR__ . '/../preload.php') && is_dir(__DIR__ . '/../vendor')) { require_once __DIR__ . '/../preload.php'; -} - -// require rector-src on split packages -if (file_exists(__DIR__ . '/../preload-split-package.php') && is_dir(__DIR__ . '/../../../../vendor')) { +} elseif (file_exists(__DIR__ . '/../preload-split-package.php') && is_dir(__DIR__ . '/../../../../vendor')) { + // rector-src on split packages require_once __DIR__ . '/../preload-split-package.php'; } diff --git a/tests/Bin/PreloadTest.php b/tests/Bin/PreloadTest.php new file mode 100644 index 00000000000..fb56d78f209 --- /dev/null +++ b/tests/Bin/PreloadTest.php @@ -0,0 +1,51 @@ +rootDirectory)) { + return; + } + + $process = Process::fromShellCommandline('rm -rf ' . escapeshellarg($this->rootDirectory)); + $process->run(); + } + + /** + * bin/rector.php picks a preload file from two conditions: "I have my own vendor/", so a + * monorepo checkout, and "I sit inside a project's vendor/". A checkout with its own vendor/ + * that also happens to be three levels below another vendor/ answers yes to both. Both preload + * files declare isPHPStanTestPreloaded(), so loading both is a fatal error. + */ + public function testPicksOnePreloadFileWhenBothConditionsHold(): void + { + $this->rootDirectory = sys_get_temp_dir() . '/rector-preload-test-' . uniqid(); + $repositoryDirectory = $this->rootDirectory . '/a/b/c/repo'; + mkdir($repositoryDirectory . '/bin', 0777, true); + + $vendorDirectory = realpath(__DIR__ . '/../../vendor'); + // the first condition, and the paths preload.php requires + symlink($vendorDirectory, $repositoryDirectory . '/vendor'); + // the second condition, and the paths preload-split-package.php requires + symlink($vendorDirectory, $this->rootDirectory . '/a/vendor'); + + foreach (['bin/rector.php', 'preload.php', 'preload-split-package.php'] as $relativeFilePath) { + copy(__DIR__ . '/../../' . $relativeFilePath, $repositoryDirectory . '/' . $relativeFilePath); + } + + $process = Process::fromShellCommandline(PHP_BINARY . ' bin/rector.php --version', $repositoryDirectory); + $process->run(); + + $this->assertStringNotContainsString('Cannot redeclare', $process->getErrorOutput()); + } +}