• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

keradus / PHP-CS-Fixer / 24023665044

02 Apr 2026 09:33PM UTC coverage: 93.056% (+0.1%) from 92.938%
24023665044

push

github

web-flow
chore: add tests for `BracesPositionFixer` (#9522)

29548 of 31753 relevant lines covered (93.06%)

43.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

71.43
/src/Console/Application.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of PHP CS Fixer.
7
 *
8
 * (c) Fabien Potencier <fabien@symfony.com>
9
 *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
10
 *
11
 * This source file is subject to the MIT license that is bundled
12
 * with this source code in the file LICENSE.
13
 */
14

15
namespace PhpCsFixer\Console;
16

17
use PhpCsFixer\Console\Command\CheckCommand;
18
use PhpCsFixer\Console\Command\DescribeCommand;
19
use PhpCsFixer\Console\Command\FixCommand;
20
use PhpCsFixer\Console\Command\HelpCommand;
21
use PhpCsFixer\Console\Command\InitCommand;
22
use PhpCsFixer\Console\Command\ListFilesCommand;
23
use PhpCsFixer\Console\Command\ListRulesCommand;
24
use PhpCsFixer\Console\Command\ListSetsCommand;
25
use PhpCsFixer\Console\Command\SelfUpdateCommand;
26
use PhpCsFixer\Console\Command\WorkerCommand;
27
use PhpCsFixer\Console\SelfUpdate\GithubClient;
28
use PhpCsFixer\Console\SelfUpdate\NewVersionChecker;
29
use PhpCsFixer\Future;
30
use PhpCsFixer\PharChecker;
31
use PhpCsFixer\Runner\Parallel\WorkerException;
32
use PhpCsFixer\ToolInfo;
33
use Symfony\Component\Console\Application as BaseApplication;
34
use Symfony\Component\Console\Command\Command;
35
use Symfony\Component\Console\Command\CompleteCommand;
36
use Symfony\Component\Console\Command\DumpCompletionCommand;
37
use Symfony\Component\Console\Command\ListCommand;
38
use Symfony\Component\Console\Exception\CommandNotFoundException;
39
use Symfony\Component\Console\Input\InputInterface;
40
use Symfony\Component\Console\Output\ConsoleOutputInterface;
41
use Symfony\Component\Console\Output\OutputInterface;
42

43
/**
44
 * @author Fabien Potencier <fabien@symfony.com>
45
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
46
 *
47
 * @internal
48
 *
49
 * @no-named-arguments Parameter names are not covered by the backward compatibility promise.
50
 */
51
final class Application extends BaseApplication
52
{
53
    public const NAME = 'PHP CS Fixer';
54
    public const VERSION = '3.94.3-DEV';
55
    public const VERSION_CODENAME = '7th Gear';
56

57
    /**
58
     * @readonly
59
     */
60
    private ToolInfo $toolInfo;
61

62
    private ?Command $executedCommand = null;
63

64
    public function __construct()
65
    {
66
        parent::__construct(self::NAME, self::VERSION);
2✔
67

68
        $this->toolInfo = new ToolInfo();
2✔
69

70
        // in alphabetical order
71
        $this->add(new CheckCommand($this->toolInfo));
2✔
72
        $this->add(new DescribeCommand());
2✔
73
        $this->add(new FixCommand($this->toolInfo));
2✔
74
        $this->add(new InitCommand());
2✔
75
        $this->add(new ListFilesCommand($this->toolInfo));
2✔
76
        $this->add(new ListRulesCommand());
2✔
77
        $this->add(new ListSetsCommand());
2✔
78
        $this->add(new SelfUpdateCommand(
2✔
79
            new NewVersionChecker(new GithubClient()),
2✔
80
            $this->toolInfo,
2✔
81
            new PharChecker(),
2✔
82
        ));
2✔
83
        $this->add(new WorkerCommand($this->toolInfo));
2✔
84
    }
85

86
    // polyfill for `add` method, as it is not available in Symfony 8.0
87
    public function add(Command $command): ?Command
88
    {
89
        if (method_exists($this, 'addCommand')) { // @phpstan-ignore-line
2✔
90
            return $this->addCommand($command);
2✔
91
        }
92

93
        return parent::add($command); // @phpstan-ignore-line
×
94
    }
95

96
    public static function getMajorVersion(): int
97
    {
98
        return (int) explode('.', self::VERSION)[0];
1✔
99
    }
100

101
    public function doRun(InputInterface $input, OutputInterface $output): int
102
    {
103
        $stdErr = $output instanceof ConsoleOutputInterface
1✔
104
            ? $output->getErrorOutput()
×
105
            : ($input->hasParameterOption('--format', true) && 'txt' !== $input->getParameterOption('--format', null, true) ? null : $output);
1✔
106

107
        if (null !== $stdErr) {
1✔
108
            $warningsDetector = new WarningsDetector($this->toolInfo);
1✔
109
            $warningsDetector->detectOldVendor();
1✔
110
            $warningsDetector->detectOldMajor();
1✔
111

112
            try {
113
                $commandName = $this->getCommandName($input);
1✔
114
                if (null === $commandName) {
1✔
115
                    throw new CommandNotFoundException('No command name found.');
×
116
                }
117
                $command = $this->find($commandName);
1✔
118

119
                if (($command instanceof CheckCommand) || ($command instanceof FixCommand)) {
1✔
120
                    $warningsDetector->detectHigherPhpVersion();
×
121
                    $warningsDetector->detectNonMonolithic();
1✔
122
                }
123
            } catch (CommandNotFoundException $e) {
×
124
                // no-op
125
            }
126

127
            $warnings = $warningsDetector->getWarnings();
1✔
128

129
            if (\count($warnings) > 0) {
1✔
130
                foreach ($warnings as $warning) {
×
131
                    $stdErr->writeln(\sprintf($stdErr->isDecorated() ? '<bg=yellow;fg=black;>%s</>' : '%s', $warning));
×
132
                }
133
                $stdErr->writeln('');
×
134
            }
135
        }
136

137
        $result = parent::doRun($input, $output);
1✔
138

139
        if (
140
            null !== $stdErr
×
141
            && $output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE
×
142
        ) {
143
            $triggeredDeprecations = Future::getTriggeredDeprecations();
×
144

145
            if (\count($triggeredDeprecations) > 0) {
×
146
                $stdErr->writeln('');
×
147
                $stdErr->writeln($stdErr->isDecorated() ? '<bg=yellow;fg=black;>Detected deprecations in use (they will stop working in next major release):</>' : 'Detected deprecations in use (they will stop working in next major release):');
×
148
                foreach ($triggeredDeprecations as $deprecation) {
×
149
                    $stdErr->writeln(\sprintf('- %s', $deprecation));
×
150
                }
151
            }
152
        }
153

154
        return $result;
×
155
    }
156

157
    /**
158
     * @internal
159
     */
160
    public static function getAbout(bool $decorated = false): string
161
    {
162
        $longVersion = \sprintf('%s <info>%s</info>', self::NAME, self::VERSION);
1✔
163

164
        // value of `$commitPlaceholderPossiblyEvaluated` will be changed during phar building, other value will not
165
        $commitPlaceholderPossiblyEvaluated = '@git-commit@';
1✔
166
        $commitPlaceholder = implode('', ['@', 'git-commit@']); // do not replace with imploded value, as here we need to prevent phar builder to replace the placeholder
1✔
167

168
        $versionCommit = $commitPlaceholder !== $commitPlaceholderPossiblyEvaluated
1✔
169
            ? substr($commitPlaceholderPossiblyEvaluated, 0, 7) // for phar builds
×
170
            : '';
1✔
171

172
        $about = implode('', [
1✔
173
            $longVersion,
1✔
174
            $versionCommit ? \sprintf(' <info>(%s)</info>', $versionCommit) : '', // @phpstan-ignore-line to avoid `Ternary operator condition is always true|false.`
1✔
175
            self::VERSION_CODENAME ? \sprintf(' <info>%s</info>', self::VERSION_CODENAME) : '', // @phpstan-ignore-line to avoid `Ternary operator condition is always true|false.`
1✔
176
            ' by <comment>Fabien Potencier</comment>, <comment>Dariusz Ruminski</comment> and <comment>contributors</comment>.',
1✔
177
        ]);
1✔
178

179
        if (false === $decorated) {
1✔
180
            return strip_tags($about);
×
181
        }
182

183
        return $about;
1✔
184
    }
185

186
    /**
187
     * @internal
188
     */
189
    public static function getAboutWithRuntime(bool $decorated = false): string
190
    {
191
        $about = self::getAbout(true)."\nPHP runtime: <info>".\PHP_VERSION.'</info>';
1✔
192
        if (false === $decorated) {
1✔
193
            return strip_tags($about);
×
194
        }
195

196
        return $about;
1✔
197
    }
198

199
    public function getLongVersion(): string
200
    {
201
        return self::getAboutWithRuntime(true);
1✔
202
    }
203

204
    protected function getDefaultCommands(): array
205
    {
206
        return [new HelpCommand(), new ListCommand(), new CompleteCommand(), new DumpCompletionCommand()];
2✔
207
    }
208

209
    /**
210
     * @throws \Throwable
211
     */
212
    protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output): int
213
    {
214
        $this->executedCommand = $command;
1✔
215

216
        return parent::doRunCommand($command, $input, $output);
1✔
217
    }
218

219
    protected function doRenderThrowable(\Throwable $e, OutputInterface $output): void
220
    {
221
        // Since parallel analysis utilises child processes, and they have their own output,
222
        // we need to capture the output of the child process to determine it there was an exception.
223
        // Default render format is not machine-friendly, so we need to override it for `worker` command,
224
        // in order to be able to easily parse exception data for further displaying on main process' side.
225
        if ($this->executedCommand instanceof WorkerCommand) {
1✔
226
            $output->writeln(WorkerCommand::ERROR_PREFIX.json_encode(
1✔
227
                [
1✔
228
                    'class' => \get_class($e),
1✔
229
                    'message' => $e->getMessage(),
1✔
230
                    'file' => $e->getFile(),
1✔
231
                    'line' => $e->getLine(),
1✔
232
                    'code' => $e->getCode(),
1✔
233
                    'trace' => $e->getTraceAsString(),
1✔
234
                ],
1✔
235
                \JSON_THROW_ON_ERROR,
1✔
236
            ));
1✔
237

238
            return;
1✔
239
        }
240

241
        parent::doRenderThrowable($e, $output);
×
242

243
        if ($output->isVeryVerbose() && $e instanceof WorkerException) {
×
244
            $output->writeln('<comment>Original trace from worker:</comment>');
×
245
            $output->writeln('');
×
246
            $output->writeln($e->getOriginalTraceAsString());
×
247
            $output->writeln('');
×
248
        }
249
    }
250
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc