Passed
Push — main ( d846f8...8b63c1 )
by mikhail
04:31
created

CommentDensity::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 6
dl 0
loc 8
ccs 1
cts 1
cp 1
crap 1
rs 10
c 0
b 0
f 0
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 3
    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 3
    }
32
33 1
    public function analyzeDirectories(array $directories): bool
34
    {
35 1
        $this->metrics->startPerformanceMonitoring();
36 1
        $comments = [];
37 1
        $commentStatistics = [];
38 1
        $totalLinesOfCode = 0;
39 1
        $cdsSum = 0;
40 1
        $filesAnalyzed = 0;
41
42 1
        foreach ($directories as $directory) {
43 1
            $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
44
            /** @var SplFileInfo $file */
45 1
            foreach ($iterator as $file) {
46 1
                if ($this->isInWhitelist($file->getRealPath())) {
47
                    continue;
48
                }
49 1
                $this->fileAnalyzer->analyzeFile(
50 1
                    $file,
51 1
                    $commentStatistics,
52 1
                    $comments,
53 1
                    $totalLinesOfCode,
54 1
                    $cdsSum
55 1
                );
56 1
                $filesAnalyzed++;
57
            }
58
        }
59
60 1
        $this->metrics->stopPerformanceMonitoring();
61
62 1
        $outputDTO = $this->createOutputDTO(
63 1
            $comments,
64 1
            $commentStatistics,
65 1
            $totalLinesOfCode,
66 1
            $cdsSum / $totalLinesOfCode,
67 1
            $filesAnalyzed,
68 1
        );
69
70 1
        $this->reporter->report($outputDTO);
71
72 1
        return $this->exceedThreshold;
73
    }
74
75 1
    private function createOutputDTO(
76
        array $comments,
77
        array $commentStatistics,
78
        int $linesOfCode,
79
        float $cds,
80
        int $filesAnalyzed,
81
    ): OutputDTO {
82 1
        if ($this->metrics->hasExceededThreshold()) {
83
            $this->exceedThreshold = true;
84
        }
85 1
        return new OutputDTO(
86 1
            $filesAnalyzed,
87 1
            $this->prepareCommentStatistics($commentStatistics),
88 1
            $this->prepareComments($comments),
89 1
            $this->metrics->getPerformanceMetrics(),
90 1
            $this->metrics->prepareComToLoc($commentStatistics, $linesOfCode),
91 1
            $this->metrics->prepareCDS($cds)
92 1
        );
93
    }
94
95 1
    private function prepareCommentStatistics(array $commentStatistics): array
96
    {
97 1
        $preparedStatistics = [];
98 1
        foreach ($commentStatistics as $type => $count) {
99 1
            if ($type === 'missingDocblock') {
100 1
                $preparedStatistics[] = new CommentStatisticsDTO(
101 1
                    $this->missingDocBlock->getColor(),
102 1
                    $this->missingDocBlock->getName(),
103 1
                    $count,
104 1
                    $this->missingDocBlock->getStatColor($count, $this->configDTO->thresholds)
105 1
                );
106 1
                $this->exceedThreshold = $this->exceedThreshold ?: $this->missingDocBlock->hasExceededThreshold();
107 1
                continue;
108
            }
109 1
            $commentType = $this->commentFactory->getCommentType($type);
110 1
            if ($commentType) {
111 1
                $preparedStatistics[] = new CommentStatisticsDTO(
112 1
                    $commentType->getColor(),
113 1
                    $commentType->getName(),
114 1
                    $count,
115 1
                    $commentType->getStatColor($count, $this->configDTO->thresholds)
116 1
                );
117 1
                $this->exceedThreshold = $this->exceedThreshold ?: $commentType->hasExceededThreshold();
0 ignored issues
show
Bug introduced by
The method hasExceededThreshold() does not exist on SavinMikhail\CommentsDen...ts\CommentTypeInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to SavinMikhail\CommentsDen...ts\CommentTypeInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

117
                $this->exceedThreshold = $this->exceedThreshold ?: $commentType->/** @scrutinizer ignore-call */ hasExceededThreshold();
Loading history...
118
            }
119
        }
120 1
        return  $preparedStatistics;
121
    }
122
123 1
    private function prepareComments(array $comments): array
124
    {
125 1
        $preparedComments = [];
126 1
        foreach ($comments as $comment) {
127
            /** @var CommentTypeInterface|string $commentType */
128 1
            $commentType = $comment['type'];
129 1
            if ($commentType === 'missingDocblock') {
130
                $preparedComments[] = new CommentDTO(
131
                    'missingDocblock',
132
                    'red',
133
                    $comment['file'],
134
                    $comment['line'],
135
                    $comment['content']
136
                );
137
                continue;
138
            }
139 1
            if ($commentType->getAttitude() === 'good') {
140 1
                continue;
141
            }
142 1
            $preparedComments[] = new CommentDTO(
143 1
                $commentType->getName(),
144 1
                $commentType->getColor(),
145 1
                $comment['file'],
146 1
                $comment['line'],
147 1
                $comment['content']
148 1
            );
149
        }
150 1
        return $preparedComments;
151
    }
152
153
    public function analyzeFile(string $filename): bool
154
    {
155
        $comments = [];
156
        $commentStatistics = [];
157
        $totalLinesOfCode = 0;
158
        $cdsSum = 0;
159
160
        $this->fileAnalyzer->analyzeFile(
161
            new SplFileInfo($filename),
162
            $commentStatistics,
163
            $comments,
164
            $totalLinesOfCode,
165
            $cdsSum
166
        );
167
168
        return $this->exceedThreshold;
169
    }
170
171 1
    private function isInWhitelist(string $filePath): bool
172
    {
173 1
        foreach ($this->configDTO->exclude as $whitelistedDir) {
174
            if (str_contains($filePath, $whitelistedDir)) {
175
                return true;
176
            }
177
        }
178 1
        return false;
179
    }
180
}
181