diff --git a/composer.json b/composer.json index 3b9010d17..df1c451ba 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ "php": ">=8.1", "doctrine/inflector": "^2.0", "nikic/php-parser": "^4.18|^5.0", + "php-cs-fixer/shim": "^v3.64", "symfony/config": "^6.4|^7.0", "symfony/console": "^6.4|^7.0", "symfony/dependency-injection": "^6.4|^7.0", diff --git a/src/Resources/bin/php-cs-fixer-v3.49.0.phar b/src/Resources/bin/php-cs-fixer-v3.49.0.phar deleted file mode 100755 index cbbbe5834..000000000 Binary files a/src/Resources/bin/php-cs-fixer-v3.49.0.phar and /dev/null differ diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 5fbc0439b..8f0b2a209 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -41,6 +41,7 @@ + %env(default::string:MAKER_PHP_CS_FIXER_BINARY_PATH)% %env(default::string:MAKER_PHP_CS_FIXER_CONFIG_PATH)% diff --git a/src/Util/TemplateLinter.php b/src/Util/TemplateLinter.php index 1d29d195d..e6bb70328 100644 --- a/src/Util/TemplateLinter.php +++ b/src/Util/TemplateLinter.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\MakerBundle\Util; use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException; +use Symfony\Bundle\MakerBundle\FileManager; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\ExecutableFinder; use Symfony\Component\Process\Process; @@ -25,14 +26,12 @@ */ final class TemplateLinter { - // Version must match bundled version file name. e.g. php-cs-fixer-v3.49.9.phar - public const BUNDLED_PHP_CS_FIXER_VERSION = '3.49.0'; - private bool $usingBundledPhpCsFixer = true; private bool $usingBundledPhpCsFixerConfig = true; private bool $needsPhpCmdPrefix = true; public function __construct( + private FileManager $fileManager, private ?string $phpCsFixerBinaryPath = null, private ?string $phpCsFixerConfigPath = null, ) { @@ -98,9 +97,15 @@ public function writeLinterMessage(OutputInterface $output): void private function setBinary(): void { - // Use Bundled PHP-CS-Fixer + // Use Bundled (shim) PHP-CS-Fixer if (null === $this->phpCsFixerBinaryPath) { - $this->phpCsFixerBinaryPath = \sprintf('%s/Resources/bin/php-cs-fixer-v%s.phar', \dirname(__DIR__), self::BUNDLED_PHP_CS_FIXER_VERSION); + $shimLocation = \sprintf('%s/vendor/bin/php-cs-fixer', \dirname(__DIR__, 2)); + + if (is_file($shimLocation)) { + $this->phpCsFixerBinaryPath = $shimLocation; + + return; + } return; } @@ -129,7 +134,8 @@ private function setBinary(): void private function setConfig(): void { // No config provided, but there is a dist config file in the project dir - if (null === $this->phpCsFixerConfigPath && file_exists($defaultConfigPath = '.php-cs-fixer.dist.php')) { + $defaultConfigPath = \sprintf('%s/.php-cs-fixer.dist.php', $this->fileManager->getRootDirectory()); + if (null === $this->phpCsFixerConfigPath && file_exists($defaultConfigPath)) { $this->phpCsFixerConfigPath = $defaultConfigPath; $this->usingBundledPhpCsFixerConfig = false; diff --git a/tests/Command/MakerCommandTest.php b/tests/Command/MakerCommandTest.php index 06aa9823d..d52b2d723 100644 --- a/tests/Command/MakerCommandTest.php +++ b/tests/Command/MakerCommandTest.php @@ -40,7 +40,7 @@ public function testExceptionOnMissingDependencies(): void $fileManager = $this->createMock(FileManager::class); - $command = new MakerCommand($maker, $fileManager, new Generator($fileManager, 'App'), new TemplateLinter()); + $command = new MakerCommand($maker, $fileManager, new Generator($fileManager, 'App'), new TemplateLinter($fileManager)); // needed because it's normally set by the Application $command->setName('make:foo'); $tester = new CommandTester($command); @@ -53,7 +53,7 @@ public function testExceptionOnUnknownRootNamespace(): void $fileManager = $this->createMock(FileManager::class); - $command = new MakerCommand($maker, $fileManager, new Generator($fileManager, 'Unknown'), new TemplateLinter()); + $command = new MakerCommand($maker, $fileManager, new Generator($fileManager, 'Unknown'), new TemplateLinter($fileManager)); // needed because it's normally set by the Application $command->setName('make:foo'); $tester = new CommandTester($command); diff --git a/tests/Maker/TemplateLinterTest.php b/tests/Maker/TemplateLinterTest.php index cf14850ab..2747bb033 100644 --- a/tests/Maker/TemplateLinterTest.php +++ b/tests/Maker/TemplateLinterTest.php @@ -33,7 +33,6 @@ protected function getMakerClass(): string public function getTestDetails(): \Generator { yield 'lints_templates_with_custom_php_cs_fixer_and_config' => [$this->createMakerTest() - ->addExtraDependencies('php-cs-fixer/shim') ->run(function (MakerTestRunner $runner) { $runner->copy('template-linter/php-cs-fixer.test.php', 'php-cs-fixer.test.php'); @@ -53,13 +52,12 @@ public function getTestDetails(): \Generator self::assertStringContainsString('Linted by custom php-cs-config', $generatedTemplate); - $expectedOutput = 'System PHP-CS-Fixer (bin/php-cs-fixer) & System PHP-CS-Fixer Configuration (php-cs-fixer.test.php)'; + $expectedOutput = 'System PHP-CS-Fixer (bin/php-cs-fixer) & System PHP-CS-Fixer Configuration'; self::assertStringContainsString($expectedOutput, $output); }), ]; yield 'lints_templates_with_flex_generated_config_file' => [$this->createMakerTest() - ->addExtraDependencies('php-cs-fixer/shim') ->run(function (MakerTestRunner $runner) { $runner->replaceInFile( '.php-cs-fixer.dist.php', @@ -79,13 +77,14 @@ public function getTestDetails(): \Generator self::assertStringContainsString('Linted with stock php-cs-config', $generatedTemplate); - $expectedOutput = 'Bundled PHP-CS-Fixer & System PHP-CS-Fixer Configuration (.php-cs-fixer.dist.php)'; + $expectedOutput = 'Bundled PHP-CS-Fixer & System PHP-CS-Fixer Configuration'; self::assertStringContainsString($expectedOutput, $output); }), ]; yield 'lints_templates_with_bundled_php_cs_fixer' => [$this->createMakerTest() ->run(function (MakerTestRunner $runner) { + $runner->deleteFile('.php-cs-fixer.dist.php'); // Voter class name $output = $runner->runMaker(['FooBar']); diff --git a/tests/Util/TemplateLinterTest.php b/tests/Util/TemplateLinterTest.php index aca250c4f..f5086b6e7 100644 --- a/tests/Util/TemplateLinterTest.php +++ b/tests/Util/TemplateLinterTest.php @@ -11,7 +11,9 @@ namespace Symfony\Bundle\MakerBundle\Tests\Util; +use Composer\InstalledVersions; use PHPUnit\Framework\TestCase; +use Symfony\Bundle\MakerBundle\FileManager; use Symfony\Bundle\MakerBundle\Util\TemplateLinter; use Symfony\Component\Process\Process; @@ -28,27 +30,30 @@ public function testExceptionBinaryPathDoesntExist(): void { $this->expectExceptionMessage('The MAKER_PHP_CS_FIXER_BINARY_PATH provided: /some/bad/path does not exist.'); - new TemplateLinter(phpCsFixerBinaryPath: '/some/bad/path'); + new TemplateLinter($this->createMock(FileManager::class), phpCsFixerBinaryPath: '/some/bad/path'); } public function testExceptionThrownIfConfigPathDoesntExist(): void { $this->expectExceptionMessage('The MAKER_PHP_CS_FIXER_CONFIG_PATH provided: /bad/config/path does not exist.'); - new TemplateLinter(phpCsFixerConfigPath: '/bad/config/path'); + new TemplateLinter($this->createMock(FileManager::class), phpCsFixerConfigPath: '/bad/config/path'); } public function testPhpCsFixerVersion(): void { $this->markTestSkippedOnWindows(); - $fixerPath = \sprintf('%s/src/Resources/bin/php-cs-fixer-v%s.phar', \dirname(__DIR__, 2), TemplateLinter::BUNDLED_PHP_CS_FIXER_VERSION); + $fixerPath = \sprintf('%s/vendor/php-cs-fixer/shim/php-cs-fixer', \dirname(__DIR__, 2)); + + // Get the installed version and remove the preceding "v" + $expectedVersion = ltrim(InstalledVersions::getPrettyVersion('php-cs-fixer/shim'), 'v'); $process = Process::fromShellCommandline(\sprintf('%s -V', $fixerPath)); $process->run(); - self::assertStringContainsString(TemplateLinter::BUNDLED_PHP_CS_FIXER_VERSION, $process->getOutput()); + self::assertStringContainsString($expectedVersion, $process->getOutput()); } private function markTestSkippedOnWindows(): void diff --git a/tests/fixtures/make-serializer-normalizer/EntityFixtureNormalizer.php b/tests/fixtures/make-serializer-normalizer/EntityFixtureNormalizer.php index 848110fab..4316e3b27 100644 --- a/tests/fixtures/make-serializer-normalizer/EntityFixtureNormalizer.php +++ b/tests/fixtures/make-serializer-normalizer/EntityFixtureNormalizer.php @@ -10,7 +10,7 @@ class EntityFixtureNormalizer implements NormalizerInterface { public function __construct( #[Autowire(service: 'serializer.normalizer.object')] - private NormalizerInterface $normalizer + private NormalizerInterface $normalizer, ) { } diff --git a/tests/fixtures/make-serializer-normalizer/FooBarNormalizer.php b/tests/fixtures/make-serializer-normalizer/FooBarNormalizer.php index 3f253fdbd..8a8c50aaf 100644 --- a/tests/fixtures/make-serializer-normalizer/FooBarNormalizer.php +++ b/tests/fixtures/make-serializer-normalizer/FooBarNormalizer.php @@ -9,7 +9,7 @@ class FooBarNormalizer implements NormalizerInterface { public function __construct( #[Autowire(service: 'serializer.normalizer.object')] - private NormalizerInterface $normalizer + private NormalizerInterface $normalizer, ) { } diff --git a/tests/fixtures/make-validator/expected/FooBar.php b/tests/fixtures/make-validator/expected/FooBar.php index 40bbd5087..239fd8bf1 100644 --- a/tests/fixtures/make-validator/expected/FooBar.php +++ b/tests/fixtures/make-validator/expected/FooBar.php @@ -14,7 +14,7 @@ final class FooBar extends Constraint public function __construct( public string $mode = 'strict', ?array $groups = null, - mixed $payload = null + mixed $payload = null, ) { parent::__construct([], $groups, $payload); } diff --git a/tests/fixtures/make-voter/expected/FooBarVoter.php b/tests/fixtures/make-voter/expected/FooBarVoter.php index 2cfc1ee22..2a2cf060c 100644 --- a/tests/fixtures/make-voter/expected/FooBarVoter.php +++ b/tests/fixtures/make-voter/expected/FooBarVoter.php @@ -22,7 +22,6 @@ protected function supports(string $attribute, mixed $subject): bool protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool { $user = $token->getUser(); - // if the user is anonymous, do not grant access if (!$user instanceof UserInterface) { return false; @@ -34,7 +33,6 @@ protected function voteOnAttribute(string $attribute, mixed $subject, TokenInter // logic to determine if the user can EDIT // return true or false break; - case self::VIEW: // logic to determine if the user can VIEW // return true or false diff --git a/tests/fixtures/make-voter/expected/not_final_FooBarVoter.php b/tests/fixtures/make-voter/expected/not_final_FooBarVoter.php index e38fb4ad2..f67500726 100644 --- a/tests/fixtures/make-voter/expected/not_final_FooBarVoter.php +++ b/tests/fixtures/make-voter/expected/not_final_FooBarVoter.php @@ -22,7 +22,6 @@ protected function supports(string $attribute, mixed $subject): bool protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool { $user = $token->getUser(); - // if the user is anonymous, do not grant access if (!$user instanceof UserInterface) { return false; @@ -34,7 +33,6 @@ protected function voteOnAttribute(string $attribute, mixed $subject, TokenInter // logic to determine if the user can EDIT // return true or false break; - case self::VIEW: // logic to determine if the user can VIEW // return true or false