Passed
Pull Request — master (#400)
by Théo
03:00
created

Validate::executeCommand()   C

Complexity

Conditions 12
Paths 183

Size

Total Lines 76
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 47
dl 0
loc 76
rs 6.2749
c 0
b 0
f 0
cc 12
nc 183
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the box project.
7
 *
8
 * (c) Kevin Herrera <[email protected]>
9
 *     Théo Fidry <[email protected]>
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 KevinGH\Box\Console\Command;
16
17
use Exception;
18
use KevinGH\Box\Console\ConfigurationLoader;
19
use KevinGH\Box\Console\IO\IO;
20
use KevinGH\Box\Console\MessageRenderer;
21
use KevinGH\Box\Json\JsonValidationException;
22
use function sprintf;
23
use Symfony\Component\Console\Exception\RuntimeException;
24
use Symfony\Component\Console\Input\InputArgument;
25
use Symfony\Component\Console\Input\InputOption;
26
27
/**
28
 * @private
29
 */
30
final class Validate extends BaseCommand
31
{
32
    private const FILE_ARGUMENT = 'file';
33
    private const IGNORE_MESSAGES_OPTION = 'ignore-recommendations-and-warnings';
34
35
    /**
36
     * {@inheritdoc}
37
     */
38
    protected function configure(): void
39
    {
40
        parent::configure();
41
42
        $this->setName('validate');
43
        $this->setDescription('⚙  Validates the configuration file');
44
        $this->setHelp(
45
            <<<'HELP'
46
The <info>%command.name%</info> command will validate the configuration file
47
and report any errors found, if any.
48
<comment>
49
  This command relies on a configuration file for loading
50
  PHAR packaging settings. If a configuration file is not
51
  specified through the <info>--configuration|-c</info> option, one of
52
  the following files will be used (in order): <info>box.json,
53
  box.json.dist</info>
54
</comment>
55
HELP
56
        );
57
        $this->addArgument(
58
            self::FILE_ARGUMENT,
59
            InputArgument::OPTIONAL,
60
            'The configuration file. (default: box.json, box.json.dist)'
61
        );
62
        $this->addOption(
63
            self::IGNORE_MESSAGES_OPTION,
64
            'i',
65
            InputOption::VALUE_NONE,
66
            'Will not return a faulty code when a recommendation or warning is found'
67
        );
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73
    protected function executeCommand(IO $io): int
74
    {
75
        $input = $io->getInput();
76
77
        try {
78
            $config = ConfigurationLoader::getConfig(
79
                $input->getArgument(self::FILE_ARGUMENT) ?? $this->getConfigurationHelper()->findDefaultPath(),
80
                $this->getConfigurationHelper(),
81
                $io,
82
                false
83
            );
84
85
            $recommendations = $config->getRecommendations();
86
            $warnings = $config->getWarnings();
87
88
            MessageRenderer::render($io, $recommendations, $warnings);
89
90
            $hasRecommendationsOrWarnings = [] === $recommendations && [] === $warnings;
91
92
            if (false === $hasRecommendationsOrWarnings) {
93
                if ([] === $recommendations) {
94
                    $io->caution('The configuration file passed the validation with warnings.');
95
                } elseif ([] === $warnings) {
96
                    $io->caution('The configuration file passed the validation with recommendations.');
97
                } else {
98
                    $io->caution('The configuration file passed the validation with recommendations and warnings.');
99
                }
100
            } else {
101
                $io->success('The configuration file passed the validation.');
102
            }
103
104
            return $hasRecommendationsOrWarnings || $input->getOption(self::IGNORE_MESSAGES_OPTION) ? 0 : 1;
105
        } catch (Exception $exception) {
106
            // Continue
107
        }
108
109
        if ($io->isVerbose()) {
110
            throw new RuntimeException(
111
                sprintf(
112
                    'The configuration file failed validation: %s',
113
                    $exception->getMessage()
114
                ),
115
                $exception->getCode(),
116
                $exception
117
            );
118
        }
119
120
        if ($exception instanceof JsonValidationException) {
121
            $io->writeln(
122
                sprintf(
123
                    '<error>The configuration file failed validation: "%s" does not match the expected JSON '
124
                    .'schema:</error>',
125
                    $exception->getValidatedFile()
126
                )
127
            );
128
129
            $io->writeln('');
130
131
            foreach ($exception->getErrors() as $error) {
132
                $io->writeln("<comment>  - $error</comment>");
133
            }
134
        } else {
135
            $errorMessage = isset($exception)
136
                ? sprintf('The configuration file failed validation: %s', $exception->getMessage())
137
                : 'The configuration file failed validation.'
138
            ;
139
140
            $io->writeln(
141
                sprintf(
142
                    '<error>%s</error>',
143
                    $errorMessage
144
                )
145
            );
146
        }
147
148
        return 1;
149
    }
150
}
151