Skip to content

Commit c9e3209

Browse files
authored
Merge pull request #1131 from antoniovj1/v2.x
feat: Add task for Twig-CS-Fixer
2 parents 24c1609 + 3fc91de commit c9e3209

File tree

6 files changed

+428
-1
lines changed

6 files changed

+428
-1
lines changed

composer.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@
8080
"sstalle/php7cc": "Lets GrumPHP check PHP 5.3 - 5.6 code compatibility with PHP 7.",
8181
"symfony/phpunit-bridge": "Lets GrumPHP run your unit tests with the phpunit-bridge of Symfony.",
8282
"symplify/easy-coding-standard": "Lets GrumPHP check coding standard.",
83-
"vimeo/psalm": "Lets GrumPHP discover errors in your code without running it."
83+
"vimeo/psalm": "Lets GrumPHP discover errors in your code without running it.",
84+
"vincentlanglet/twig-cs-fixer": "Lets GrumPHP check and fix twig coding standard."
8485
},
8586
"autoload": {
8687
"psr-4": {

doc/tasks.md

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ grumphp:
6363
stylelint: ~
6464
tester: ~
6565
twigcs: ~
66+
twigcsfixer: ~
6667
xmllint: ~
6768
yamllint: ~
6869
```
@@ -129,6 +130,7 @@ Every task has its own default configuration. It is possible to overwrite the pa
129130
- [Stylelint](tasks/stylelint.md)
130131
- [Tester](tasks/tester.md)
131132
- [TwigCs](tasks/twigcs.md)
133+
- [Twig-CS-Fixer](tasks/twigcsfixer.md)
132134
- [XmlLint](tasks/xmllint.md)
133135
- [YamlLint](tasks/yamllint.md)
134136

doc/tasks/twigcsfixer.md

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Twig-CS-Fixer
2+
3+
Check and fix Twig coding standard using [VincentLanglet/Twig-CS-Fixer](https://github.com/VincentLanglet/Twig-CS-Fixer).
4+
5+
***Composer***
6+
7+
```
8+
composer require --dev "vincentlanglet/twig-cs-fixer:>=2"
9+
```
10+
11+
***Config***
12+
13+
The task lives under the `twigcsfixer` namespace and has following configurable parameters:
14+
15+
```yaml
16+
# grumphp.yml
17+
grumphp:
18+
tasks:
19+
twigcsfixer:
20+
paths: []
21+
level: ~
22+
config: ~
23+
report: 'text'
24+
no-cache: false
25+
verbose: false
26+
triggered_by: ['twig']
27+
```
28+
29+
**paths**
30+
31+
*Default: []*
32+
33+
By default, current folder will be used.
34+
On precommit only changed files that live in the paths will be passed as arguments.
35+
36+
37+
**level**
38+
39+
*Default: 'notice'*
40+
41+
The level of the messages to display (possibles values are : 'notice', 'warning', 'error').
42+
43+
**config**
44+
45+
*Default: null*
46+
47+
Path to a `.twig-cs-fixer.php` config file. If not set, the default config will be used.
48+
49+
You can check config file [here](https://github.com/VincentLanglet/Twig-CS-Fixer/blob/main/docs/configuration.md).
50+
51+
**report**
52+
53+
*Default: 'text'*
54+
55+
The `--report` option allows to choose the output format for the linter report.
56+
57+
Supported formats are:
58+
- `text` selected by default.
59+
- `checkstyle` following the common checkstyle XML schema.
60+
- `github` if you want annotations on GitHub actions.
61+
- `junit` following JUnit schema XML from Jenkins.
62+
- `null` if you don't want any reporting.
63+
64+
**no-cache**
65+
66+
*Default: false*
67+
68+
Do not use cache.
69+
70+
**verbose**
71+
72+
*Default: false*
73+
74+
Increase the verbosity of messages.
75+
76+
**triggered_by**
77+
78+
*Default: [twig]*
79+
80+
This option will specify which file extensions will trigger this task.

resources/config/tasks.yml

+7
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,13 @@ services:
401401
tags:
402402
- {name: grumphp.task, task: twigcs}
403403

404+
GrumPHP\Task\TwigCsFixer:
405+
arguments:
406+
- '@process_builder'
407+
- '@formatter.raw_process'
408+
tags:
409+
- {name: grumphp.task, task: twigcsfixer}
410+
404411
GrumPHP\Task\XmlLint:
405412
arguments:
406413
- '@linter.xmllint'

src/Task/TwigCsFixer.php

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace GrumPHP\Task;
6+
7+
use GrumPHP\Formatter\ProcessFormatterInterface;
8+
use GrumPHP\Runner\TaskResult;
9+
use GrumPHP\Runner\TaskResultInterface;
10+
use GrumPHP\Task\Config\ConfigOptionsResolver;
11+
use GrumPHP\Task\Context\ContextInterface;
12+
use GrumPHP\Task\Context\GitPreCommitContext;
13+
use GrumPHP\Task\Context\RunContext;
14+
use Symfony\Component\OptionsResolver\OptionsResolver;
15+
use GrumPHP\Fixer\Provider\FixableProcessResultProvider;
16+
use Symfony\Component\Process\Process;
17+
18+
/**
19+
* @extends AbstractExternalTask<ProcessFormatterInterface>
20+
*/
21+
class TwigCsFixer extends AbstractExternalTask
22+
{
23+
public static function getConfigurableOptions(): ConfigOptionsResolver
24+
{
25+
$resolver = new OptionsResolver();
26+
$resolver->setDefaults([
27+
'paths' => [],
28+
'level' => null,
29+
'config' => null,
30+
'report' => 'text',
31+
'no-cache' => false,
32+
'verbose' => false,
33+
'triggered_by' => ['twig'],
34+
]);
35+
36+
$resolver->addAllowedTypes('paths', ['array']);
37+
$resolver->addAllowedTypes('level', ['null', 'string']);
38+
$resolver->addAllowedTypes('config', ['null', 'string']);
39+
$resolver->addAllowedTypes('report', ['null', 'string']);
40+
$resolver->addAllowedTypes('no-cache', ['bool']);
41+
$resolver->addAllowedTypes('verbose', ['bool']);
42+
43+
return ConfigOptionsResolver::fromOptionsResolver($resolver);
44+
}
45+
46+
public function canRunInContext(ContextInterface $context): bool
47+
{
48+
return $context instanceof GitPreCommitContext || $context instanceof RunContext;
49+
}
50+
51+
public function run(ContextInterface $context): TaskResultInterface
52+
{
53+
$config = $this->getConfig()->getOptions();
54+
$files = $context->getFiles()
55+
->extensions($config['triggered_by'])
56+
->paths($config['paths']);
57+
58+
if (\count($files) === 0) {
59+
return TaskResult::createSkipped($this, $context);
60+
}
61+
62+
$arguments = $this->processBuilder->createArgumentsForCommand('twig-cs-fixer');
63+
$arguments->add('lint');
64+
65+
if ($context instanceof GitPreCommitContext) {
66+
$arguments->addFiles($files);
67+
}
68+
69+
if ($context instanceof RunContext) {
70+
$arguments->addArgumentArray('%s', $config['paths']);
71+
}
72+
73+
$arguments->addOptionalArgument('--level=%s', $config['level']);
74+
$arguments->addOptionalArgument('--config=%s', $config['config']);
75+
$arguments->addOptionalArgument('--report=%s', $config['report']);
76+
77+
$arguments->addOptionalArgument('--no-cache', $config['no-cache']);
78+
$arguments->addOptionalArgument('--verbose', $config['verbose']);
79+
80+
$process = $this->processBuilder->buildProcess($arguments);
81+
$process->run();
82+
83+
if (!$process->isSuccessful()) {
84+
return FixableProcessResultProvider::provide(
85+
TaskResult::createFailed($this, $context, $this->formatter->format($process)),
86+
function () use ($arguments): Process {
87+
$arguments->add('--fix');
88+
return $this->processBuilder->buildProcess($arguments);
89+
}
90+
);
91+
}
92+
93+
return TaskResult::createPassed($this, $context);
94+
}
95+
}

0 commit comments

Comments
 (0)