Passed
Push — master ( 137960...4d87d9 )
by Sys
11:11
created

ExportSchemaCommand::saveFile()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
c 0
b 0
f 0
dl 0
loc 9
rs 10
cc 2
nc 2
nop 4
1
<?php
2
3
4
namespace TgScraper\Commands;
5
6
7
use Exception;
8
use Psr\Log\LoggerInterface;
9
use Symfony\Component\Console\Command\Command;
10
use Symfony\Component\Console\Input\InputArgument;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Input\InputOption;
13
use Symfony\Component\Console\Logger\ConsoleLogger;
14
use Symfony\Component\Console\Output\OutputInterface;
15
use TgScraper\Common\Encoder;
16
use TgScraper\Constants\Versions;
17
use TgScraper\TgScraper;
18
use Throwable;
19
20
class ExportSchemaCommand extends Command
21
{
22
23
    protected static $defaultName = 'app:export-schema';
24
25
    protected function configure(): void
26
    {
27
        $this
28
            ->setDescription('Export schema as JSON or YAML.')
29
            ->setHelp('This command allows you to create a schema for a specific version of the Telegram bot API.')
30
            ->addArgument('destination', InputArgument::REQUIRED, 'Destination file')
31
            ->addOption(
32
                'yaml',
33
                null,
34
                InputOption::VALUE_NONE,
35
                'Export schema as YAML instead of JSON (does not affect "--postman")'
36
            )
37
            ->addOption(
38
                'postman',
39
                null,
40
                InputOption::VALUE_NONE,
41
                'Export schema as a Postman-compatible JSON'
42
            )
43
            ->addOption(
44
                'openapi',
45
                null,
46
                InputOption::VALUE_NONE,
47
                'Export schema as a OpenAPI-compatible file (takes precedence over "--postman")'
48
            )
49
            ->addOption('options', 'o', InputOption::VALUE_REQUIRED, 'Encoder options', 0)
50
            ->addOption(
51
                'readable',
52
                'r',
53
                InputOption::VALUE_NONE,
54
                'Generate a human-readable file (overrides "--inline" and "--indent")'
55
            )
56
            ->addOption('inline', null, InputOption::VALUE_REQUIRED, '(YAML only) Inline level', 12)
57
            ->addOption('indent', null, InputOption::VALUE_REQUIRED, '(YAML only) Indent level', 4)
58
            ->addOption('layer', 'l', InputOption::VALUE_REQUIRED, 'Bot API version to use', Versions::LATEST)
59
            ->addOption(
60
                'prefer-stable',
61
                null,
62
                InputOption::VALUE_NONE,
63
                'Prefer latest stable version (takes precedence over "--layer")'
64
            );
65
    }
66
67
    private function saveFile(ConsoleLogger $logger, OutputInterface $output, string $destination, string $data): int
68
    {
69
        $result = file_put_contents($destination, $data);
70
        if (false === $result) {
71
            $logger->critical('Unable to save file to ' . $destination);
72
            return Command::FAILURE;
73
        }
74
        $output->writeln('Done!');
75
        return Command::SUCCESS;
76
    }
77
78
    protected function execute(InputInterface $input, OutputInterface $output): int
79
    {
80
        $logger = new ConsoleLogger($output);
81
        $version = Versions::getVersionFromText($input->getOption('layer'));
82
        if ($input->getOption('prefer-stable')) {
83
            $version = Versions::STABLE;
84
        }
85
        $logger->info('Using version: ' . $version);
86
        try {
87
            $output->writeln('Fetching data for version...');
88
            $generator = TgScraper::fromVersion($logger, $version);
89
        } catch (Throwable) {
90
            return Command::FAILURE;
91
        }
92
        $output->writeln('Exporting schema from data...');
93
        $destination = $input->getArgument('destination');
94
        try {
95
            TgScraper::getTargetDirectory(pathinfo($destination)['dirname']);
96
        } catch (Exception) {
97
            return Command::FAILURE;
98
        }
99
        $readable = $input->getOption('readable');
100
        $options = $input->getOption('options');
101
        $useYaml = $input->getOption('yaml');
102
        $inline = $readable ? 12 : $input->getOption('inline');
103
        $indent = $readable ? 4 : $input->getOption('indent');
104
        $output->writeln('Saving schema to file...');
105
        if ($input->getOption('openapi')) {
106
            $data = $generator->toOpenApi();
107
            if ($useYaml) {
108
                return $this->saveFile($logger, $output, $destination, Encoder::toYaml($data, $inline, $indent, $options));
109
            }
110
            return $this->saveFile($logger, $output, $destination, Encoder::toJson($data, $options, $readable));
111
        }
112
        if ($input->getOption('postman')) {
113
            $data = $generator->toPostman();
114
            return $this->saveFile($logger, $output, $destination, Encoder::toJson($data, $options, $readable));
115
        }
116
        $data = $generator->toArray();
117
        if ($useYaml) {
118
            return $this->saveFile($logger, $output, $destination, Encoder::toYaml($data, $inline, $indent, $options));
119
        }
120
        return $this->saveFile($logger, $output, $destination, Encoder::toJson($data, $options, $readable));
121
    }
122
123
}