Passed
Push — trunk ( 6b4dda...e7c57d )
by Christian
11:25 queued 15s
created

OpenApiValidationCommand::execute()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 37
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 21
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 37
rs 9.584
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Core\DevOps\System\Command;
4
5
use Shopware\Core\Framework\Adapter\Console\ShopwareStyle;
6
use Shopware\Core\Framework\Api\ApiDefinition\DefinitionService;
7
use Shopware\Core\Framework\Api\ApiDefinition\Generator\OpenApi3Generator;
8
use Shopware\Core\Framework\Log\Package;
9
use Symfony\Component\Console\Attribute\AsCommand;
10
use Symfony\Component\Console\Command\Command;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Command\Command was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Symfony\Component\Console\Input\InputArgument;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Input\InputOption;
14
use Symfony\Component\Console\Output\OutputInterface;
15
use Symfony\Contracts\HttpClient\HttpClientInterface;
16
17
/**
18
 * @internal
19
 */
20
#[Package('core')]
21
#[AsCommand(
22
    name: 'open-api:validate',
23
    description: 'Validates the OpenAPI schema',
24
)]
25
class OpenApiValidationCommand extends Command
26
{
27
    public function __construct(
28
        private HttpClientInterface $client,
29
        private DefinitionService $definitionService
30
    ) {
31
        parent::__construct();
32
    }
33
34
    protected function configure(): void
35
    {
36
        $this->addArgument('validatorUrl', InputArgument::OPTIONAL, 'The URL of the validator', 'https://validator.swagger.io/validator/debug');
37
        $this->addOption('api-type', '', InputOption::VALUE_REQUIRED, 'The API type to validate', DefinitionService::API);
38
    }
39
40
    protected function execute(InputInterface $input, OutputInterface $output): int
41
    {
42
        $validatorURL = $input->getArgument('validatorUrl');
43
        $apiType = match ($input->getOption('api-type')) {
44
            DefinitionService::API => DefinitionService::API,
45
            DefinitionService::STORE_API => DefinitionService::STORE_API,
46
            default => throw new \InvalidArgumentException('Invalid --api-type, must be one of "api" or "store-api"'),
47
        };
48
49
        $schema = $this->definitionService->generate(
50
            OpenApi3Generator::FORMAT,
51
            $apiType,
52
        );
53
54
        $response = $this->client->request('POST', $validatorURL, [
55
            'json' => $schema,
56
            'headers' => [
57
                'Accept' => 'application/json',
58
            ],
59
        ]);
60
        $content = $response->toArray();
61
62
        // The CI validator returns an empty response if the schema is valid
63
        // The public Web validator returns an object with an empty (schemaValidation)Messages array
64
        $messages = array_merge(
65
            $content['messages'] ?? [],
66
            $content['schemaValidationMessages'] ?? []
67
        );
68
69
        if (\count($messages) === 0) {
70
            return Command::SUCCESS;
71
        }
72
73
        $style = new ShopwareStyle($input, $output);
74
        $this->renderErrorMessages($style, $messages);
75
76
        return Command::FAILURE;
77
    }
78
79
    /**
80
     * @param array<string, string|array<mixed>> $messages
81
     */
82
    private function renderErrorMessages(ShopwareStyle $style, array $messages): void
83
    {
84
        $style->error('The OpenAPI schema is invalid:');
85
        $table = $style->createTable();
86
        $table->setHeaders(['No.', 'Error']);
87
88
        foreach ($messages as $i => $message) {
89
            if (\is_array($message)) {
90
                $message = json_encode($message, \JSON_PRETTY_PRINT);
91
            }
92
            $table->addRow([$i, $message]);
93
        }
94
95
        $table->render();
96
    }
97
}
98