Test Failed
Push — main ( dcdb43...82a4c2 )
by mikhail
03:16
created

CommentDensity::removeUnusedStatistics()   A

Complexity

Conditions 6
Paths 10

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 8
c 1
b 0
f 0
nc 10
nop 2
dl 0
loc 13
ccs 9
cts 9
cp 1
crap 6
rs 9.2222
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SavinMikhail\CommentsDensity;
6
7
use SavinMikhail\CommentsDensity\Comments\CommentFactory;
8
use SavinMikhail\CommentsDensity\Comments\CommentTypeInterface;
9
use SavinMikhail\CommentsDensity\DTO\Input\ConfigDTO;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\CommentsDensity\DTO\Input\ConfigDTO was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use SavinMikhail\CommentsDensity\DTO\Output\CommentDTO;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\CommentsDensity\DTO\Output\CommentDTO was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use SavinMikhail\CommentsDensity\DTO\Output\CommentStatisticsDTO;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\CommentsDen...ut\CommentStatisticsDTO was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use SavinMikhail\CommentsDensity\DTO\Output\OutputDTO;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\CommentsDensity\DTO\Output\OutputDTO was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use SavinMikhail\CommentsDensity\Metrics\Metrics;
0 ignored issues
show
Bug introduced by
The type SavinMikhail\CommentsDensity\Metrics\Metrics was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use SavinMikhail\CommentsDensity\Reporters\ReporterInterface;
15
use SplFileInfo;
16
17
use function array_keys;
18
use function in_array;
19
20
final class CommentDensity
21
{
22
    private bool $exceedThreshold = false;
23 5
24
    public function __construct(
25
        private readonly ConfigDTO $configDTO,
26
        private readonly CommentFactory $commentFactory,
27
        private readonly FileAnalyzer $fileAnalyzer,
0 ignored issues
show
Bug introduced by
The type SavinMikhail\CommentsDensity\FileAnalyzer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
        private readonly ReporterInterface $reporter,
29
        private readonly MissingDocBlockAnalyzer $missingDocBlock,
30
        private readonly Metrics $metrics,
31 5
    ) {
32
    }
33 1
34
    public function analyzeFiles(array $files): bool
35 1
    {
36 1
        return $this->analyze($files);
37
    }
38
39 2
    private function analyze(array $files): bool
40
    {
41 2
        $this->metrics->startPerformanceMonitoring();
42 2
        $comments = [];
43
        $commentStatistics = [];
44
        $totalLinesOfCode = 0;
45 1
        $cdsSum = 0;
46
        $filesAnalyzed = 0;
47 1
48 1
        foreach ($files as $file) {
49 1
            if (! ($file instanceof SplFileInfo)) {
50 1
                continue;
51 1
            }
52
            if ($this->isInWhitelist($file->getRealPath())) {
53
                continue;
54 1
            }
55
            $this->fileAnalyzer->analyzeFile(
56
                $file,
57 3
                $commentStatistics,
58
                $comments,
59 3
                $totalLinesOfCode,
60 3
                $cdsSum
61 3
            );
62 3
            $filesAnalyzed++;
63 3
        }
64 3
65
        $this->metrics->stopPerformanceMonitoring();
66 3
67 3
        $this->removeUnusedStatistics($comments, $commentStatistics);
68 3
69 3
        $outputDTO = $this->createOutputDTO(
70 3
            $comments,
71 3
            $commentStatistics,
72 3
            $totalLinesOfCode,
73 3
            $cdsSum / $totalLinesOfCode,
74 3
            $filesAnalyzed,
75 3
        );
76
77
        $this->reporter->report($outputDTO);
78
79 3
        return $this->exceedThreshold;
80
    }
81 3
82 3
    protected function removeUnusedStatistics(array &$comments, array &$commentStatistics): void
83 3
    {
84 3
        if (! $this->configDTO->only) {
85 3
            return;
86 3
        }
87 3
        foreach ($comments as $key => $comment) {
88
            if (! in_array((string) $comment['type'], $this->configDTO->only)) {
89 3
                unset($comments[$key]);
90
            }
91 3
        }
92
        foreach (array_keys($commentStatistics) as $commentType) {
93
            if (! in_array($commentType, $this->configDTO->only)) {
94 3
                unset($commentStatistics[$commentType]);
95
            }
96
        }
97
    }
98
99
    private function createOutputDTO(
100
        array $comments,
101 3
        array $commentStatistics,
102 3
        int $linesOfCode,
103 3
        float $cds,
104 3
        int $filesAnalyzed,
105 3
    ): OutputDTO {
106 3
        $outputDTO = new OutputDTO(
107 3
            $filesAnalyzed,
108 3
            $this->prepareCommentStatistics($commentStatistics),
109 3
            $this->prepareComments($comments),
110 1
            $this->metrics->getPerformanceMetrics(),
111
            $this->metrics->prepareComToLoc($commentStatistics, $linesOfCode),
112 3
            $this->metrics->prepareCDS($cds)
113
        );
114
        if ($this->metrics->hasExceededThreshold()) {
115 3
            $this->exceedThreshold = true;
116
        }
117 3
        return $outputDTO;
118 3
    }
119 3
120 3
    private function prepareCommentStatistics(array $commentStatistics): array
121 3
    {
122 3
        $preparedStatistics = [];
123 3
        foreach ($commentStatistics as $type => $count) {
124 3
            if ($type === 'missingDocblock') {
125 3
                $preparedStatistics[] = new CommentStatisticsDTO(
126 3
                    $this->missingDocBlock->getColor(),
127
                    $this->missingDocBlock->getName(),
128
                    $count,
129 3
                    $this->missingDocBlock->getStatColor($count, $this->configDTO->thresholds)
130
                );
131 3
                if ($this->missingDocBlock->hasExceededThreshold()) {
132 3
                    $this->exceedThreshold = true;
133 3
                }
134 3
                continue;
135 3
            }
136 3
            $commentType = $this->commentFactory->getCommentType($type);
137 3
            if ($commentType) {
138 3
                $preparedStatistics[] = new CommentStatisticsDTO(
139 3
                    $commentType->getColor(),
140
                    $commentType->getName(),
141
                    $count,
142
                    $commentType->getStatColor($count, $this->configDTO->thresholds)
143
                );
144 3
                if ($commentType->hasExceededThreshold()) {
145
                    $this->exceedThreshold = true;
146
                }
147 3
            }
148
        }
149 3
        return $preparedStatistics;
150 3
    }
151
152 3
    private function prepareComments(array $comments): array
153 3
    {
154
        $preparedComments = [];
155
        foreach ($comments as $comment) {
156
            /** @var CommentTypeInterface|string $commentType */
157
            $commentType = $comment['type'];
158
            if ($commentType === 'missingDocblock') {
159
                $preparedComments[] = new CommentDTO(
160
                    'missingDocblock',
161
                    'red',
162
                    $comment['file'],
163 3
                    $comment['line'],
164 1
                    $comment['content']
165
                );
166 3
                continue;
167 3
            }
168 3
            if ($commentType->getAttitude() === 'good') {
169 3
                continue;
170 3
            }
171 3
            $preparedComments[] = new CommentDTO(
172 3
                $commentType->getName(),
173
                $commentType->getColor(),
174 3
                $comment['file'],
175
                $comment['line'],
176
                $comment['content']
177 3
            );
178
        }
179 3
        return $preparedComments;
180
    }
181
182
    private function isInWhitelist(string $filePath): bool
183
    {
184 3
        foreach ($this->configDTO->exclude as $whitelistedDir) {
185
            if (str_contains($filePath, $whitelistedDir)) {
186
                return true;
187
            }
188
        }
189
        return false;
190
    }
191
}
192