Skip to content

Commit 5c5fd4d

Browse files
SanderMullerclaude
andauthored
refactor: extract AutoloadFileParameterResolver from bin, add tests (#8035)
Follow-up to #8034, which merged before its last revision: the parameter registration moves from inline bin code into a unit-testable class. Tests pin that every CLI spelling (--autoload-file path, --autoload-file=path, -a path) resolves to the same real path, that the parameter stays untouched without the flag, and that registering it changes FileHashComputer's configuration hash. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 1f43c36 commit 5c5fd4d

4 files changed

Lines changed: 117 additions & 8 deletions

File tree

‎bin/rector.php‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
declare(strict_types=1);
44

55
use Nette\Utils\Json;
6+
use Rector\Bootstrap\AutoloadFileParameterResolver;
67
use Rector\Bootstrap\RectorConfigsResolver;
78
use Rector\ChangesReporting\Output\JsonOutputFormatter;
89
use Rector\Configuration\Option;
9-
use Rector\Configuration\Parameter\SimpleParameterProvider;
1010
use Rector\Console\Style\SymfonyStyleFactory;
1111
use Rector\DependencyInjection\LazyContainerFactory;
1212
use Rector\DependencyInjection\RectorContainerFactory;
@@ -128,13 +128,7 @@ public function loadIfExistsAndNotLoadedYet(string $filePath): void
128128
$autoloadIncluder->autoloadRectorInstalledAsGlobalDependency();
129129
$autoloadIncluder->autoloadFromCommandLine();
130130

131-
// a different extra autoload changes what PHPStan can resolve, so cached results
132-
// must not survive it: register it before the configuration hash is computed.
133-
// ArgvInput handles both "--autoload-file path" and "--autoload-file=path"
134-
$autoloadFileOption = (new ArgvInput())->getParameterOption(['--autoload-file', '-a'], null);
135-
if (is_string($autoloadFileOption) && $autoloadFileOption !== '') {
136-
SimpleParameterProvider::setParameter(Option::AUTOLOAD_FILE, realpath($autoloadFileOption) ?: $autoloadFileOption);
137-
}
131+
AutoloadFileParameterResolver::resolveFromArgv($_SERVER['argv']);
138132

139133
$rectorConfigsResolver = new RectorConfigsResolver();
140134

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Bootstrap;
6+
7+
use Rector\Configuration\Option;
8+
use Rector\Configuration\Parameter\SimpleParameterProvider;
9+
use Symfony\Component\Console\Input\ArgvInput;
10+
11+
/**
12+
* A different extra autoload changes what PHPStan can resolve, so cached results
13+
* must not survive it. Registering the file as a parameter folds it into the
14+
* configuration hash, which invalidates the cache like any other config change.
15+
*
16+
* Called from bin/rector.php before the configuration hash is computed.
17+
*
18+
* @see \Rector\Tests\Bootstrap\AutoloadFileParameterResolverTest
19+
*/
20+
final class AutoloadFileParameterResolver
21+
{
22+
/**
23+
* @param array<int, mixed> $argv
24+
*/
25+
public static function resolveFromArgv(array $argv): void
26+
{
27+
// handles "--autoload-file path", "--autoload-file=path" and "-a path";
28+
// parallel workers receive the space-separated form, so all spellings must
29+
// normalize to the same value or main process and workers would disagree
30+
$autoloadFile = (new ArgvInput($argv))->getParameterOption(['--autoload-file', '-a'], null);
31+
if (! is_string($autoloadFile) || $autoloadFile === '') {
32+
return;
33+
}
34+
35+
SimpleParameterProvider::setParameter(Option::AUTOLOAD_FILE, realpath($autoloadFile) ?: $autoloadFile);
36+
}
37+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\Bootstrap;
6+
7+
use PHPUnit\Framework\Attributes\DataProvider;
8+
use PHPUnit\Framework\TestCase;
9+
use Rector\Bootstrap\AutoloadFileParameterResolver;
10+
use Rector\Caching\Config\FileHashComputer;
11+
use Rector\Configuration\Option;
12+
use Rector\Configuration\Parameter\SimpleParameterProvider;
13+
14+
final class AutoloadFileParameterResolverTest extends TestCase
15+
{
16+
protected function setUp(): void
17+
{
18+
SimpleParameterProvider::setParameter(Option::AUTOLOAD_FILE, '');
19+
}
20+
21+
/**
22+
* all spellings must resolve to the same value, or the main process and
23+
* parallel workers, which receive the space-separated form, would compute
24+
* different configuration hashes
25+
*
26+
* @param array<int, string> $argv
27+
*/
28+
#[DataProvider('provideArgvSpellings')]
29+
public function testEverySpellingResolvesToSameRealPath(array $argv): void
30+
{
31+
AutoloadFileParameterResolver::resolveFromArgv($argv);
32+
33+
$this->assertSame(
34+
(string) realpath(__FILE__),
35+
SimpleParameterProvider::provideStringParameter(Option::AUTOLOAD_FILE)
36+
);
37+
}
38+
39+
/**
40+
* @return iterable<string, array{array<int, string>}>
41+
*/
42+
public static function provideArgvSpellings(): iterable
43+
{
44+
$relativePath = 'tests/Bootstrap/' . basename(__FILE__);
45+
46+
yield 'long with space' => [['bin/rector', 'process', '--autoload-file', __FILE__]];
47+
yield 'long with equals' => [['bin/rector', 'process', '--autoload-file=' . __FILE__]];
48+
yield 'short with space' => [['bin/rector', 'process', '-a', __FILE__]];
49+
yield 'relative path is normalized' => [['bin/rector', 'process', '-a', $relativePath]];
50+
}
51+
52+
public function testWithoutOptionParameterStaysUntouched(): void
53+
{
54+
AutoloadFileParameterResolver::resolveFromArgv(['bin/rector', 'process', '--dry-run']);
55+
56+
$this->assertSame('', SimpleParameterProvider::provideStringParameter(Option::AUTOLOAD_FILE));
57+
}
58+
59+
public function testResolvedAutoloadFileChangesConfigurationHash(): void
60+
{
61+
$fileHashComputer = new FileHashComputer();
62+
$configFilePath = __DIR__ . '/config/some_config.php';
63+
64+
$hashWithout = $fileHashComputer->compute($configFilePath);
65+
66+
AutoloadFileParameterResolver::resolveFromArgv(['bin/rector', 'process', '-a', __FILE__]);
67+
68+
$this->assertNotSame($hashWithout, $fileHashComputer->compute($configFilePath));
69+
}
70+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\Config\RectorConfig;
6+
7+
return static function (RectorConfig $rectorConfig): void {
8+
};

0 commit comments

Comments
 (0)