Passed
Pull Request — master (#288)
by Théo
02:08
created

Validate::configure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 29
rs 9.7333
c 0
b 0
f 0
cc 1
nc 1
nop 0
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\MessageRenderer;
19
use KevinGH\Box\Console\OutputConfigurator;
20
use KevinGH\Box\Json\JsonValidationException;
21
use Symfony\Component\Console\Exception\RuntimeException;
22
use Symfony\Component\Console\Input\InputArgument;
23
use Symfony\Component\Console\Input\InputInterface;
24
use Symfony\Component\Console\Input\InputOption;
25
use Symfony\Component\Console\Output\OutputInterface;
26
use Symfony\Component\Console\Style\SymfonyStyle;
27
28
/**
29
 * @private
30
 */
31
final class Validate extends Configurable
32
{
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
            'file',
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 execute(InputInterface $input, OutputInterface $output): int
74
    {
75
        $io = new SymfonyStyle($input, $output);
76
77
        OutputConfigurator::configure($output);
78
79
        try {
80
            $config = $this->getConfig($input, $output);
81
82
            $recommendations = $config->getRecommendations();
83
            $warnings = $config->getWarnings();
84
85
            MessageRenderer::render($io, $recommendations, $warnings);
86
87
            $hasRecommendationsOrWarnings = [] === $recommendations && [] === $warnings;
88
89
            if (false === $hasRecommendationsOrWarnings) {
90
                if ([] === $recommendations) {
91
                    $io->caution('The configuration file passed the validation with warnings.');
92
                } elseif ([] === $warnings) {
93
                    $io->caution('The configuration file passed the validation with recommendations.');
94
                } else {
95
                    $io->caution('The configuration file passed the validation with recommendations and warnings.');
96
                }
97
            } else {
98
                $io->success('The configuration file passed the validation.');
99
            }
100
101
            return ($hasRecommendationsOrWarnings || $input->getOption(self::IGNORE_MESSAGES_OPTION)) ? 0 : 1;
102
        } catch (Exception $exception) {
103
            // Continue
104
        }
105
106
        if ($output->isVerbose()) {
107
            throw new RuntimeException(
108
                sprintf(
109
                    'The configuration file failed validation: %s',
110
                    $exception->getMessage()
111
                ),
112
                $exception->getCode(),
113
                $exception
114
            );
115
        }
116
117
        if ($exception instanceof JsonValidationException) {
118
            $output->writeln(
119
                sprintf(
120
                    '<error>The configuration file failed validation: "%s" does not match the expected JSON '
121
                    .'schema:</error>',
122
                    $exception->getValidatedFile()
123
                )
124
            );
125
126
            $output->writeln('');
127
128
            foreach ($exception->getErrors() as $error) {
129
                $output->writeln("<comment>  - $error</comment>");
130
            }
131
        } else {
132
            $errorMessage = isset($exception)
133
                ? sprintf('The configuration file failed validation: %s', $exception->getMessage())
134
                : 'The configuration file failed validation.'
135
            ;
136
137
            $output->writeln(
138
                sprintf(
139
                    '<error>%s</error>',
140
                    $errorMessage
141
                )
142
            );
143
        }
144
145
        return 1;
146
    }
147
}
148