DoAnalyze   C
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 20

Importance

Changes 4
Bugs 1 Features 0
Metric Value
wmc 9
c 4
b 1
f 0
lcom 1
cbo 20
dl 0
loc 141
rs 6.4706

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
C execute() 0 81 8
1
<?php
2
3
/*
4
 * (c) Jean-François Lépine <https://twitter.com/Halleck45>
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Hal\Application\Command\Job;
11
use Hal\Application\Command\Job\Analyze\CardAndAgrestiAnalyzer;
12
use Hal\Application\Command\Job\Analyze\CouplingAnalyzer;
13
use Hal\Application\Command\Job\Analyze\FileAnalyzer;
14
use Hal\Application\Command\Job\Analyze\LcomAnalyzer;
15
use Hal\Component\Compatibility\PhpCompatibility;
16
use Hal\Component\Cache\CacheMemory;
17
use Hal\Component\File\Finder;
18
use Hal\Component\File\SyntaxChecker;
19
use Hal\Component\OOP\Extractor\ClassMap;
20
use Hal\Component\OOP\Extractor\Extractor;
21
use Hal\Component\Result\ResultCollection;
22
use Hal\Component\Token\NoTokenizableException;
23
use Hal\Component\Token\Tokenizer;
24
use Symfony\Component\Console\Helper\ProgressBar;
25
use Symfony\Component\Console\Output\OutputInterface;
26
27
28
/**
29
 * Starts analyze
30
 *
31
 * @author Jean-François Lépine <https://twitter.com/Halleck45>
32
 */
33
class DoAnalyze implements JobInterface
34
{
35
36
    /**
37
     * Path to analyze
38
     *
39
     * @var string
40
     */
41
    private $path;
42
43
    /**
44
     * Output
45
     *
46
     * @var \Symfony\Component\Console\Output\OutputInterface
47
     */
48
    private $output;
49
50
    /**
51
     * Finder
52
     *
53
     * @var Finder
54
     */
55
    private $finder;
56
57
    /**
58
     * do OOP analyze ?
59
     *
60
     * @var bool
61
     */
62
    private $withOOP;
63
64
    /**
65
     * Ignore errors ?
66
     * @var bool
67
     */
68
    private $ignoreErrors;
69
70
    /**
71
     * Constructor
72
     *
73
     * @param OutputInterface $output
74
     * @param Finder $finder
75
     * @param string $path
76
     * @param bool $withOOP
77
     * @param bool $ignoreErrors
78
     */
79
    public function __construct(OutputInterface $output, Finder $finder, $path, $withOOP, $ignoreErrors = false)
80
    {
81
        $this->output = $output;
82
        $this->finder = $finder;
83
        $this->path = $path;
84
        $this->withOOP = $withOOP;
85
        $this->ignoreErrors = $ignoreErrors;
86
    }
87
88
    /**
89
     * @inheritdoc
90
     */
91
    public function execute(ResultCollection $collection, ResultCollection $aggregatedResults) {
92
93
        $files = $this->finder->find($this->path);
94
95
        if(0 == sizeof($files, COUNT_NORMAL)) {
96
            throw new \LogicException('No file found');
97
        }
98
99
        $progress = new ProgressBar($this->output);
100
        $progress->start(sizeof($files, COUNT_NORMAL));
101
102
        // tools
103
        $classMap = new ClassMap();
104
        $tokenizer = new Tokenizer(new CacheMemory());
105
        $syntaxChecker = new SyntaxChecker();
106
107
        $fileAnalyzer = new FileAnalyzer(
108
            $this->output
109
            , $this->withOOP
110
            , new Extractor($tokenizer)
111
            , new \Hal\Metrics\Complexity\Text\Halstead\Halstead($tokenizer, new \Hal\Component\Token\TokenType())
112
            , new \Hal\Metrics\Complexity\Text\Length\Loc($tokenizer)
113
            , new \Hal\Metrics\Design\Component\MaintainabilityIndex\MaintainabilityIndex()
114
            , new \Hal\Metrics\Complexity\Component\McCabe\McCabe($tokenizer)
115
            , new \Hal\Metrics\Complexity\Component\Myer\Myer($tokenizer)
116
            , $classMap
117
        );
118
119
        foreach($files as $k => $filename) {
120
121
            $progress->advance();
122
123
            // Integrity
124
            if(!$this->ignoreErrors && !$syntaxChecker->isCorrect($filename)) {
125
                $this->output->writeln(sprintf('<error>file %s is not valid and has been skipped</error>', $filename));
126
                unset($files[$k]);
127
                continue;
128
            }
129
130
            // Analyze
131
            try {
132
                $resultSet = $fileAnalyzer->execute($filename);
133
            } catch(NoTokenizableException $e) {
134
                $this->output->writeln(sprintf("<error>file %s has been skipped: \n%s</error>", $filename, $e->getMessage()));
135
                unset($files[$k]);
136
                continue;
137
            } catch (\Exception $e) {
138
                throw new \Exception(
139
                    (
140
                        sprintf("a '%s' exception occured analyzing file %s\nMessage: %s", get_class($e), $filename, $e->getMessage())
141
                        . sprintf("\n------------\nStack:\n%s", $e->getTraceAsString())
142
                        . sprintf("\n------------\nDo not hesitate to report a bug: https://github.com/Halleck45/PhpMetrics/issues")
143
                    )
144
                , 0, $e->getPrevious());
145
            }
146
147
            $collection->push($resultSet);
148
        }
149
150
        $progress->clear();
151
        $progress->finish();
152
153
154
        if($this->withOOP) {
155
            // COUPLING (should be done after parsing files)
156
            $this->output->write(str_pad("\x0DAnalyzing coupling. This will take few minutes...", 80, "\x20"));
157
            $couplingAnalyzer = new CouplingAnalyzer($classMap, $collection);
158
            $couplingAnalyzer->execute($files);
159
160
            // LCOM (should be done after parsing files)
161
            $this->output->write(str_pad("\x0DLack of cohesion of method (lcom). This will take few minutes...", 80, "\x20"));
162
            $lcomAnalyzer = new LcomAnalyzer($classMap, $collection);
163
            $lcomAnalyzer->execute($files);
164
165
            // Card and Agresti (should be done after parsing files)
166
            $this->output->write(str_pad("\x0DAnalyzing System complexity. This will take few minutes...", 80, "\x20"));
167
            $lcomAnalyzer = new CardAndAgrestiAnalyzer($classMap, $collection);
168
            $lcomAnalyzer->execute($files);
169
        }
170
171
    }
172
173
}
174