Passed
Push — master ( 176455...e166a4 )
by Satoshi
02:24
created

VerifyDependencyCommand::inspectDependencyGraph()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 40
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 27
nc 16
nop 2
dl 0
loc 40
rs 8.8657
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace DependencyAnalyzer\Commands;
5
6
use DependencyAnalyzer\Detector\RuleViolationDetector;
7
use DependencyAnalyzer\Detector\RuleViolationDetector\DependencyRuleFactory;
8
use DependencyAnalyzer\DependencyGraph;
9
use DependencyAnalyzer\Exceptions\InvalidCommandArgumentException;
10
use LucidFrame\Console\ConsoleTable;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Input\InputOption;
13
use Symfony\Component\Console\Output\OutputInterface;
14
15
class VerifyDependencyCommand extends AnalyzeDependencyCommand
16
{
17
    protected $ruleDefinition;
18
19
    protected function getCommandName(): string
20
    {
21
        return 'verify';
22
    }
23
24
    protected function getCommandDescription(): string
25
    {
26
        return 'verify dependency map by rule';
27
    }
28
29
    protected function configure(): void
30
    {
31
        parent::configure();
32
        $this->addOption('rule', 'r', InputOption::VALUE_REQUIRED, 'Rule file');
33
    }
34
35
    protected function initialize(InputInterface $input, OutputInterface $output)
36
    {
37
        parent::initialize($input, $output);
38
39
        $ruleFile = $input->getOption('rule');
40
        if (!is_file($ruleFile)) {
0 ignored issues
show
Bug introduced by
It seems like $ruleFile can also be of type string[]; however, parameter $filename of is_file() does only seem to accept string, 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

40
        if (!is_file(/** @scrutinizer ignore-type */ $ruleFile)) {
Loading history...
41
            throw new InvalidCommandArgumentException(sprintf('rule is not file "%s".', $ruleFile));
0 ignored issues
show
Bug introduced by
It seems like $ruleFile can also be of type string[]; however, parameter $args of sprintf() does only seem to accept string, 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

41
            throw new InvalidCommandArgumentException(sprintf('rule is not file "%s".', /** @scrutinizer ignore-type */ $ruleFile));
Loading history...
42
        }
43
        $this->ruleDefinition = require_once $ruleFile;
44
        if (!is_array($this->ruleDefinition)) {
45
            throw new InvalidCommandArgumentException(sprintf('rule is invalid file "%s".', $ruleFile));
46
        }
47
    }
48
49
    protected function inspectDependencyGraph(DependencyGraph $graph, OutputInterface $output): int
50
    {
51
        $detector = new RuleViolationDetector((new DependencyRuleFactory())->create(array_merge(
52
            $this->ruleDefinition,
53
            $this->createRuleDefinitionFromPhpDoc($graph)
54
        )));
55
        $responses = $detector->inspect($graph);
56
57
        $errorCount = 0;
58
        foreach ($responses as $respons) {
59
            if ($respons->count() > 0) {
60
                $table = (new ConsoleTable())
61
                    ->addHeader('depender')
62
                    ->addHeader('component')
63
                    ->addHeader('')
64
                    ->addHeader('dependee')
65
                    ->addHeader('component');
66
67
                $errorCount += $respons->count();
68
                $output->writeln('');
69
                $output->writeln($respons->getRuleName());
70
                foreach ($respons->getViolations() as $violation) {
71
                    $table->addRow([
72
                        $violation['depender'],
73
                        $violation['dependerComponent'],
74
                        '->',
75
                        $violation['dependee'],
76
                        $violation['dependeeComponent']
77
                    ]);
78
                }
79
80
                $output->write($table->getTable());
81
            }
82
        }
83
84
        if ($errorCount === 0) {
0 ignored issues
show
introduced by
The condition $errorCount === 0 is always true.
Loading history...
85
            $output->write('rule violation is not found.');
86
        }
87
88
        return $errorCount > 0 ? 1 : 0;
89
    }
90
91
    protected function createRuleDefinitionFromPhpDoc(DependencyGraph $graph): array
92
    {
93
        $ruleDefinitions = [];
94
        foreach ($graph->getClassesHaveOnlyUsedTag() as $class => $classesInPhpDoc) {
95
            // TODO: Is '\\' needed?
96
            $targetComponent = [
97
                'define' => ['\\' . $class],
98
                'depender' => $classesInPhpDoc
99
            ];
100
101
            $otherComponent = [
102
                'define' => array_merge(['\\'], array_map(function (string $className) {
103
                    return '!' . $className;
104
                }, $classesInPhpDoc)),
105
            ];
106
107
            $ruleDefinitions['phpdoc in ' . $class] = [
108
                'phpdoc' => $targetComponent,
109
                'other' => $otherComponent
110
            ];
111
        }
112
113
        return $ruleDefinitions;
114
    }
115
}
116