Completed
Pull Request — master (#2)
by Julien
02:16
created

VersionComparator::comparePreRelease()   D

Complexity

Conditions 9
Paths 7

Size

Total Lines 37
Code Lines 23

Duplication

Lines 17
Ratio 45.95 %

Importance

Changes 0
Metric Value
dl 17
loc 37
rs 4.909
c 0
b 0
f 0
cc 9
eloc 23
nc 7
nop 2
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
abstract class VersionComparator
17
{
18
    /**
19
     * @param Version $version1
20
     * @param Version $version2
21
     *
22
     * @return int
23
     */
24
    public static function compare(Version $version1, Version $version2) : int
25
    {
26
        $compare = self::compareNumericParts($version1, $version2);
27
        if (0 !== $compare) {
28
            return $compare;
29
        }
30
31
        return self::comparePreRelease($version1, $version2);
32
    }
33
34
    /**
35
     * @param Version $version1
36
     * @param Version $version2
37
     *
38
     * @return int
39
     */
40
    private static function compareNumericParts(Version $version1, Version $version2) : int
41
    {
42
        $compare = $version1->getMajor() <=> $version2->getMajor();
43
        if (0 !== $compare) {
44
            return $compare;
45
        }
46
        $compare = $version1->getMinor() <=> $version2->getMinor();
47
        if (0 !== $compare) {
48
            return $compare;
49
        }
50
        $compare = $version1->getPatch() <=> $version2->getPatch();
51
        if (0 !== $compare) {
52
            return $compare;
53
        }
54
55
        return 0;
56
    }
57
58
    /**
59
     * @param Version $version1
60
     * @param Version $version2
61
     *
62
     * @return int
63
     */
64
    private static function comparePreRelease(Version $version1, Version $version2) : int
65
    {
66
        $preRelease1 = $version1->getPreRelease();
67
        $preRelease2 = $version2->getPreRelease();
68
        $leftPreReleaseIsEmpty  = '' === $preRelease1;
69
        $rightPreReleaseIsEmpty = '' === $preRelease2;
70
        if ($rightPreReleaseIsEmpty !== $leftPreReleaseIsEmpty) {
71
            return $leftPreReleaseIsEmpty ? 1 : -1;
72
        }
73
74
        if ($leftPreReleaseIsEmpty) {
75
            return 0;
76
        }
77
        // need to compare each subversion
78
        $preReleaseIdentifiers1 = explode('.', $preRelease1);
79
        $preReleaseIdentifiers2 = explode('.', $preRelease2);
80
81 View Code Duplication
        do {
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...
82
            $preReleasePart1 = array_shift($preReleaseIdentifiers1);
83
            $preReleasePart2 = array_shift($preReleaseIdentifiers2);
84
85
            if (null === $preReleasePart1) {
86
                return -1;
87
            }
88
89
            if (null === $preReleasePart2) {
90
                return 1;
91
            }
92
93
            $compare = static::comparePreReleasePart($preReleasePart1, $preReleasePart2);
0 ignored issues
show
Bug introduced by
Since comparePreReleasePart() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of comparePreReleasePart() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
94
            if (0 !== $compare) {
95
                return $compare;
96
            }
97
        } while (count($preReleaseIdentifiers1) || count($preReleaseIdentifiers2));
98
99
        return 0;
100
    }
101
102
    /**
103
     * @param string $preReleasePart1
104
     * @param string $preReleasePart2
105
     *
106
     * @return int
107
     */
108
    private static function comparePreReleasePart(string $preReleasePart1, string $preReleasePart2) : int
109
    {
110
        $mineIsInt  = ctype_digit($preReleasePart1) && strpos($preReleasePart1, '00') !== 0;
111
        $theirIsInt = ctype_digit($preReleasePart2) && strpos($preReleasePart2, '00') !== 0;
112
113
        if ($mineIsInt !== $theirIsInt) {
114
            return $mineIsInt ? -1 : 1;
115
        }
116
        if ($mineIsInt) {
117
            return ((int) $preReleasePart1) <=> ((int) $preReleasePart2);
118
        }
119
120
        return $preReleasePart1 <=> $preReleasePart2;
121
    }
122
}
123