Test Failed
Push — main ( 6d127d...41f629 )
by mikhail
13:20
created

CommentDensity::prepareComments()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 28
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 4.128

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 20
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 28
rs 9.6
ccs 16
cts 20
cp 0.8
crap 4.128
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SavinMikhail\CommentsDensity;
6
7
use RecursiveDirectoryIterator;
8
use RecursiveIteratorIterator;
9
use SavinMikhail\CommentsDensity\Comments\CommentFactory;
10
use SavinMikhail\CommentsDensity\Comments\CommentTypeInterface;
11
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...
12
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...
13
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...
14
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...
15
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...
16
use SavinMikhail\CommentsDensity\Reporters\ReporterInterface;
17
use SplFileInfo;
18
19
final class CommentDensity
20
{
21
    private bool $exceedThreshold = false;
22
23 5
    public function __construct(
24
        private readonly ConfigDTO $configDTO,
25
        private readonly CommentFactory $commentFactory,
26
        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...
27
        private readonly ReporterInterface $reporter,
28
        private readonly MissingDocBlockAnalyzer $missingDocBlock,
29
        private readonly Metrics $metrics,
30
    ) {
31 5
    }
32
33 1
    public function analyzeFiles(array $files): bool
34
    {
35 1
        $splFiles = array_map(fn($file) => new SplFileInfo($file), $files);
36 1
        return $this->analyze($splFiles);
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 && !$this->isInWhitelist($file->getRealPath())) {
50 1
                $this->fileAnalyzer->analyzeFile(
51 1
                    $file,
52
                    $commentStatistics,
53
                    $comments,
54 1
                    $totalLinesOfCode,
55
                    $cdsSum
56
                );
57 3
                $filesAnalyzed++;
58
            }
59 3
        }
60 3
61 3
        $this->metrics->stopPerformanceMonitoring();
62 3
63 3
        $outputDTO = $this->createOutputDTO(
64 3
            $comments,
65
            $commentStatistics,
66 3
            $totalLinesOfCode,
67 3
            $cdsSum / $totalLinesOfCode,
68 3
            $filesAnalyzed,
69 3
        );
70 3
71 3
        $this->reporter->report($outputDTO);
72 3
73 3
        return $this->exceedThreshold;
74 3
    }
75 3
76
    private function createOutputDTO(
77
        array $comments,
78
        array $commentStatistics,
79 3
        int $linesOfCode,
80
        float $cds,
81 3
        int $filesAnalyzed,
82 3
    ): OutputDTO {
83 3
        $outputDTO = new OutputDTO(
84 3
            $filesAnalyzed,
85 3
            $this->prepareCommentStatistics($commentStatistics),
86 3
            $this->prepareComments($comments),
87 3
            $this->metrics->getPerformanceMetrics(),
88
            $this->metrics->prepareComToLoc($commentStatistics, $linesOfCode),
89 3
            $this->metrics->prepareCDS($cds)
90
        );
91 3
        if ($this->metrics->hasExceededThreshold()) {
92
            $this->exceedThreshold = true;
93
        }
94 3
        return $outputDTO;
95
    }
96
97
    private function prepareCommentStatistics(array $commentStatistics): array
98
    {
99
        $preparedStatistics = [];
100
        foreach ($commentStatistics as $type => $count) {
101 3
            if ($type === 'missingDocblock') {
102 3
                $preparedStatistics[] = new CommentStatisticsDTO(
103 3
                    $this->missingDocBlock->getColor(),
104 3
                    $this->missingDocBlock->getName(),
105 3
                    $count,
106 3
                    $this->missingDocBlock->getStatColor($count, $this->configDTO->thresholds)
107 3
                );
108 3
                if ($this->missingDocBlock->hasExceededThreshold()) {
109 3
                    $this->exceedThreshold = true;
110 1
                }
111
                continue;
112 3
            }
113
            $commentType = $this->commentFactory->getCommentType($type);
114
            if ($commentType) {
115 3
                $preparedStatistics[] = new CommentStatisticsDTO(
116
                    $commentType->getColor(),
117 3
                    $commentType->getName(),
118 3
                    $count,
119 3
                    $commentType->getStatColor($count, $this->configDTO->thresholds)
120 3
                );
121 3
                if ($commentType->hasExceededThreshold()) {
122 3
                    $this->exceedThreshold = true;
123 3
                }
124 3
            }
125 3
        }
126 3
        return $preparedStatistics;
127
    }
128
129 3
    private function prepareComments(array $comments): array
130
    {
131 3
        $preparedComments = [];
132 3
        foreach ($comments as $comment) {
133 3
            /** @var CommentTypeInterface|string $commentType */
134 3
            $commentType = $comment['type'];
135 3
            if ($commentType === 'missingDocblock') {
136 3
                $preparedComments[] = new CommentDTO(
137 3
                    'missingDocblock',
138 3
                    'red',
139 3
                    $comment['file'],
140
                    $comment['line'],
141
                    $comment['content']
142
                );
143
                continue;
144 3
            }
145
            if ($commentType->getAttitude() === 'good') {
146
                continue;
147 3
            }
148
            $preparedComments[] = new CommentDTO(
149 3
                $commentType->getName(),
150 3
                $commentType->getColor(),
151
                $comment['file'],
152 3
                $comment['line'],
153 3
                $comment['content']
154
            );
155
        }
156
        return $preparedComments;
157
    }
158
159
    private function isInWhitelist(string $filePath): bool
160
    {
161
        foreach ($this->configDTO->exclude as $whitelistedDir) {
162
            if (str_contains($filePath, $whitelistedDir)) {
163 3
                return true;
164 1
            }
165
        }
166 3
        return false;
167 3
    }
168
}
169