Completed
Push — master ( 2c0ce9...eb7a8f )
by Julien
02:09
created

Version::minor()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 3
Ratio 37.5 %

Importance

Changes 0
Metric Value
dl 3
loc 8
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 4
nc 2
nop 0
1
<?php
2
3
/*
4
 * This file is part of semver/semver.
5
 *
6
 * (c) SemVer <https://github.com/git-pull-request>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace SemVer\SemVer;
15
16
use SemVer\SemVer\Exception\InvalidArgumentException;
17
18
/**
19
 * Definition of a Version according to Semantic Versioning 2.0.0.
20
 *
21
 * @link http://semver.org/
22
 */
23
final class Version
24
{
25
    /** @var string */
26
    private $build;
27
    /** @var int */
28
    private $major;
29
    /** @var int */
30
    private $minor;
31
    /** @var int */
32
    private $patch;
33
    /** @var string */
34
    private $preRelease;
35
36
    /**
37
     * @param int    $major
38
     * @param int    $minor
39
     * @param int    $patch
40
     * @param string $preRelease
41
     * @param string $build
42
     *
43
     * @throws \SemVer\SemVer\Exception\InvalidArgumentException
44
     */
45
    public function __construct(int $major, int $minor, int $patch, string $preRelease = '', string $build = '')
46
    {
47
        $this->major      = $major;
48
        $this->minor      = $minor;
49
        $this->patch      = $patch;
50
        $this->preRelease = $preRelease;
51
        $this->build      = $build;
52
53
        if ('' !== $this->preRelease && !preg_match('#^([0-9A-Za-z-]+\.)*[0-9A-Za-z-]+$#', $this->preRelease)) {
54
            throw new InvalidArgumentException(
55
                'The pre-release version is not compatible with rule 9 of the specifications.'
56
            );
57
        }
58
59
        if ('' !== $this->build && !preg_match('#^([0-9A-Za-z-]+\.)*[0-9A-Za-z-]+$#', $this->build)) {
60
            throw new InvalidArgumentException(
61
                'The build version is not compatible with rule 10 of the specifications.'
62
            );
63
        }
64
    }
65
66
    /** @return string */
67
    public function __toString() : string
68
    {
69
        $str = sprintf('%d.%d.%d', $this->major, $this->minor, $this->patch);
70
        if ('' !== $this->preRelease) {
71
            $str .= '-'.$this->preRelease;
72
        }
73
        if ('' !== $this->build) {
74
            $str .= '+'.$this->build;
75
        }
76
77
        return $str;
78
    }
79
80
    /**
81
     * @param string $version
82
     *
83
     * @throws InvalidArgumentException
84
     *
85
     * @return Version
86
     */
87
    public static function fromString(string $version) : Version
88
    {
89
        $patternMajor      = '(?P<major>[0-9]+)';
90
        $patternMinor      = '(?P<minor>[0-9]+)';
91
        $patternPatch      = '(?P<patch>[0-9]+)';
92
        $patternPreRelease = '(?:-(?P<prerelease>(?:[0-9A-Za-z-]+\.)*(?:[0-9A-Za-z-]+)))?';
93
        $patternBuild      = '(?:\+(?P<build>(?:[0-9A-Za-z-]+\.)*(?:[0-9A-Za-z-]+)))?';
94
95
        $pattern = '#^'.$patternMajor.'\.'.$patternMinor.'\.'.$patternPatch.$patternPreRelease.$patternBuild.'$#';
96
        if (!preg_match($pattern, $version, $matches)) {
97
            throw new InvalidArgumentException(sprintf('The string "%s" does not look like a version.', $version));
98
        }
99
100
        return new static(
101
            (int) $matches['major'],
102
            (int) $matches['minor'],
103
            (int) $matches['patch'],
104
            $matches['prerelease'] ?? '',
105
            $matches['build'] ?? ''
106
        );
107
    }
108
109
    /**
110
     * @return int
111
     */
112
    public function getMajor() : int
113
    {
114
        return $this->major;
115
    }
116
117
    /**
118
     * @return int
119
     */
120
    public function getMinor() : int
121
    {
122
        return $this->minor;
123
    }
124
125
    /**
126
     * @return int
127
     */
128
    public function getPatch() : int
129
    {
130
        return $this->patch;
131
    }
132
133
    /**
134
     * @return string
135
     */
136
    public function getPreRelease() : string
137
    {
138
        return $this->preRelease;
139
    }
140
141
    /**
142
     * @return string
143
     */
144
    public function getBuild() : string
145
    {
146
        return $this->build;
147
    }
148
149
    /**
150
     * @throws \SemVer\SemVer\Exception\InvalidArgumentException
151
     *
152
     * @return Version
153
     */
154
    public function major() : Version
155
    {
156 View Code Duplication
        if ('' !== $this->preRelease && 0 === $this->patch && 0 === $this->minor) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
157
            return new self($this->major, 0, 0);
158
        }
159
160
        return new self($this->major + 1, 0, 0);
161
    }
162
163
    /**
164
     * @throws \SemVer\SemVer\Exception\InvalidArgumentException
165
     *
166
     * @return Version
167
     */
168
    public function minor() : Version
169
    {
170 View Code Duplication
        if ('' !== $this->preRelease && 0 === $this->patch) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
171
            return new self($this->major, $this->minor, 0);
172
        }
173
174
        return new self($this->major, $this->minor + 1, 0);
175
    }
176
177
    /**
178
     * @throws \SemVer\SemVer\Exception\InvalidArgumentException
179
     *
180
     * @return Version
181
     */
182
    public function patch() : Version
183
    {
184
        if ('' !== $this->preRelease) {
185
            return new self($this->major, $this->minor, $this->patch);
186
        }
187
188
        return new self($this->major, $this->minor, $this->patch + 1);
189
    }
190
191
    /**
192
     * @param Version $other
193
     *
194
     * @return bool
195
     */
196
    public function isEquals(Version $other) : bool
197
    {
198
        return 0 === VersionComparator::compare($this, $other);
199
    }
200
201
    /**
202
     * @param Version $other
203
     *
204
     * @return bool
205
     */
206
    public function isGreaterThan(Version $other) : bool
207
    {
208
        return 1 === VersionComparator::compare($this, $other);
209
    }
210
211
    /**
212
     * @param Version $other
213
     *
214
     * @return bool
215
     */
216
    public function isGreaterThanOrEqual(Version $other) : bool
217
    {
218
        return 0 <= VersionComparator::compare($this, $other);
219
    }
220
221
    /**
222
     * @param Version $other
223
     *
224
     * @return bool
225
     */
226
    public function isLessThan(Version $other) : bool
227
    {
228
        return -1 === VersionComparator::compare($this, $other);
229
    }
230
231
    /**
232
     * @param Version $other
233
     *
234
     * @return bool
235
     */
236
    public function isLessThanOrEqual(Version $other) : bool
237
    {
238
        return 0 >= VersionComparator::compare($this, $other);
239
    }
240
}
241