Completed
Push — master ( a2b807...0ad465 )
by Nikola
03:00
created

Version::setComparator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Version;
6
7
use JsonSerializable;
8
use Version\Extension\Build;
9
use Version\Extension\NoBuild;
10
use Version\Extension\NoPreRelease;
11
use Version\Exception\InvalidVersionElementException;
12
use Version\Exception\InvalidVersionStringException;
13
use Version\Comparator\ComparatorInterface;
14
use Version\Comparator\SemverComparator;
15
use Version\Constraint\ConstraintInterface;
16
use Version\Constraint\Constraint;
17
use Version\Extension\PreRelease;
18
19
/**
20
 * @author Nikola Posa <[email protected]>
21
 */
22
class Version implements JsonSerializable
23
{
24
    /**
25
     * @var int
26
     */
27
    protected $major;
28
29
    /**
30
     * @var int
31
     */
32
    protected $minor;
33
34
    /**
35
     * @var int
36
     */
37
    protected $patch;
38
39
    /**
40
     * @var PreRelease
41
     */
42
    protected $preRelease;
43
44
    /**
45
     * @var Build
46
     */
47
    protected $build;
48
49 75
    protected function __construct(int $major, int $minor, int $patch, PreRelease $preRelease, Build $build)
50
    {
51 75
        $this->major = $major;
52 75
        $this->minor = $minor;
53 75
        $this->patch = $patch;
54 75
        $this->preRelease = $preRelease;
55 75
        $this->build = $build;
56 75
    }
57
58 78
    public static function fromParts(int $major, int $minor, int $patch, PreRelease $preRelease, Build $build) : Version
59
    {
60 78
        static::validatePart('major', $major);
61 77
        static::validatePart('minor', $minor);
62 76
        static::validatePart('patch', $patch);
63
64 75
        return new static($major, $minor, $patch, $preRelease, $build);
65
    }
66
67 10
    public static function fromMajor(int $major) : Version
68
    {
69 10
        return static::fromParts($major, 0, 0, new NoPreRelease(), new NoBuild());
70
    }
71
72 2
    public static function fromMinor(int $major, int $minor) : Version
73
    {
74 2
        return static::fromParts($major, $minor, 0, new NoPreRelease(), new NoBuild());
75
    }
76
77 2
    public static function fromPatch(int $major, int $minor, int $patch) : Version
78
    {
79 2
        return static::fromParts($major, $minor, $patch, new NoPreRelease(), new NoBuild());
80
    }
81
82 1
    public static function fromPreRelease(int $major, int $minor, int $patch, PreRelease $preRelease) : Version
83
    {
84 1
        return static::fromParts($major, $minor, $patch, $preRelease, new NoBuild());
85
    }
86
87 1
    public static function fromBuild(int $major, int $minor, int $patch, Build $build) : Version
88
    {
89 1
        return static::fromParts($major, $minor, $patch, new NoPreRelease(), $build);
90
    }
91
92
    /**
93
     * @param string $versionString
94
     * @return Version
95
     * @throws InvalidVersionStringException
96
     */
97 72
    public static function fromString(string $versionString) : Version
98
    {
99 72
        if (!preg_match(
100
            '#^'
101
            . 'v?'
102
            . '(?P<core>(?:[0-9]|[1-9][0-9]+)(?:\.(?:[0-9]|[1-9][0-9]+)){2})'
103
            . '(?:\-(?P<preRelease>[0-9A-Za-z\-\.]+))?'
104
            . '(?:\+(?P<build>[0-9A-Za-z\-\.]+))?'
105 72
            . '$#',
106 72
            $versionString,
107 72
            $parts
108
        )) {
109 4
            throw InvalidVersionStringException::forVersionString($versionString);
110
        }
111
112 68
        [$major, $minor, $patch] = explode('.', $parts['core']);
0 ignored issues
show
Bug introduced by
The variable $major seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
Bug introduced by
The variable $minor seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
Bug introduced by
The variable $patch seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
113 68
        $major = (int) $major;
0 ignored issues
show
Bug introduced by
The variable $major seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
114 68
        $minor = (int) $minor;
0 ignored issues
show
Bug introduced by
The variable $minor seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
115 68
        $patch = (int) $patch;
0 ignored issues
show
Bug introduced by
The variable $patch seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
116
117 68
        $preRelease = !empty($parts['preRelease']) ? PreRelease::fromIdentifiersString($parts['preRelease']) : new NoPreRelease();
118
119 67
        $build = !empty($parts['build']) ? Build::fromIdentifiersString($parts['build']) : new NoBuild();
120
121 67
        return static::fromParts($major, $minor, $patch, $preRelease, $build);
122
    }
123
124 78
    protected static function validatePart(string $part, int $value) : void
125
    {
126 78
        if ($value < 0) {
127 3
            throw InvalidVersionElementException::forElement($part);
128
        }
129 77
    }
130
131 55
    public function getMajor() : int
132
    {
133 55
        return $this->major;
134
    }
135
136 51
    public function getMinor() : int
137
    {
138 51
        return $this->minor;
139
    }
140
141 47
    public function getPatch() : int
142
    {
143 47
        return $this->patch;
144
    }
145
146 29
    public function getPreRelease() : PreRelease
147
    {
148 29
        return $this->preRelease;
149
    }
150
151 7
    public function getBuild() : Build
152
    {
153 7
        return $this->build;
154
    }
155
156 49
    public function isPreRelease() : bool
157
    {
158 49
        return !$this->preRelease->isEmpty();
159
    }
160
161 29
    public function isBuild() : bool
162
    {
163 29
        return !$this->build->isEmpty();
164
    }
165
166
    /**
167
     * @param self|string $version
168
     * @return bool
169
     */
170 5
    public function isEqualTo($version) : bool
171
    {
172 5
        return $this->compareTo($version) === 0;
173
    }
174
175
    /**
176
     * @param self|string $version
177
     * @return bool
178
     */
179 1
    public function isNotEqualTo($version) : bool
180
    {
181 1
        return !$this->isEqualTo($version);
182
    }
183
184
    /**
185
     * @param self|string $version
186
     * @return bool
187
     */
188 3
    public function isGreaterThan($version) : bool
189
    {
190 3
        return $this->compareTo($version) > 0;
191
    }
192
193
    /**
194
     * @param self|string $version
195
     * @return bool
196
     */
197 4
    public function isGreaterOrEqualTo($version) : bool
198
    {
199 4
        return $this->compareTo($version) >= 0;
200
    }
201
202
    /**
203
     * @param self|string $version
204
     * @return bool
205
     */
206 3
    public function isLessThan($version) : bool
207
    {
208 3
        return $this->compareTo($version) < 0;
209
    }
210
211
    /**
212
     * @param self|string $version
213
     * @return bool
214
     */
215 3
    public function isLessOrEqualTo($version) : bool
216
    {
217 3
        return $this->compareTo($version) <= 0;
218
    }
219
220
    /**
221
     * @param self|string $version
222
     * @return int (1 if $this > $version, -1 if $this < $version, 0 if equal)
223
     */
224 21
    public function compareTo($version) : int
225
    {
226 21
        if (is_string($version)) {
227 7
            $version = static::fromString($version);
228
        }
229
230 21
        return $this->getComparator()->compare($this, $version);
231
    }
232
233
    /**
234
     * @param ConstraintInterface|string $constraint
235
     * @return bool
236
     */
237 3
    public function matches($constraint) : bool
238
    {
239 3
        if (! $constraint instanceof ConstraintInterface) {
240 1
            $constraint = Constraint::fromString($constraint);
241
        }
242
243 3
        return $constraint->assert($this);
244
    }
245
246 1
    public function incrementMajor() : Version
247
    {
248 1
        return static::fromParts($this->major + 1, 0, 0, new NoPreRelease(), new NoBuild());
249
    }
250
251 2
    public function incrementMinor() : Version
252
    {
253 2
        return static::fromParts($this->major, $this->minor + 1, 0, new NoPreRelease(), new NoBuild());
254
    }
255
256 1
    public function incrementPatch() : Version
257
    {
258 1
        return static::fromParts($this->major, $this->minor, $this->patch + 1, new NoPreRelease(), new NoBuild());
259
    }
260
261 2
    public function withPreRelease($preRelease) : Version
262
    {
263 2
        if (is_string($preRelease)) {
264 2
            $preRelease = PreRelease::fromIdentifiersString($preRelease);
265
        }
266
267 2
        return static::fromParts($this->major, $this->minor, $this->patch, $preRelease, new NoBuild());
268
    }
269
270 1
    public function withBuild($build) : Version
271
    {
272 1
        if (is_string($build)) {
273 1
            $build = Build::fromIdentifiersString($build);
274
        }
275
276 1
        return static::fromParts($this->major, $this->minor, $this->patch, $this->preRelease, $build);
277
    }
278
279 14
    public function getVersionString() : string
280
    {
281
        return
282 14
            $this->major
283 14
            . '.' . $this->minor
284 14
            . '.' . $this->patch
285 14
            . ($this->isPreRelease() ? '-' . (string) $this->preRelease : '')
286 14
            . ($this->isBuild() ? '+' . (string) $this->build : '')
287
        ;
288
    }
289
290 10
    public function __toString() : string
291
    {
292 10
        return $this->getVersionString();
293
    }
294
295 4
    public function jsonSerialize() : string
296
    {
297 4
        return $this->getVersionString();
298
    }
299
300 4
    public function toArray() : array
301
    {
302
        return [
303 4
            'major' => $this->major,
304 4
            'minor' => $this->minor,
305 4
            'patch' => $this->patch,
306 4
            'preRelease' => $this->preRelease->getIdentifiers(),
307 4
            'build' => $this->build->getIdentifiers(),
308
        ];
309
    }
310
311 21
    protected function getComparator() : ComparatorInterface
312
    {
313 21
        static $comparator = null;
314
315 21
        if (null === $comparator) {
316 1
            $comparator = new SemverComparator();
317
        }
318
319 21
        return $comparator;
320
    }
321
}
322