Test Setup Failed
Push — master ( a5ba65...160652 )
by Nikita
08:48
created

GenerateCommand::execute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 10
nc 1
nop 2
1
<?php
2
/**
3
 * This file is part of PHP-Yacc package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace PhpYacc\Console;
11
12
use PhpYacc\Generator;
13
use PhpYacc\Grammar\Context;
14
use Symfony\Component\Console\Command\Command;
15
use Symfony\Component\Console\Exception\InvalidArgumentException;
16
use Symfony\Component\Console\Exception\InvalidOptionException;
17
use Symfony\Component\Console\Exception\RuntimeException;
18
use Symfony\Component\Console\Input\InputArgument;
19
use Symfony\Component\Console\Input\InputInterface;
20
use Symfony\Component\Console\Input\InputOption;
21
use Symfony\Component\Console\Output\OutputInterface;
22
23
/**
24
 * Class GenerateCommand
25
 */
26
class GenerateCommand extends Command
27
{
28
    /**
29
     * @return void
30
     */
31
    public function configure(): void
32
    {
33
        $this->setName('generate');
34
        $this->setDescription('The command to generate a parser.');
35
        $this->addArgument('grammar', InputArgument::REQUIRED, 'Grammar file.');
36
37
        $this->addOption('skeleton', 's', InputOption::VALUE_REQUIRED, 'Specify the skeleton to use.');
38
        $this->addOption('output', 'o', InputOption::VALUE_REQUIRED, 'Leave output to file.');
39
        $this->addOption('class', 'c', InputOption::VALUE_REQUIRED, 'Parser class name.', 'YaccParser');
40
    }
41
42
    /**
43
     * @param InputInterface $input
44
     * @param OutputInterface $output
45
     * @return void
46
     */
47
    public function execute(InputInterface $input, OutputInterface $output): void
48
    {
49
        $this->validateInput($input);
50
51
        $grammar = $input->getArgument('grammar');
52
        $skeleton = $input->getOption('skeleton');
53
        $class = $input->getOption('class');
54
        $result = $input->getOption('output') ?? \sprintf('.%s%s.php', DIRECTORY_SEPARATOR, $class);
55
56
        $context = new Context(\basename($grammar));
57
        $context->className = $class;
58
59
        $this->generate($context, $grammar, $skeleton, $result);
60
        $output->writeln('<info>OK</info>');
61
    }
62
63
    /**
64
     * @param InputInterface $input
65
     * @return void
66
     */
67
    private function validateInput(InputInterface $input): void
68
    {
69
        $skeleton = $input->getOption('skeleton');
70
        if ($skeleton === null || ! \file_exists($skeleton)) {
71
            throw new InvalidOptionException(\sprintf('The skeleton file "%s" is not found', $skeleton));
72
        }
73
74
        $grammar = $input->getArgument('grammar');
75
        if (! \file_exists($grammar)) {
76
            throw new InvalidArgumentException(\sprintf('The grammar file "%s" is not found', $grammar));
77
        }
78
    }
79
80
    /**
81
     * @param Context $context
82
     * @param string $grammar
83
     * @param string $skeleton
84
     * @param string $result
85
     * @return void
86
     */
87
    private function generate(Context $context, string $grammar, string $skeleton, string $result): void
88
    {
89
        $generator = new Generator();
90
        try {
91
            $generator->generate($context, \file_get_contents($grammar), \file_get_contents($skeleton), $result);
92
        } catch (\Exception $e) {
93
            throw new RuntimeException($e->getMessage());
94
        }
95
    }
96
}
97