DumpSchemasCommand   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 143
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 14
eloc 113
c 1
b 0
f 0
dl 0
loc 143
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A rrmdir() 0 11 3
C execute() 0 102 10
A configure() 0 18 1
1
<?php
2
3
namespace TgScraper\Commands;
4
5
use Exception;
6
use FilesystemIterator;
7
use PharData;
8
use RecursiveDirectoryIterator;
9
use RecursiveIteratorIterator;
10
use ReflectionClass;
11
use Symfony\Component\Console\Command\Command;
12
use Symfony\Component\Console\Input\InputArgument;
13
use Symfony\Component\Console\Input\InputInterface;
14
use Symfony\Component\Console\Input\InputOption;
15
use Symfony\Component\Console\Logger\ConsoleLogger;
16
use Symfony\Component\Console\Output\OutputInterface;
17
use TgScraper\Common\Encoder;
18
use TgScraper\Constants\Versions;
19
use TgScraper\TgScraper;
20
use Throwable;
21
22
class DumpSchemasCommand extends Command
23
{
24
25
    use Common;
26
27
    protected static $defaultName = 'app:dump-schemas';
28
29
    protected static function rrmdir(string $directory): void
30
    {
31
        $files = new RecursiveIteratorIterator(
32
            new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS),
33
            RecursiveIteratorIterator::CHILD_FIRST
34
        );
35
        foreach ($files as $fileInfo) {
36
            $todo = ($fileInfo->isDir() ? 'rmdir' : 'unlink');
37
            $todo($fileInfo->getRealPath());
38
        }
39
        rmdir($directory);
40
    }
41
42
    protected function configure(): void
43
    {
44
        $this
45
            ->setDescription('Export all schemas and stubs to a directory.')
46
            ->setHelp('This command allows you to generate the schemas for all versions of the Telegram bot API.')
47
            ->addArgument('destination', InputArgument::REQUIRED, 'Destination directory')
48
            ->addOption(
49
                'namespace-prefix',
50
                null,
51
                InputOption::VALUE_REQUIRED,
52
                'Namespace prefix for stubs',
53
                'TelegramApi'
54
            )
55
            ->addOption(
56
                'readable',
57
                'r',
58
                InputOption::VALUE_NONE,
59
                'Generate human-readable files'
60
            );
61
    }
62
63
    protected function execute(InputInterface $input, OutputInterface $output): int
64
    {
65
        $versionReplacer = function (string $ver) {
66
            /** @noinspection PhpUndefinedFieldInspection */
67
            $this->version = $ver;
68
        };
69
        $logger = new ConsoleLogger($output);
70
        $destination = $input->getArgument('destination');
71
        $readable = $input->getOption('readable');
72
        $output->writeln('Creating directory tree...');
73
        try {
74
            $destination = TgScraper::getTargetDirectory($destination);
75
            mkdir($destination . '/custom/json', 0755, true);
76
            mkdir($destination . '/custom/yaml', 0755, true);
77
            mkdir($destination . '/postman', 0755, true);
78
            mkdir($destination . '/openapi/json', 0755, true);
79
            mkdir($destination . '/openapi/yaml', 0755, true);
80
            mkdir($destination . '/stubs', 0755, true);
81
        } catch (Exception $e) {
82
            $logger->critical((string)$e);
83
            return Command::FAILURE;
84
        }
85
        $versions = array_keys(
86
            (new ReflectionClass(Versions::class))
87
                ->getConstants()['URLS']
88
        );
89
        $versions = array_diff($versions, ['latest']);
90
        foreach ($versions as $version) {
91
            $output->writeln(sprintf('Generating v%s schemas...', $version));
92
            $filename = 'v' . str_replace('.', '', $version);
93
            try {
94
                $logger->info($version . ': Fetching data...');
95
                $generator = TgScraper::fromVersion($logger, $version);
96
            } catch (Throwable $e) {
97
                $logger->critical((string)$e);
98
                return Command::FAILURE;
99
            }
100
            $versionReplacer->call($generator, $version);
101
            $custom = $generator->toArray();
102
            $postman = $generator->toPostman();
103
            $openapi = $generator->toOpenApi();
104
            try {
105
                $logger->info($version . ': Creating stubs...');
106
                $generator->toStubs("$destination/tmp", $input->getOption('namespace-prefix'));
107
            } catch (Exception) {
108
                $logger->critical($version . ': Could not create stubs.');
109
                return Command::FAILURE;
110
            }
111
            $logger->info($version . ': Compressing stubs...');
112
            $zip = new PharData("$destination/stubs/$filename.zip");
113
            $zip->buildFromDirectory("$destination/tmp");
114
            self::rrmdir("$destination/tmp");
115
            $logger->info($version . ': Saving schemas...');
116
            if ($this->saveFile(
117
                    $logger,
118
                    $output,
119
                    "$destination/custom/json/$filename.json",
120
                    Encoder::toJson($custom, readable: $readable),
121
                    sprintf('v%s custom (JSON): ', $version)
122
                ) !== Command::SUCCESS) {
123
                return Command::FAILURE;
124
            }
125
            if ($this->saveFile(
126
                    $logger,
127
                    $output,
128
                    "$destination/custom/yaml/$filename.yaml",
129
                    Encoder::toYaml($custom),
130
                    sprintf('v%s custom (YAML): ', $version)
131
                ) !== Command::SUCCESS) {
132
                return Command::FAILURE;
133
            }
134
            if ($this->saveFile(
135
                    $logger,
136
                    $output,
137
                    "$destination/postman/$filename.json",
138
                    Encoder::toJson($postman, readable: $readable),
139
                    sprintf('v%s Postman: ', $version)
140
                ) !== Command::SUCCESS) {
141
                return Command::FAILURE;
142
            }
143
            if ($this->saveFile(
144
                    $logger,
145
                    $output,
146
                    "$destination/openapi/json/$filename.json",
147
                    Encoder::toJson($openapi, readable: $readable),
148
                    sprintf('v%s OpenAPI (JSON): ', $version)
149
                ) !== Command::SUCCESS) {
150
                return Command::FAILURE;
151
            }
152
            if ($this->saveFile(
153
                    $logger,
154
                    $output,
155
                    "$destination/openapi/yaml/$filename.yaml",
156
                    Encoder::toYaml($openapi),
157
                    sprintf('v%s OpenAPI (YAML): ', $version)
158
                ) !== Command::SUCCESS) {
159
                return Command::FAILURE;
160
            }
161
            $logger->info($version . ': Done!');
162
        }
163
        $output->writeln('Done!');
164
        return Command::SUCCESS;
165
    }
166
167
}