Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[make:*] use php-cs-fixer to style/lint all generated php templates #1251

Merged
merged 25 commits into from
Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b087e09
[make:*] use php-cs-fixer to lint generated php files
jrushlow Dec 2, 2022
29fc215
php-cs-fixer it up
jrushlow Dec 6, 2022
40a3805
allow user to use their own config and bin
jrushlow Dec 5, 2022
383ef3e
add template linter to command test
jrushlow Dec 6, 2022
ee288c9
assert the linter is working
jrushlow Dec 6, 2022
b6aa002
test linter works in project
jrushlow Dec 8, 2022
be16d93
use default php-cs-config file and binary if it exists
jrushlow Dec 8, 2022
7598e22
better readme
jrushlow Dec 8, 2022
2015522
cleanup
jrushlow Dec 8, 2022
b5695b4
add docs for symfony/doc
jrushlow Dec 8, 2022
71dae37
move the binary to resources
jrushlow Dec 8, 2022
aaa0d31
refactor to track all generated files
jrushlow Dec 9, 2022
21ab33c
use finder to get the php-cs-fixer executable
jrushlow Dec 9, 2022
e1db268
composer can tell us the bin paths
jrushlow Dec 9, 2022
6e8e562
no looking for a global php-cs-fixer
jrushlow Dec 10, 2022
fd02a55
we dont look for the binary anymore
jrushlow Dec 12, 2022
1d523e6
consistency
jrushlow Dec 12, 2022
f622ef2
better docs
jrushlow Dec 14, 2022
6dc6e28
better path eg
jrushlow Dec 14, 2022
68aec4c
no php
jrushlow Dec 14, 2022
e0c4f29
only show linter output if verbose
jrushlow Dec 14, 2022
0a86bf4
refactor linter message
jrushlow Dec 14, 2022
ad2d4f6
let add the ability to use a php-cs-fixer thats in the system path
jrushlow Dec 14, 2022
926a3b3
we no longer need to run php-cs-fixer in all of our tests
jrushlow Dec 14, 2022
d38cf50
ensure we use php prefix on windows
jrushlow Dec 15, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"symfony/filesystem": "^5.4.7|^6.0",
"symfony/finder": "^5.4.3|^6.0",
"symfony/framework-bundle": "^5.4.7|^6.0",
"symfony/http-kernel": "^5.4.7|^6.0"
"symfony/http-kernel": "^5.4.7|^6.0",
"symfony/process": "^5.4.7|^6.0"
},
"require-dev": {
"composer/semver": "^3.0",
Expand All @@ -32,7 +33,6 @@
"symfony/http-client": "^5.4.7|^6.0",
"symfony/phpunit-bridge": "^5.4.7|^6.0",
"symfony/polyfill-php80": "^1.16.0",
"symfony/process": "^5.4.7|^6.0",
"symfony/security-core": "^5.4.7|^6.0",
"symfony/yaml": "^5.4.3|^6.0",
"twig/twig": "^2.0|^3.0"
Expand Down
15 changes: 13 additions & 2 deletions src/Command/MakerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Symfony\Bundle\MakerBundle\Generator;
use Symfony\Bundle\MakerBundle\InputConfiguration;
use Symfony\Bundle\MakerBundle\MakerInterface;
use Symfony\Bundle\MakerBundle\Util\TemplateLinter;
use Symfony\Bundle\MakerBundle\Validator;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
Expand All @@ -36,8 +37,12 @@ final class MakerCommand extends Command
private ConsoleStyle $io;
private bool $checkDependencies = true;

public function __construct(private MakerInterface $maker, private FileManager $fileManager, private Generator $generator)
{
public function __construct(
private MakerInterface $maker,
private FileManager $fileManager,
private Generator $generator,
private TemplateLinter $linter,
) {
$this->inputConfig = new InputConfiguration();

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

protected function execute(InputInterface $input, OutputInterface $output): int
{
if ($output->isVerbose()) {
$this->linter->writeLinterMessage($output);
}

$this->maker->generate($input, $this->io, $this->generator);

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

$this->linter->lintFiles($this->generator->getGeneratedFiles());

return 0;
}

Expand Down
64 changes: 40 additions & 24 deletions src/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Generator
private GeneratorTwigHelper $twigHelper;
private array $pendingOperations = [];
private ?TemplateComponentGenerator $templateComponentGenerator;
private array $generatedFiles = [];

public function __construct(
private FileManager $fileManager,
Expand Down Expand Up @@ -74,6 +75,8 @@ public function generateClass(string $className, string $templateName, array $va

/**
* Generate a normal file from a template.
*
* @return void
*/
public function generateFile(string $targetPath, string $templateName, array $variables = [])
{
Expand All @@ -84,6 +87,9 @@ public function generateFile(string $targetPath, string $templateName, array $va
$this->addOperation($targetPath, $templateName, $variables);
}

/**
* @return void
*/
public function dumpFile(string $targetPath, string $contents)
{
$this->pendingOperations[$targetPath] = [
Expand Down Expand Up @@ -160,29 +166,6 @@ public function getRootDirectory(): string
return $this->fileManager->getRootDirectory();
}

private function addOperation(string $targetPath, string $templateName, array $variables): void
{
if ($this->fileManager->fileExists($targetPath)) {
throw new RuntimeCommandException(sprintf('The file "%s" can\'t be generated because it already exists.', $this->fileManager->relativizePath($targetPath)));
}

$variables['relative_path'] = $this->fileManager->relativizePath($targetPath);

$templatePath = $templateName;
if (!file_exists($templatePath)) {
$templatePath = __DIR__.'/Resources/skeleton/'.$templateName;

if (!file_exists($templatePath)) {
throw new \Exception(sprintf('Cannot find template "%s"', $templateName));
}
}

$this->pendingOperations[$targetPath] = [
'template' => $templatePath,
'variables' => $variables,
];
}

public function hasPendingOperations(): bool
{
return !empty($this->pendingOperations);
Expand All @@ -196,6 +179,8 @@ public function hasPendingOperations(): bool
public function writeChanges()
{
foreach ($this->pendingOperations as $targetPath => $templateData) {
$this->generatedFiles[] = $targetPath;

if (isset($templateData['contents'])) {
$this->fileManager->dumpFile($targetPath, $templateData['contents']);

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

$this->fileManager->dumpFile(
$targetPath,
$this->getFileContentsForPendingOperation($targetPath, $templateData)
$this->getFileContentsForPendingOperation($targetPath)
Comment on lines -207 to +192
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused var unrelated to this pr

);
}

Expand Down Expand Up @@ -242,6 +227,14 @@ public function generateTemplate(string $targetPath, string $templateName, array
);
}

/**
* Get the full path of each file created by the Generator.
*/
public function getGeneratedFiles(): array
{
return $this->generatedFiles;
}

/**
* @deprecated MakerBundle only supports AbstractController::class. This method will be removed in the future.
*/
Expand All @@ -251,4 +244,27 @@ public static function getControllerBaseClass(): ClassNameDetails

return new ClassNameDetails(AbstractController::class, '\\');
}

private function addOperation(string $targetPath, string $templateName, array $variables): void
{
if ($this->fileManager->fileExists($targetPath)) {
throw new RuntimeCommandException(sprintf('The file "%s" can\'t be generated because it already exists.', $this->fileManager->relativizePath($targetPath)));
}

$variables['relative_path'] = $this->fileManager->relativizePath($targetPath);

$templatePath = $templateName;
if (!file_exists($templatePath)) {
$templatePath = __DIR__.'/Resources/skeleton/'.$templateName;

if (!file_exists($templatePath)) {
throw new \Exception(sprintf('Cannot find template "%s"', $templateName));
}
}

$this->pendingOperations[$targetPath] = [
'template' => $templatePath,
'variables' => $variables,
];
}
}
Binary file added src/Resources/bin/php-cs-fixer-v3.13.0.phar
Binary file not shown.
20 changes: 20 additions & 0 deletions src/Resources/config/php-cs-fixer.config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/*
* This file is part of the Symfony MakerBundle package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

return (new PhpCsFixer\Config())
->setRules([
'@Symfony' => true,
'@Symfony:risky' => true,
'native_function_invocation' => false,
'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']],
])
->setRiskyAllowed(true)
;
6 changes: 6 additions & 0 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,16 @@
<argument type="service" id="doctrine" on-invalid="ignore" />
</service>

<service id="maker.template_linter" class="Symfony\Bundle\MakerBundle\Util\TemplateLinter">
<argument>%env(default::string:MAKER_PHP_CS_FIXER_BINARY_PATH)%</argument>
<argument>%env(default::string:MAKER_PHP_CS_FIXER_CONFIG_PATH)%</argument>
</service>

<service id="maker.auto_command.abstract" class="Symfony\Bundle\MakerBundle\Command\MakerCommand" abstract="true">
<argument /> <!-- maker -->
<argument type="service" id="maker.file_manager" />
<argument type="service" id="maker.generator" />
<argument type="service" id="maker.template_linter" />
</service>

<service id="maker.generator" class="Symfony\Bundle\MakerBundle\Generator">
Expand Down
21 changes: 21 additions & 0 deletions src/Resources/doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,27 @@ optional arguments and options. Check them out with the ``--help`` option:

$ php bin/console make:controller --help


Linting Generated Code
______________________

MakerBundle uses php-cs-fixer to enforce coding standards when generating ``.php``
files. When running a ``make`` command, MakerBundle will use a ``php-cs-fixer``
version and configuration that is packaged with this bundle.

You can explicitly set a custom path to a php-cs-fixer binary and/or configuration
file by their respective environment variables:

- ``MAKER_PHP_CS_FIXER_BINARY_PATH`` e.g. tools/vendor/bin/php-cs-fixer
- ``MAKER_PHP_CS_FIXER_CONFIG_PATH`` e.g. .php-cs-fixer.config.php


.. tip::

Is PHP-CS-Fixer installed globally? To avoid needing to set these in every
project, you can instead set these on your operating system.


Configuration
-------------

Expand Down
13 changes: 0 additions & 13 deletions src/Resources/test/.php_cs.test

This file was deleted.

10 changes: 0 additions & 10 deletions src/Test/MakerTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,6 @@ protected function executeMakerCommand(MakerTestDetails $testDetails)
foreach ($files as $file) {
$this->assertTrue($testEnv->fileExists($file), sprintf('The file "%s" does not exist after generation', $file));

if (str_ends_with($file, '.php')) {
$csProcess = $testEnv->runPhpCSFixer($file);

$this->assertTrue($csProcess->isSuccessful(), sprintf(
"File '%s' has a php-cs problem: %s\n",
$file,
$csProcess->getErrorOutput()."\n".$csProcess->getOutput()
));
}

if (str_ends_with($file, '.twig')) {
$csProcess = $testEnv->runTwigCSLint($file);

Expand Down
13 changes: 0 additions & 13 deletions src/Test/MakerTestEnvironment.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,19 +216,6 @@ public function fileExists(string $file): bool
return $this->fs->exists($this->path.'/'.$file);
}

public function runPhpCSFixer(string $file): MakerTestProcess
{
if (!file_exists(__DIR__.'/../../tools/php-cs-fixer/vendor/bin/php-cs-fixer')) {
throw new \Exception('php-cs-fixer not found: run: "composer install --working-dir=tools/php-cs-fixer".');
}

return MakerTestProcess::create(
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),
$this->rootPath,
['PHP_CS_FIXER_IGNORE_ENV' => '1']
)->run(true);
}

public function runTwigCSLint(string $file): MakerTestProcess
{
if (!file_exists(__DIR__.'/../../tools/twigcs/vendor/bin/twigcs')) {
Expand Down
Loading