Completed
Pull Request — master (#283)
by Enrico
04:27
created

CompileCommand   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 90.48%

Importance

Changes 0
Metric Value
dl 0
loc 120
ccs 57
cts 63
cp 0.9048
rs 10
c 0
b 0
f 0
wmc 13
lcom 1
cbo 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 7 1
C execute() 0 85 10
A getCompiler() 0 4 1
A getMemoryUsage() 0 4 1
1
<?php
2
3
namespace PHPSA\Command;
4
5
use PhpParser\ParserFactory;
6
use PHPSA\Application;
7
use PHPSA\Compiler;
8
use PHPSA\Context;
9
use PHPSA\Definition\FileParser;
10
use RecursiveDirectoryIterator;
11
use RecursiveIteratorIterator;
12
use SplFileInfo;
13
use FilesystemIterator;
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\Output\OutputInterface;
18
use Webiny\Component\EventManager\EventManager;
19
20
/**
21
 * Command to run compiler on files (no analyzer)
22
 */
23
class CompileCommand extends Command
24
{
25
26
    /**
27
     * {@inheritdoc}
28
     */
29 886
    protected function configure()
30
    {
31 886
        $this
32 886
            ->setName('compile')
33 886
            ->setDescription('Runs compiler on all files in path')
34 886
            ->addArgument('path', InputArgument::OPTIONAL, 'Path to check file or directory', '.');
35 886
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40 1
    protected function execute(InputInterface $input, OutputInterface $output)
41
    {
42 1
        $output->writeln('');
43
44 1
        if (extension_loaded('xdebug')) {
45
            /**
46
             * This will disable only showing stack traces on error conditions.
47
             */
48 1
            if (function_exists('xdebug_disable')) {
49 1
                xdebug_disable();
50 1
            }
51
52 1
            $output->writeln('<error>It is highly recommended to disable the XDebug extension before invoking this command.</error>');
53 1
        }
54
55 1
        $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7, new \PhpParser\Lexer\Emulative([
56
            'usedAttributes' => [
57 1
                'comments',
58 1
                'startLine',
59 1
                'endLine',
60 1
                'startTokenPos',
61
                'endTokenPos'
62 1
            ]
63 1
        ]));
64
65
        /** @var Application $application */
66 1
        $application = $this->getApplication();
67 1
        $application->compiler = new Compiler();
68
69 1
        $em = EventManager::getInstance();
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $em. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
70 1
        $context = new Context($output, $application, $em);
71
72 1
        $fileParser = new FileParser(
73 1
            $parser,
74 1
            $this->getCompiler()
75 1
        );
76
77 1
        $path = $input->getArgument('path');
78 1
        if (is_dir($path)) {
79 1
            $directoryIterator = new RecursiveIteratorIterator(
80 1
                new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)
81 1
            );
82 1
            $output->writeln('Scanning directory <info>' . $path . '</info>');
83
84 1
            $count = 0;
85
86
            /** @var SplFileInfo $file */
87 1
            foreach ($directoryIterator as $file) {
88 1
                if ($file->getExtension() !== 'php') {
89
                    continue;
90
                }
91
92 1
                $context->debug($file->getPathname());
93 1
                $count++;
94 1
            }
95
96 1
            $output->writeln("Found <info>{$count} files</info>");
97
98 1
            if ($count > 100) {
99
                $output->writeln('<comment>Caution: You are trying to scan a lot of files; this might be slow. For bigger libraries, consider setting up a dedicated platform or using ci.lowl.io.</comment>');
100
            }
101
102 1
            $output->writeln('');
103
104
            /** @var SplFileInfo $file */
105 1
            foreach ($directoryIterator as $file) {
106 1
                if ($file->getExtension() !== 'php') {
107
                    continue;
108
                }
109
110 1
                $fileParser->parserFile($file->getPathname(), $context);
111 1
            }
112 1
        } elseif (is_file($path)) {
113
            $fileParser->parserFile($path, $context);
114
        }
115
116
117
        /**
118
         * Step 2 Recursive check ...
119
         */
120 1
        $application->compiler->compile($context);
121
122 1
        $output->writeln('');
123 1
        $output->writeln('Memory usage: ' . $this->getMemoryUsage(false) . ' (peak: ' . $this->getMemoryUsage(true) . ') MB');
124 1
    }
125
126
    /**
127
     * @return Compiler
128
     */
129 1
    protected function getCompiler()
130
    {
131 1
        return $this->getApplication()->compiler;
0 ignored issues
show
Bug introduced by
The property compiler does not seem to exist in Symfony\Component\Console\Application.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
132
    }
133
134
    /**
135
     * @param boolean $type
136
     * @return float
137
     */
138 1
    protected function getMemoryUsage($type)
139
    {
140 1
        return round(memory_get_usage($type) / 1024 / 1024, 2);
141
    }
142
}
143