Skip to content

Commit 97f9fa5

Browse files
authored
[make:*] use php-cs-fixer to style/lint all generated php templates (#1251)
1 parent 584a06e commit 97f9fa5

File tree

15 files changed

+401
-66
lines changed

15 files changed

+401
-66
lines changed

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"symfony/filesystem": "^5.4.7|^6.0",
2424
"symfony/finder": "^5.4.3|^6.0",
2525
"symfony/framework-bundle": "^5.4.7|^6.0",
26-
"symfony/http-kernel": "^5.4.7|^6.0"
26+
"symfony/http-kernel": "^5.4.7|^6.0",
27+
"symfony/process": "^5.4.7|^6.0"
2728
},
2829
"require-dev": {
2930
"composer/semver": "^3.0",
@@ -32,7 +33,6 @@
3233
"symfony/http-client": "^5.4.7|^6.0",
3334
"symfony/phpunit-bridge": "^5.4.7|^6.0",
3435
"symfony/polyfill-php80": "^1.16.0",
35-
"symfony/process": "^5.4.7|^6.0",
3636
"symfony/security-core": "^5.4.7|^6.0",
3737
"symfony/yaml": "^5.4.3|^6.0",
3838
"twig/twig": "^2.0|^3.0"

src/Command/MakerCommand.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Bundle\MakerBundle\Generator;
2020
use Symfony\Bundle\MakerBundle\InputConfiguration;
2121
use Symfony\Bundle\MakerBundle\MakerInterface;
22+
use Symfony\Bundle\MakerBundle\Util\TemplateLinter;
2223
use Symfony\Bundle\MakerBundle\Validator;
2324
use Symfony\Component\Console\Application;
2425
use Symfony\Component\Console\Command\Command;
@@ -36,8 +37,12 @@ final class MakerCommand extends Command
3637
private ConsoleStyle $io;
3738
private bool $checkDependencies = true;
3839

39-
public function __construct(private MakerInterface $maker, private FileManager $fileManager, private Generator $generator)
40-
{
40+
public function __construct(
41+
private MakerInterface $maker,
42+
private FileManager $fileManager,
43+
private Generator $generator,
44+
private TemplateLinter $linter,
45+
) {
4146
$this->inputConfig = new InputConfiguration();
4247

4348
parent::__construct();
@@ -90,13 +95,19 @@ protected function interact(InputInterface $input, OutputInterface $output): voi
9095

9196
protected function execute(InputInterface $input, OutputInterface $output): int
9297
{
98+
if ($output->isVerbose()) {
99+
$this->linter->writeLinterMessage($output);
100+
}
101+
93102
$this->maker->generate($input, $this->io, $this->generator);
94103

95104
// sanity check for custom makers
96105
if ($this->generator->hasPendingOperations()) {
97106
throw new \LogicException('Make sure to call the writeChanges() method on the generator.');
98107
}
99108

109+
$this->linter->lintFiles($this->generator->getGeneratedFiles());
110+
100111
return 0;
101112
}
102113

src/Generator.php

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class Generator
2626
private GeneratorTwigHelper $twigHelper;
2727
private array $pendingOperations = [];
2828
private ?TemplateComponentGenerator $templateComponentGenerator;
29+
private array $generatedFiles = [];
2930

3031
public function __construct(
3132
private FileManager $fileManager,
@@ -74,6 +75,8 @@ public function generateClass(string $className, string $templateName, array $va
7475

7576
/**
7677
* Generate a normal file from a template.
78+
*
79+
* @return void
7780
*/
7881
public function generateFile(string $targetPath, string $templateName, array $variables = [])
7982
{
@@ -84,6 +87,9 @@ public function generateFile(string $targetPath, string $templateName, array $va
8487
$this->addOperation($targetPath, $templateName, $variables);
8588
}
8689

90+
/**
91+
* @return void
92+
*/
8793
public function dumpFile(string $targetPath, string $contents)
8894
{
8995
$this->pendingOperations[$targetPath] = [
@@ -160,29 +166,6 @@ public function getRootDirectory(): string
160166
return $this->fileManager->getRootDirectory();
161167
}
162168

163-
private function addOperation(string $targetPath, string $templateName, array $variables): void
164-
{
165-
if ($this->fileManager->fileExists($targetPath)) {
166-
throw new RuntimeCommandException(sprintf('The file "%s" can\'t be generated because it already exists.', $this->fileManager->relativizePath($targetPath)));
167-
}
168-
169-
$variables['relative_path'] = $this->fileManager->relativizePath($targetPath);
170-
171-
$templatePath = $templateName;
172-
if (!file_exists($templatePath)) {
173-
$templatePath = __DIR__.'/Resources/skeleton/'.$templateName;
174-
175-
if (!file_exists($templatePath)) {
176-
throw new \Exception(sprintf('Cannot find template "%s"', $templateName));
177-
}
178-
}
179-
180-
$this->pendingOperations[$targetPath] = [
181-
'template' => $templatePath,
182-
'variables' => $variables,
183-
];
184-
}
185-
186169
public function hasPendingOperations(): bool
187170
{
188171
return !empty($this->pendingOperations);
@@ -196,6 +179,8 @@ public function hasPendingOperations(): bool
196179
public function writeChanges()
197180
{
198181
foreach ($this->pendingOperations as $targetPath => $templateData) {
182+
$this->generatedFiles[] = $targetPath;
183+
199184
if (isset($templateData['contents'])) {
200185
$this->fileManager->dumpFile($targetPath, $templateData['contents']);
201186

@@ -204,7 +189,7 @@ public function writeChanges()
204189

205190
$this->fileManager->dumpFile(
206191
$targetPath,
207-
$this->getFileContentsForPendingOperation($targetPath, $templateData)
192+
$this->getFileContentsForPendingOperation($targetPath)
208193
);
209194
}
210195

@@ -242,6 +227,14 @@ public function generateTemplate(string $targetPath, string $templateName, array
242227
);
243228
}
244229

230+
/**
231+
* Get the full path of each file created by the Generator.
232+
*/
233+
public function getGeneratedFiles(): array
234+
{
235+
return $this->generatedFiles;
236+
}
237+
245238
/**
246239
* @deprecated MakerBundle only supports AbstractController::class. This method will be removed in the future.
247240
*/
@@ -251,4 +244,27 @@ public static function getControllerBaseClass(): ClassNameDetails
251244

252245
return new ClassNameDetails(AbstractController::class, '\\');
253246
}
247+
248+
private function addOperation(string $targetPath, string $templateName, array $variables): void
249+
{
250+
if ($this->fileManager->fileExists($targetPath)) {
251+
throw new RuntimeCommandException(sprintf('The file "%s" can\'t be generated because it already exists.', $this->fileManager->relativizePath($targetPath)));
252+
}
253+
254+
$variables['relative_path'] = $this->fileManager->relativizePath($targetPath);
255+
256+
$templatePath = $templateName;
257+
if (!file_exists($templatePath)) {
258+
$templatePath = __DIR__.'/Resources/skeleton/'.$templateName;
259+
260+
if (!file_exists($templatePath)) {
261+
throw new \Exception(sprintf('Cannot find template "%s"', $templateName));
262+
}
263+
}
264+
265+
$this->pendingOperations[$targetPath] = [
266+
'template' => $templatePath,
267+
'variables' => $variables,
268+
];
269+
}
254270
}
2.56 MB
Binary file not shown.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
return (new PhpCsFixer\Config())
13+
->setRules([
14+
'@Symfony' => true,
15+
'@Symfony:risky' => true,
16+
'native_function_invocation' => false,
17+
'blank_line_before_statement' => ['statements' => ['break', 'case', 'continue', 'declare', 'default', 'do', 'exit', 'for', 'foreach', 'goto', 'if', 'include', 'include_once', 'phpdoc', 'require', 'require_once', 'return', 'switch', 'throw', 'try', 'while', 'yield', 'yield_from']],
18+
])
19+
->setRiskyAllowed(true)
20+
;

src/Resources/config/services.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,16 @@
4040
<argument type="service" id="doctrine" on-invalid="ignore" />
4141
</service>
4242

43+
<service id="maker.template_linter" class="Symfony\Bundle\MakerBundle\Util\TemplateLinter">
44+
<argument>%env(default::string:MAKER_PHP_CS_FIXER_BINARY_PATH)%</argument>
45+
<argument>%env(default::string:MAKER_PHP_CS_FIXER_CONFIG_PATH)%</argument>
46+
</service>
47+
4348
<service id="maker.auto_command.abstract" class="Symfony\Bundle\MakerBundle\Command\MakerCommand" abstract="true">
4449
<argument /> <!-- maker -->
4550
<argument type="service" id="maker.file_manager" />
4651
<argument type="service" id="maker.generator" />
52+
<argument type="service" id="maker.template_linter" />
4753
</service>
4854

4955
<service id="maker.generator" class="Symfony\Bundle\MakerBundle\Generator">

src/Resources/doc/index.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,27 @@ optional arguments and options. Check them out with the ``--help`` option:
4343
4444
$ php bin/console make:controller --help
4545
46+
47+
Linting Generated Code
48+
______________________
49+
50+
MakerBundle uses php-cs-fixer to enforce coding standards when generating ``.php``
51+
files. When running a ``make`` command, MakerBundle will use a ``php-cs-fixer``
52+
version and configuration that is packaged with this bundle.
53+
54+
You can explicitly set a custom path to a php-cs-fixer binary and/or configuration
55+
file by their respective environment variables:
56+
57+
- ``MAKER_PHP_CS_FIXER_BINARY_PATH`` e.g. tools/vendor/bin/php-cs-fixer
58+
- ``MAKER_PHP_CS_FIXER_CONFIG_PATH`` e.g. .php-cs-fixer.config.php
59+
60+
61+
.. tip::
62+
63+
Is PHP-CS-Fixer installed globally? To avoid needing to set these in every
64+
project, you can instead set these on your operating system.
65+
66+
4667
Configuration
4768
-------------
4869

src/Resources/test/.php_cs.test

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/Test/MakerTestCase.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,6 @@ protected function executeMakerCommand(MakerTestDetails $testDetails)
7777
foreach ($files as $file) {
7878
$this->assertTrue($testEnv->fileExists($file), sprintf('The file "%s" does not exist after generation', $file));
7979

80-
if (str_ends_with($file, '.php')) {
81-
$csProcess = $testEnv->runPhpCSFixer($file);
82-
83-
$this->assertTrue($csProcess->isSuccessful(), sprintf(
84-
"File '%s' has a php-cs problem: %s\n",
85-
$file,
86-
$csProcess->getErrorOutput()."\n".$csProcess->getOutput()
87-
));
88-
}
89-
9080
if (str_ends_with($file, '.twig')) {
9181
$csProcess = $testEnv->runTwigCSLint($file);
9282

src/Test/MakerTestEnvironment.php

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -216,19 +216,6 @@ public function fileExists(string $file): bool
216216
return $this->fs->exists($this->path.'/'.$file);
217217
}
218218

219-
public function runPhpCSFixer(string $file): MakerTestProcess
220-
{
221-
if (!file_exists(__DIR__.'/../../tools/php-cs-fixer/vendor/bin/php-cs-fixer')) {
222-
throw new \Exception('php-cs-fixer not found: run: "composer install --working-dir=tools/php-cs-fixer".');
223-
}
224-
225-
return MakerTestProcess::create(
226-
sprintf('php tools/php-cs-fixer/vendor/bin/php-cs-fixer --config=%s fix --dry-run --diff %s', __DIR__.'/../Resources/test/.php_cs.test', $this->path.'/'.$file),
227-
$this->rootPath,
228-
['PHP_CS_FIXER_IGNORE_ENV' => '1']
229-
)->run(true);
230-
}
231-
232219
public function runTwigCSLint(string $file): MakerTestProcess
233220
{
234221
if (!file_exists(__DIR__.'/../../tools/twigcs/vendor/bin/twigcs')) {

0 commit comments

Comments
 (0)