Completed
Pull Request — master (#202)
by personal
03:02
created

RunMetricsCommand::execute()   C

Complexity

Conditions 10
Paths 19

Size

Total Lines 73
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 3 Features 1
Metric Value
c 4
b 3
f 1
dl 0
loc 73
rs 5.8564
cc 10
eloc 42
nc 19
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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;
11
use Hal\Application\Command\Job\QueueAnalyzeFactory;
12
use Hal\Application\Command\Job\QueueFactory;
13
use Hal\Application\Command\Job\QueueReportFactory;
14
use Hal\Application\Config\ConfigFactory;
15
use Hal\Application\Extension\ExtensionService;
16
use Hal\Application\Extension\Repository;
17
use Hal\Component\Bounds\Bounds;
18
use Hal\Component\Evaluation\Evaluator;
19
use Hal\Component\File\Finder;
20
use Symfony\Component\Console\Command\Command;
21
use Symfony\Component\Console\Input\InputArgument;
22
use Symfony\Component\Console\Input\InputInterface;
23
use Symfony\Component\Console\Input\InputOption;
24
use Symfony\Component\Console\Output\OutputInterface;
25
26
/**
27
 * Command for run analysis
28
 *
29
 * @author Jean-François Lépine <https://twitter.com/Halleck45>
30
 */
31
class RunMetricsCommand extends Command
32
{
33
    /**
34
     * @inheritdoc
35
     */
36
    protected function configure()
37
    {
38
        $this
39
                ->setName('metrics')
40
                ->setDescription('Run analysis')
41
                ->addArgument(
42
                    'path', InputArgument::OPTIONAL, 'Path to explore'
43
                )
44
                ->addOption(
45
                    'report-html',null, InputOption::VALUE_REQUIRED, 'Path to save report in HTML format. Example: /tmp/report.html'
46
                )
47
                ->addOption(
48
                    'report-xml', null, InputOption::VALUE_REQUIRED, 'Path to save summary report in XML format. Example: /tmp/report.xml'
49
                )
50
                ->addOption(
51
                    'report-cli', null, InputOption::VALUE_NONE, 'Enable report in terminal'
52
                )
53
                ->addOption(
54
                    'violations-xml', null, InputOption::VALUE_REQUIRED, 'Path to save violations in XML format. Example: /tmp/report.xml'
55
                )
56
                ->addOption(
57
                    'report-csv', null, InputOption::VALUE_REQUIRED, 'Path to save summary report in CSV format. Example: /tmp/report.csv'
58
                )
59
                ->addOption(
60
                    'report-json', null, InputOption::VALUE_REQUIRED, 'Path to save detailed report in JSON format. Example: /tmp/report.json'
61
                )
62
                ->addOption(
63
                    'chart-bubbles', null, InputOption::VALUE_REQUIRED, 'Path to save Bubbles chart, in SVG format. Example: /tmp/chart.svg. Graphviz **IS** required'
64
                )
65
                ->addOption(
66
                    'level', null, InputOption::VALUE_REQUIRED, 'Depth of summary report', 0
67
                )
68
                ->addOption(
69
                    'extensions', null, InputOption::VALUE_REQUIRED, 'Regex of extensions to include', null
70
                )
71
                ->addOption(
72
                    'excluded-dirs', null, InputOption::VALUE_REQUIRED, 'Regex of subdirectories to exclude', null
73
                )
74
                ->addOption(
75
                    'symlinks', null, InputOption::VALUE_NONE, 'Enable following symlinks'
76
                )
77
                ->addOption(
78
                    'without-oop', null, InputOption::VALUE_NONE, 'If provided, tool will not extract any information about OOP model (faster)'
79
                )
80
                ->addOption(
81
                    'ignore-errors', null, InputOption::VALUE_NONE, 'If provided, files will be analyzed even with syntax errors'
82
                )
83
                ->addOption(
84
                    'failure-condition', null, InputOption::VALUE_REQUIRED, 'Optional failure condition, in english. For example: average.maintainabilityIndex < 50 or sum.loc > 10000', null
85
                )
86
                ->addOption(
87
                    'config', null, InputOption::VALUE_REQUIRED, 'Config file (YAML)', null
88
                )
89
                ->addOption(
90
                    'template-title', null, InputOption::VALUE_REQUIRED, 'Title for the HTML summary report', null
91
                )
92
                ->addOption(
93
                    'offline', null, InputOption::VALUE_NONE, 'Include all JavaScript and CSS files in HTML. Generated report will be bigger'
94
                )
95
                ->addOption(
96
                    'plugins', null, InputOption::VALUE_REQUIRED, 'Path of extensions to load, separated by comma (,)'
97
                )
98
        ;
99
    }
100
101
    /**
102
     * @inheritdoc
103
     */
104
    protected function execute(InputInterface $input, OutputInterface $output)
105
    {
106
107
        $output->writeln('PHPMetrics by Jean-François Lépine <https://twitter.com/Halleck45>');
108
        $output->writeln('');
109
110
        // config
111
        $configFactory = new ConfigFactory();
112
        $config = $configFactory->factory($input);
113
114
        // files
115
        if(null === $config->getPath()->getBasePath()) {
116
            throw new \LogicException('Please provide a path to analyze');
117
        }
118
119
        // files to analyze
120
        $finder = new Finder(
121
            $config->getPath()->getExtensions()
122
            , $config->getPath()->getExcludedDirs()
123
            , $config->getPath()->isFollowSymlinks() ? Finder::FOLLOW_SYMLINKS : null
124
        );
125
126
        // prepare plugins
127
        $repository = new Repository();
128
        foreach($config->getExtensions()->getExtensions() as $filename) {
0 ignored issues
show
Bug introduced by
The method getExtensions cannot be called on $config->getExtensions() (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
129
            if(!file_exists($filename) ||!is_readable($filename)) {
130
                $output->writeln(sprintf('<error>Plugin %s skipped: not found</error>', $filename));
131
                continue;
132
            }
133
            $plugin = require_once($filename);
134
            $repository->attach($plugin);
135
        }
136
        $extensionService = new ExtensionService($repository);
137
138
        // prepare structures
139
        $bounds = new Bounds();
140
        $collection = new \Hal\Component\Result\ResultCollection();
141
        $aggregatedResults = new \Hal\Component\Result\ResultCollection();
142
143
        // execute analyze
144
        $queueFactory = new QueueAnalyzeFactory($input, $output, $config, $extensionService);
145
        $queue = $queueFactory->factory($finder, $bounds);
146
        gc_disable();
147
        $queue->execute($collection, $aggregatedResults);
148
        gc_enable();
149
150
        $output->writeln('');
151
152
        // provide data to extensions
153
        if(($n = sizeof($repository->all())) > 0) {
154
            $output->writeln(sprintf('%d %s. Executing analyzis', $n, ($n > 1 ? 'plugins are enabled' : 'plugin is enabled') ));
155
            $extensionService->receive($config, $collection, $aggregatedResults, $bounds);
156
        }
157
158
        // generating reports
159
        $output->writeln("Generating reports...");
160
        $queueFactory = new QueueReportFactory($input, $output, $config, $extensionService);
161
        $queue = $queueFactory->factory($finder, $bounds);
162
        $queue->execute($collection, $aggregatedResults);
163
164
        $output->writeln('<info>Done</info>');
165
166
        // evaluation of success
167
        $rule = $config->getFailureCondition();
168
        if(null !== $rule) {
169
            $evaluator = new Evaluator($collection, $aggregatedResults, $bounds);
170
            $result = $evaluator->evaluate($rule);
171
            // fail if failure-condition is realized
172
            return $result->isValid() ? 1 : 0;
173
        }
174
175
        return 0;
176
    }
177
178
}
179