Completed
Push — master ( c5181d...c8e170 )
by Nikola
01:19
created

Version::getBuild()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Version;
6
7
use JsonSerializable;
8
use Version\Assert\VersionAssert;
9
use Version\Extension\Build;
10
use Version\Exception\InvalidVersionString;
11
use Version\Comparison\Comparator;
12
use Version\Comparison\SemverComparator;
13
use Version\Comparison\Constraint\Constraint;
14
use Version\Extension\PreRelease;
15
16
class Version implements JsonSerializable
17
{
18
    /** @var int */
19
    protected $major;
20
21
    /** @var int */
22
    protected $minor;
23
24
    /**  @var int */
25
    protected $patch;
26
27
    /** @var PreRelease */
28
    protected $preRelease;
29
30
    /** @var Build */
31
    protected $build;
32
33
    /** @var Comparator|null */
34
    protected static $comparator;
35
36 78
    protected function __construct(int $major, int $minor, int $patch, PreRelease $preRelease, Build $build)
37
    {
38 78
        VersionAssert::that($major)->greaterOrEqualThan(0, 'Major version must be positive integer');
39 77
        VersionAssert::that($minor)->greaterOrEqualThan(0, 'Minor version must be positive integer');
40 76
        VersionAssert::that($patch)->greaterOrEqualThan(0, 'Patch version must be positive integer');
41
42 75
        $this->major = $major;
43 75
        $this->minor = $minor;
44 75
        $this->patch = $patch;
45 75
        $this->preRelease = $preRelease;
46 75
        $this->build = $build;
47 75
    }
48
49 78
    public static function from(int $major, int $minor = 0, int $patch = 0, PreRelease $preRelease = null, Build $build = null): Version
50
    {
51 78
        return new static($major, $minor, $patch, $preRelease ?? PreRelease::empty(), $build ?? Build::empty());
52
    }
53
54
    /**
55
     * @param string $versionString
56
     *
57
     * @return Version
58
     * @throws InvalidVersionString
59
     *
60
     */
61 76
    public static function fromString(string $versionString): Version
62
    {
63 76
        if (!preg_match(
64
            '#^'
65
            . '(v|release\-)?'
66
            . '(?P<core>(?:[0-9]|[1-9][0-9]+)(?:\.(?:[0-9]|[1-9][0-9]+)){2})'
67
            . '(?:\-(?P<preRelease>[0-9A-Za-z\-\.]+))?'
68
            . '(?:\+(?P<build>[0-9A-Za-z\-\.]+))?'
69 76
            . '$#',
70 76
            $versionString,
71 76
            $parts
72
        )) {
73 4
            throw InvalidVersionString::notParsable($versionString);
74
        }
75
76 72
        [$major, $minor, $patch] = explode('.', $parts['core']);
0 ignored issues
show
Bug introduced by
The variable $major does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $minor does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $patch does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
77 72
        $preRelease = !empty($parts['preRelease']) ? PreRelease::fromString($parts['preRelease']) : PreRelease::empty();
78 72
        $build = !empty($parts['build']) ? Build::fromString($parts['build']) : Build::empty();
79
80 72
        return static::from((int) $major, (int) $minor, (int) $patch, $preRelease, $build);
81
    }
82
83 57
    public function getMajor(): int
84
    {
85 57
        return $this->major;
86
    }
87
88 53
    public function getMinor(): int
89
    {
90 53
        return $this->minor;
91
    }
92
93 49
    public function getPatch(): int
94
    {
95 49
        return $this->patch;
96
    }
97
98 46
    public function getPreRelease(): PreRelease
99
    {
100 46
        return $this->preRelease;
101
    }
102
103 26
    public function getBuild(): Build
104
    {
105 26
        return $this->build;
106
    }
107
108
    /**
109
     * @param Version|string $version
110
     * @return bool
111
     */
112 6
    public function isEqualTo($version): bool
113
    {
114 6
        return $this->compareTo($version) === 0;
115
    }
116
117
    /**
118
     * @param Version|string $version
119
     * @return bool
120
     */
121 1
    public function isNotEqualTo($version): bool
122
    {
123 1
        return !$this->isEqualTo($version);
124
    }
125
126
    /**
127
     * @param Version|string $version
128
     * @return bool
129
     */
130 3
    public function isGreaterThan($version): bool
131
    {
132 3
        return $this->compareTo($version) > 0;
133
    }
134
135
    /**
136
     * @param Version|string $version
137
     * @return bool
138
     */
139 4
    public function isGreaterOrEqualTo($version): bool
140
    {
141 4
        return $this->compareTo($version) >= 0;
142
    }
143
144
    /**
145
     * @param Version|string $version
146
     * @return bool
147
     */
148 3
    public function isLessThan($version): bool
149
    {
150 3
        return $this->compareTo($version) < 0;
151
    }
152
153
    /**
154
     * @param Version|string $version
155
     * @return bool
156
     */
157 2
    public function isLessOrEqualTo($version): bool
158
    {
159 2
        return $this->compareTo($version) <= 0;
160
    }
161
162
    /**
163
     * @param Version|string $version
164
     * @return int (1 if $this > $version, -1 if $this < $version, 0 if equal)
165
     */
166 23
    public function compareTo($version): int
167
    {
168 23
        if (is_string($version)) {
169 7
            $version = static::fromString($version);
170
        }
171
172 23
        return $this->getComparator()->compare($this, $version);
173
    }
174
175 2
    public function isMajorRelease(): bool
176
    {
177 2
        return $this->major > 0 && $this->minor === 0 && $this->patch === 0;
178
    }
179
180 1
    public function isMinorRelease(): bool
181
    {
182 1
        return $this->minor > 0 && $this->patch === 0;
183
    }
184
185 1
    public function isPatchRelease(): bool
186
    {
187 1
        return $this->patch > 0;
188
    }
189
190 37
    public function isPreRelease(): bool
191
    {
192 37
        return !($this->preRelease === PreRelease::empty());
193
    }
194
195 15
    public function hasBuild(): bool
196
    {
197 15
        return !($this->build === Build::empty());
198
    }
199
200 1
    public function incrementMajor(): Version
201
    {
202 1
        return static::from($this->major + 1, 0, 0, PreRelease::empty(), Build::empty());
203
    }
204
205 2
    public function incrementMinor(): Version
206
    {
207 2
        return static::from($this->major, $this->minor + 1, 0, PreRelease::empty(), Build::empty());
208
    }
209
210 1
    public function incrementPatch(): Version
211
    {
212 1
        return static::from($this->major, $this->minor, $this->patch + 1, PreRelease::empty(), Build::empty());
213
    }
214
215
    /**
216
     * @param PreRelease|string|null $preRelease
217
     * @return Version
218
     */
219 2
    public function withPreRelease($preRelease): Version
220
    {
221 2
        if (is_string($preRelease)) {
222 2
            $preRelease = PreRelease::fromString($preRelease);
223
        }
224
225 2
        return static::from($this->major, $this->minor, $this->patch, $preRelease, Build::empty());
226
    }
227
228
    /**
229
     * @param Build|string|null $build
230
     * @return Version
231
     */
232 1
    public function withBuild($build): Version
233
    {
234 1
        if (is_string($build)) {
235 1
            $build = Build::fromString($build);
236
        }
237
238 1
        return static::from($this->major, $this->minor, $this->patch, $this->preRelease, $build);
239
    }
240
241 2
    public function matches(Constraint $constraint): bool
242
    {
243 2
        return $constraint->assert($this);
244
    }
245
246 14
    public function toString(): string
247
    {
248
        return
249 14
            $this->major
250 14
            . '.' . $this->minor
251 14
            . '.' . $this->patch
252 14
            . ($this->isPreRelease() ? '-' . $this->preRelease->toString() : '')
253 14
            . ($this->hasBuild() ? '+' . $this->build->toString() : '')
254
        ;
255
    }
256
257
    public function __toString(): string
258
    {
259
        return $this->toString();
260
    }
261
262 4
    public function jsonSerialize(): string
263
    {
264 4
        return $this->toString();
265
    }
266
267 4
    public function toArray(): array
268
    {
269
        return [
270 4
            'major' => $this->major,
271 4
            'minor' => $this->minor,
272 4
            'patch' => $this->patch,
273 4
            'preRelease' => $this->preRelease->getIdentifiers(),
274 4
            'build' => $this->build->getIdentifiers(),
275
        ];
276
    }
277
278 1
    public static function setComparator(?Comparator $comparator): void
279
    {
280 1
        static::$comparator = $comparator;
281 1
    }
282
283 23
    protected function getComparator(): Comparator
284
    {
285 23
        if (null === static::$comparator) {
286 1
            static::$comparator = new SemverComparator();
287
        }
288
289 23
        return static::$comparator;
290
    }
291
}
292