Passed
Branch master (f3f280)
by Maciej
03:18
created

RegenerateCommand::execute()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 32
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
cc 6
eloc 18
nc 5
nop 2
dl 0
loc 32
rs 9.0444
c 3
b 0
f 1
1
<?php
2
3
namespace Kadet\Highlighter\bin\Commands\Test;
4
5
use Kadet\Highlighter\Formatter\FormatterInterface;
6
use Kadet\Highlighter\KeyLighter;
7
use Kadet\Highlighter\Language\Language;
8
use Kadet\Highlighter\Parser\Tokens;
9
use Kadet\Highlighter\Tests\Helpers\TestFormatter;
10
use Kadet\Highlighter\Utils\StringHelper;
11
use RecursiveDirectoryIterator;
12
use RecursiveIteratorIterator;
13
use SplFileInfo;
14
use Symfony\Component\Console\Command\Command;
15
use Symfony\Component\Console\Input\InputArgument;
16
use Symfony\Component\Console\Input\InputInterface;
17
use Symfony\Component\Console\Input\InputOption;
18
use Symfony\Component\Console\Output\OutputInterface;
19
use Symfony\Component\Console\Question\ConfirmationQuestion;
20
21
class RegenerateCommand extends Command
22
{
23
    /**
24
     * @var KeyLighter
25
     */
26
    private $_keylighter;
27
    /** @var FormatterInterface */
28
    private $_formatter;
29
30
    private $_input;
31
    private $_output;
32
33
    protected function configure()
34
    {
35
        $this->setName('test:regenerate')
36
            ->addArgument('files', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'tests to regenerate', ['*'])
37
            ->addOption('new', null, InputOption::VALUE_NONE, 'generate only new files')
38
            ->addOption('review', 'r', InputOption::VALUE_OPTIONAL, 'review generated files')
39
            ->setDescription('Regenerates test files')
40
        ;
41
42
        $this->_keylighter = KeyLighter::get();
43
        $this->_formatter  = new TestFormatter();
44
45
        $this->_input  = realpath(__DIR__ . '/../../../Tests/Samples');
46
        $this->_output = realpath(__DIR__ . '/../../../Tests/Expected/Test');
47
    }
48
49
    protected function execute(InputInterface $input, OutputInterface $output)
50
    {
51
        $iterator = new RecursiveIteratorIterator(
52
            new RecursiveDirectoryIterator(
53
                $this->_input,
54
                RecursiveDirectoryIterator::SKIP_DOTS | RecursiveDirectoryIterator::UNIX_PATHS
55
            ),
56
            RecursiveIteratorIterator::LEAVES_ONLY
57
        );
58
59
        $reviewer = $this->_keylighter->getFormatter($input->getOption('review') ?: 'cli');
60
61
        /** @var SplFileInfo $file */
62
        foreach ($iterator as $file) {
63
            $pathname = substr($file->getPathname(), strlen($this->_input) + 1);
64
            if (!$this->regenerate($input, $pathname)) {
65
                continue;
66
            }
67
68
            $output->writeln("Generating $pathname...", OutputInterface::VERBOSITY_QUIET);
69
70
            $language = Language::byFilename($pathname);
71
            $tokens   = $language->parse(file_get_contents($file->getPathname()));
72
73
            if ($this->review($input, $output, $tokens, $reviewer)) {
0 ignored issues
show
Bug introduced by
It seems like $reviewer can also be of type false; however, parameter $reviewer of Kadet\Highlighter\bin\Co...nerateCommand::review() does only seem to accept Kadet\Highlighter\Formatter\FormatterInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

73
            if ($this->review($input, $output, $tokens, /** @scrutinizer ignore-type */ $reviewer)) {
Loading history...
74
                $result = StringHelper::normalize($this->_formatter->format($tokens));
75
76
                if (!file_exists($this->_output . '/' . dirname($pathname))) {
77
                    mkdir($this->_output . '/' . dirname($pathname), 0755, true);
78
                }
79
80
                file_put_contents("{$this->_output}/$pathname.tkn", $result);
81
            }
82
        }
83
    }
84
85
    private function review(InputInterface $input, OutputInterface $output, Tokens $tokens, FormatterInterface $reviewer)
86
    {
87
        if (!$this->shouldReview($input)) {
88
            return true;
89
        }
90
91
        $result = $reviewer->format($tokens);
92
        $output->writeln($result);
93
94
        $question = new ConfirmationQuestion('Does it look right? ');
95
        return $this->getHelper('question')->ask($input, $output, $question);
96
    }
97
98
    private function shouldReview(InputInterface $input)
99
    {
100
        return $input->hasParameterOption('--review')
101
            || $input->hasParameterOption('-r');
102
    }
103
104
    private function regenerate(InputInterface $input, $filename)
105
    {
106
        $filename = str_replace(DIRECTORY_SEPARATOR, '/', $filename);
107
        $patterns = $input->getArgument('files');
108
109
        foreach ($patterns as $pattern) {
110
            if ($input->getOption('new') && file_exists("{$this->_output}/$filename.tkn")) {
111
                continue;
112
            }
113
114
            if (fnmatch($pattern, $filename)) {
115
                return true;
116
            }
117
        }
118
119
        return false;
120
    }
121
}
122