-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCodeStyleCommand.php
More file actions
171 lines (148 loc) · 6.38 KB
/
CodeStyleCommand.php
File metadata and controls
171 lines (148 loc) · 6.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<?php
declare(strict_types=1);
/**
* Fast Forward Development Tools for PHP projects.
*
* This file is part of fast-forward/dev-tools project.
*
* @author Felipe Sayão Lobato Abreu <github@mentordosnerds.com>
* @license https://opensource.org/licenses/MIT MIT License
*
* @see https://github.com/php-fast-forward/
* @see https://github.com/php-fast-forward/dev-tools
* @see https://github.com/php-fast-forward/dev-tools/issues
* @see https://php-fast-forward.github.io/dev-tools/
* @see https://datatracker.ietf.org/doc/html/rfc2119
*/
namespace FastForward\DevTools\Console\Command;
use FastForward\DevTools\Console\Command\Traits\LogsCommandResults;
use Composer\Command\BaseCommand;
use FastForward\DevTools\Console\Input\HasJsonOption;
use FastForward\DevTools\Process\ProcessBuilderInterface;
use FastForward\DevTools\Process\ProcessQueueInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Config\FileLocatorInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Represents the command responsible for checking and fixing code style issues.
* This class MUST NOT be overridden and SHALL rely on external tools like ECS and Composer Normalize.
*/
#[AsCommand(
name: 'code-style',
description: 'Checks and fixes code style issues using EasyCodingStandard and Composer Normalize.'
)]
final class CodeStyleCommand extends BaseCommand implements LoggerAwareCommandInterface
{
use HasJsonOption;
use LogsCommandResults;
/**
* @var string the default configuration file used for EasyCodingStandard
*/
public const string CONFIG = 'ecs.php';
/**
* Constructs a new command instance responsible for orchestrating code style checks.
*
* The provided collaborators SHALL be used to locate the ECS configuration,
* build process definitions, and execute the resulting process queue. These
* dependencies MUST be valid service instances capable of supporting the
* command lifecycle expected by this class.
*
* @param FileLocatorInterface $fileLocator locates the configuration file required by EasyCodingStandard
* @param ProcessBuilderInterface $processBuilder builds the process instances used to execute Composer and ECS commands
* @param ProcessQueueInterface $processQueue queues and executes the generated processes in the required order
* @param LoggerInterface $logger logs command feedback
*/
public function __construct(
private readonly FileLocatorInterface $fileLocator,
private readonly ProcessBuilderInterface $processBuilder,
private readonly ProcessQueueInterface $processQueue,
private readonly LoggerInterface $logger,
) {
parent::__construct();
}
/**
* Configures the current command.
*
* This method MUST define the name, description, help text, and options for the command.
* It SHALL register the `--fix` option to allow automatic resolutions of style issues.
*
* @return void
*/
protected function configure(): void
{
$this->setHelp(
'This command runs EasyCodingStandard and Composer Normalize to check and fix code style issues.'
);
$this->addJsonOption()
->addOption(
name: 'progress',
mode: InputOption::VALUE_NONE,
description: 'Whether to enable progress output from code style tools.',
)
->addOption(
name: 'fix',
shortcut: 'f',
mode: InputOption::VALUE_NONE,
description: 'Automatically fix code style issues.'
);
}
/**
* Executes the code style checks and fixes block.
*
* The method MUST execute `composer update --lock`, `composer normalize`, and ECS using secure processes.
* It SHALL return `self::SUCCESS` if all commands succeed, or `self::FAILURE` otherwise.
*
* @param InputInterface $input the input interface to retrieve options
* @param OutputInterface $output the output interface to log messages
*
* @return int the status code of the command
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$jsonOutput = $this->isJsonOutput($input);
$processOutput = $jsonOutput ? new BufferedOutput() : $output;
$fix = (bool) $input->getOption('fix');
$progress = ! $jsonOutput && (bool) $input->getOption('progress');
$this->logger->info('Running code style checks and fixes...');
$composerUpdate = $this->processBuilder
->withArgument('--lock')
->withArgument('--quiet')
->build('composer update');
$composerNormalize = $this->processBuilder
->withArgument('--ansi')
->withArgument($fix ? '--quiet' : '--dry-run')
->build('composer normalize');
$processBuilder = $this->processBuilder
->withArgument('--config', $this->fileLocator->locate(self::CONFIG));
if (! $progress) {
$processBuilder = $processBuilder->withArgument('--no-progress-bar');
}
if ($jsonOutput) {
$processBuilder = $processBuilder->withArgument('--output-format', 'json');
}
if ($fix) {
$processBuilder = $processBuilder->withArgument('--fix');
}
$ecs = $processBuilder->build('vendor/bin/ecs');
$this->processQueue->add($composerUpdate);
$this->processQueue->add($composerNormalize);
$this->processQueue->add($ecs);
$result = $this->processQueue->run($processOutput);
if (self::SUCCESS === $result) {
return $this->success('Code style checks completed successfully.', $input, [
'fix' => $fix,
'config' => self::CONFIG,
'process_output' => $processOutput instanceof BufferedOutput ? $processOutput->fetch() : null,
]);
}
return $this->failure('Code style checks failed.', $input, [
'fix' => $fix,
'config' => self::CONFIG,
'process_output' => $processOutput instanceof BufferedOutput ? $processOutput->fetch() : null,
]);
}
}