@@ -27,14 +27,43 @@ module SemanticVersion
2727 module_function
2828
2929 def pre_release? ( target )
30- # Method to check if the given version contains "-"
30+ # Method to check if the given version is a prerelease
3131 #
3232 # target - String representing semantic version
3333 #
34- # Returns true if the given version does contain "-"
34+ # Returns true if the given version is a prerelease
3535 # false if it doesn't
3636
37- target . include? SEMVER_PRE_RELEASE
37+ raise unless target . is_a? String
38+
39+ prerelease_index = target . index ( SEMVER_PRE_RELEASE )
40+ build_index = target . index ( SEMVER_BUILD )
41+
42+ return false if prerelease_index . nil?
43+ return true if build_index . nil?
44+
45+ # when both operators are present prerelease should precede the build operator
46+ prerelease_index < build_index
47+ end
48+
49+ def build? ( target )
50+ # Method to check if the given version is a build
51+ #
52+ # target - String representing semantic version
53+ #
54+ # Returns true if the given version is a build
55+ # false if it doesn't
56+
57+ raise unless target . is_a? String
58+
59+ prerelease_index = target . index ( SEMVER_PRE_RELEASE )
60+ build_index = target . index ( SEMVER_BUILD )
61+
62+ return false if build_index . nil?
63+ return true if prerelease_index . nil?
64+
65+ # when both operators are present build should precede the prerelease operator
66+ build_index < prerelease_index
3867 end
3968
4069 def split_semantic_version ( target )
@@ -52,9 +81,9 @@ def split_semantic_version(target)
5281 raise InvalidSemanticVersion if target . include? ' '
5382
5483 if pre_release? ( target )
55- target_parts = target . split ( SEMVER_PRE_RELEASE )
56- elsif target . include? SEMVER_BUILD
57- target_parts = target . split ( SEMVER_BUILD )
84+ target_parts = target . split ( SEMVER_PRE_RELEASE , 2 )
85+ elsif build? target
86+ target_parts = target . split ( SEMVER_BUILD , 2 )
5887 end
5988
6089 unless target_parts . empty?
@@ -91,6 +120,9 @@ def compare_user_version_with_target_version(target_version, user_version)
91120 raise InvalidAttributeType unless target_version . is_a? String
92121 raise InvalidAttributeType unless user_version . is_a? String
93122
123+ is_target_version_prerelease = pre_release? ( target_version )
124+ is_user_version_prerelease = pre_release? ( user_version )
125+
94126 target_version_parts = split_semantic_version ( target_version )
95127 user_version_parts = split_semantic_version ( user_version )
96128 user_version_parts_len = user_version_parts . length if user_version_parts
@@ -99,15 +131,23 @@ def compare_user_version_with_target_version(target_version, user_version)
99131 target_version_parts . each_with_index do |_item , idx |
100132 if user_version_parts_len <= idx
101133 # even if they are equal at this point. if the target is a prerelease
102- # then it must be greater than the pre release.
103- return 1 if pre_release? ( target_version )
134+ # then user version must be greater than the pre release.
135+ return 1 if is_target_version_prerelease
104136
105137 return -1
106138
107139 elsif !Helpers ::Validator . string_numeric? user_version_parts [ idx ]
108140 # compare strings
109- return -1 if user_version_parts [ idx ] < target_version_parts [ idx ]
110- return 1 if user_version_parts [ idx ] > target_version_parts [ idx ]
141+ if user_version_parts [ idx ] < target_version_parts [ idx ]
142+ return 1 if is_target_version_prerelease && !is_user_version_prerelease
143+
144+ return -1
145+
146+ elsif user_version_parts [ idx ] > target_version_parts [ idx ]
147+ return -1 if is_user_version_prerelease && !is_target_version_prerelease
148+
149+ return 1
150+ end
111151
112152 else
113153 user_version_part = user_version_parts [ idx ] . to_i
@@ -118,7 +158,7 @@ def compare_user_version_with_target_version(target_version, user_version)
118158 end
119159 end
120160
121- return -1 if pre_release? ( user_version ) && !pre_release? ( target_version )
161+ return -1 if is_user_version_prerelease && !is_target_version_prerelease
122162
123163 0
124164 end
0 commit comments