CommitCollection   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 24
eloc 46
c 2
b 0
f 1
dl 0
loc 127
ccs 57
cts 57
cp 1
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A add() 0 17 4
A __construct() 0 4 1
A setMajorMarker() 0 4 2
A addRawMessage() 0 9 2
A hasMinorMarker() 0 3 1
A getIterator() 0 4 2
A detectionSection() 0 14 4
A detectMarkers() 0 13 5
A getVisibleSections() 0 5 2
A hasMajorMarker() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Vasoft\VersionIncrement\Commits;
6
7
final class CommitCollection implements \IteratorAggregate
8
{
9
    private bool $majorMarker = false;
10
    private bool $minorMarker = false;
11
12
    /**
13
     * @param array<string,Section> $sections
14
     */
15 29
    public function __construct(
16
        private readonly array $sections,
17
        private readonly Section $defaultSection,
18 29
    ) {}
19
20
    /**
21
     * Adds a commit to the collection.
22
     *
23
     * If the commit type exists in the collection, it is added to the corresponding section.
24
     * Otherwise, it is added to the default section.
25
     */
26 26
    public function add(Commit $commit): void
27
    {
28 26
        $this->detectMarkers($commit);
29 26
        $rawMessage = false;
30 26
        $detectedKey = $this->detectionSection($commit, $rawMessage);
31 26
        if ($rawMessage) {
32 19
            $this->addRawMessage($commit->rawMessage);
33
34 19
            return;
35
        }
36 25
        if ($detectedKey !== $commit->type) {
37 3
            $commit = $commit->withType($detectedKey);
38 3
            $this->detectMarkers($commit);
39
        }
40 25
        $section = $this->sections[$commit->type] ?? $this->defaultSection;
41 25
        if (!$section->hidden) {
42 25
            $section->addCommit($commit);
43
        }
44
    }
45
46 26
    private function detectMarkers(Commit $commit): void
47
    {
48 26
        if ($commit->breakingChange) {
49 3
            $this->majorMarker = true;
50
51 3
            return;
52
        }
53 26
        $section = $this->sections[$commit->type] ?? null;
54 26
        if ($section) {
55 25
            if ($section->isMajorMarker) {
56 2
                $this->majorMarker = true;
57 25
            } elseif ($section->isMinorMarker) {
58 20
                $this->minorMarker = true;
59
            }
60
        }
61
    }
62
63
    /**
64
     * Adds a commit to the default section.
65
     *
66
     * This method performs the following steps:
67
     * 1. Checks if the default section is not hidden.
68
     * 2. Creates a new Commit object with the processed message and adds it to the default section.
69
     */
70 20
    public function addRawMessage(string $message): void
71
    {
72 20
        if (!$this->defaultSection->hidden) {
73 20
            $this->defaultSection->addCommit(
74 20
                new Commit(
75 20
                    $message,
76 20
                    $this->defaultSection->type,
77 20
                    trim($message),
78 20
                    false,
79 20
                ),
80 20
            );
81
        }
82
    }
83
84
    /**
85
     * Returns non-empty sections of the commit collection.
86
     *
87
     * @return array<string, Section>
88
     */
89 27
    public function getVisibleSections(): array
90
    {
91 27
        return array_filter(
92 27
            $this->sections,
93 27
            static fn(Section $section): bool => !$section->isEmpty() && !$section->hidden,
94 27
        );
95
    }
96
97 26
    private function detectionSection(
98
        Commit $commit,
99
        bool &$rawMessage,
100
    ): string {
101 26
        foreach ($this->sections as $index => $section) {
102 26
            foreach ($section->rules as $rule) {
103 26
                if ($rule($commit)) {
104 25
                    return $index;
105
                }
106
            }
107
        }
108 19
        $rawMessage = true;
109
110 19
        return $this->defaultSection->type;
111
    }
112
113 27
    public function hasMajorMarker(): bool
114
    {
115 27
        return $this->majorMarker;
116
    }
117
118 21
    public function hasMinorMarker(): bool
119
    {
120 21
        return $this->minorMarker;
121
    }
122
123 2
    public function setMajorMarker(bool $majorMarker): void
124
    {
125 2
        if ($majorMarker) {
126 1
            $this->majorMarker = true;
127
        }
128
    }
129
130 1
    public function getIterator(): \Traversable
131
    {
132 1
        foreach ($this->sections as $section) {
133 1
            yield $section;
134
        }
135
    }
136
}
137