Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.91% covered (success)
90.91%
40 / 44
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
StandardsCommand
90.91% covered (success)
90.91%
40 / 44
66.67% covered (warning)
66.67%
2 / 3
12.11
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 configure
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
 execute
87.10% covered (warning)
87.10%
27 / 31
0.00% covered (danger)
0.00%
0 / 1
10.21
1<?php
2
3declare(strict_types=1);
4
5/**
6 * Fast Forward Development Tools for PHP projects.
7 *
8 * This file is part of fast-forward/dev-tools project.
9 *
10 * @author   Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
11 * @license  https://opensource.org/licenses/MIT MIT License
12 *
13 * @see      https://github.com/php-fast-forward/
14 * @see      https://github.com/php-fast-forward/dev-tools
15 * @see      https://github.com/php-fast-forward/dev-tools/issues
16 * @see      https://php-fast-forward.github.io/dev-tools/
17 * @see      https://datatracker.ietf.org/doc/html/rfc2119
18 */
19
20namespace FastForward\DevTools\Console\Command;
21
22use FastForward\DevTools\Console\Command\Traits\LogsCommandResults;
23use Composer\Command\BaseCommand;
24use FastForward\DevTools\Console\Input\HasJsonOption;
25use FastForward\DevTools\Process\ProcessBuilderInterface;
26use FastForward\DevTools\Process\ProcessQueueInterface;
27use Psr\Log\LoggerInterface;
28use Symfony\Component\Console\Attribute\AsCommand;
29use Symfony\Component\Console\Input\InputInterface;
30use Symfony\Component\Console\Input\InputOption;
31use Symfony\Component\Console\Output\BufferedOutput;
32use Symfony\Component\Console\Output\OutputInterface;
33
34/**
35 * Executes the full suite of Fast Forward code standard checks.
36 * This class MUST NOT be modified through inheritance and SHALL streamline code validation workflows.
37 */
38#[AsCommand(
39    name: 'standards',
40    description: 'Runs Fast Forward code standards checks.',
41    help: 'This command runs all Fast Forward code standards checks, including code refactoring, PHPDoc validation, code style checks, documentation generation, and tests execution.'
42)]
43 class StandardsCommand extends BaseCommand implements LoggerAwareCommandInterface
44{
45    use HasJsonOption;
46    use LogsCommandResults;
47
48    /**
49     * @param ProcessBuilderInterface $processBuilder
50     * @param ProcessQueueInterface $processQueue
51     * @param LoggerInterface $logger
52     */
53    public function __construct(
54        private  ProcessBuilderInterface $processBuilder,
55        private  ProcessQueueInterface $processQueue,
56        private  LoggerInterface $logger,
57    ) {
58        parent::__construct();
59    }
60
61    /**
62     * Configures constraints and arguments for the collective standard runner.
63     *
64     * @return void
65     */
66    protected function configure(): void
67    {
68        $this->addJsonOption()
69            ->addOption(
70                name: 'progress',
71                mode: InputOption::VALUE_NONE,
72                description: 'Whether to enable progress output from nested standards commands.'
73            )
74            ->addOption(
75                name: 'fix',
76                shortcut: 'f',
77                mode: InputOption::VALUE_NONE,
78                description: 'Automatically fix code standards issues.'
79            );
80    }
81
82    /**
83     * @param InputInterface $input
84     * @param OutputInterface $output
85     */
86    protected function execute(InputInterface $input, OutputInterface $output): int
87    {
88        $jsonOutput = $this->isJsonOutput($input);
89        $prettyJsonOutput = $this->isPrettyJsonOutput($input);
90        $progress = ! $jsonOutput && (bool) $input->getOption('progress');
91
92        $commandOutput = $jsonOutput ? new BufferedOutput() : $output;
93        $commands = [];
94        $fix = (bool) $input->getOption('fix');
95
96        $this->logger->info('Running code standards checks...', [
97            'input' => $input,
98        ]);
99
100        foreach (['refactor', 'phpdoc', 'code-style', 'reports'] as $command) {
101            $commands[] = $command;
102            $processBuilder = $this->processBuilder;
103
104            if ($progress) {
105                $processBuilder = $processBuilder->withArgument('--progress');
106            }
107
108            if ('reports' !== $command && $fix) {
109                $processBuilder = $processBuilder->withArgument('--fix');
110            }
111
112            if ($jsonOutput) {
113                $processBuilder = $processBuilder->withArgument('--json');
114            }
115
116            if ($prettyJsonOutput) {
117                $processBuilder = $processBuilder->withArgument('--pretty-json');
118            }
119
120            $this->processQueue->add($processBuilder->build('composer dev-tools ' . $command . ' --'));
121        }
122
123        $result = $this->processQueue->run($commandOutput);
124
125        if (self::FAILURE === $result) {
126            return $this->failure('Code standards checks failed.', $input, [
127                'output' => $commandOutput,
128                'commands' => $commands,
129            ]);
130        }
131
132        return $this->success('Code standards checks completed successfully.', $input, [
133            'output' => $commandOutput,
134            'commands' => $commands,
135        ]);
136    }
137}