jamesfredley commented on code in PR #15696:
URL: https://github.com/apache/grails-core/pull/15696#discussion_r3322106370
##########
grails-bootstrap/src/main/groovy/grails/plugins/VersionComparator.groovy:
##########
@@ -112,4 +99,97 @@ class VersionComparator implements Comparator<String> {
protected boolean isSnapshot(String version) {
SNAPSHOT_SUFFIXES.any { String it -> version?.endsWith(it) }
}
+
+ /**
+ * Splits a version into its leading numeric components and an optional
trailing qualifier.
+ * The first token that is not purely numeric ends the numeric section. A
token of the form
+ * {@code <digits>-<qualifier>} (for example {@code 0-RC1} from {@code
7.0.0-RC1}) contributes
+ * its leading digits to the numeric section and the remainder becomes the
qualifier.
+ */
+ private static ParsedVersion parse(String version) {
+ List<Integer> numbers = []
+ String qualifier = null
+ if (version) {
+ for (String token : version.split(/\./)) {
+ if (DIGITS.matcher(token).matches()) {
+ numbers.add(Integer.parseInt(token))
+ continue
+ }
+ Matcher matcher = NUMERIC_PREFIX.matcher(token)
+ if (matcher.matches()) {
+ numbers.add(Integer.parseInt(matcher.group(1)))
+ qualifier = normalizeQualifier(matcher.group(2))
+ } else {
+ qualifier = normalizeQualifier(token)
+ }
+ break
+ }
+ }
+ return new ParsedVersion(numbers, qualifier)
+ }
+
+ private static int compareNumbers(List<Integer> a, List<Integer> b) {
+ int max = Math.max(a.size(), b.size())
+ for (int i = 0; i < max; i++) {
+ int left = i < a.size() ? a.get(i) : 0
+ int right = i < b.size() ? b.get(i) : 0
+ int result = Integer.compare(left, right)
+ if (result != 0) {
+ return result
+ }
+ }
+ return 0
+ }
+
+ private static int compareQualifiers(String q1, String q2) {
+ int tier = Integer.compare(qualifierTier(q1), qualifierTier(q2))
+ if (tier != 0) {
+ return tier
+ }
+ return Integer.compare(qualifierNumber(q1), qualifierNumber(q2))
+ }
Review Comment:
Good catch - fixed in edf2dda0f1. compareQualifiers now only compares the
trailing qualifier number for the milestone and release candidate tiers, so
unrecognised qualifiers stay equal to the final release within their tier.
7.0.0-FOO2 now compares equal to 7.0.0 instead of newer, and explicit spec
coverage was added.
##########
grails-bootstrap/src/main/groovy/grails/plugins/VersionComparator.groovy:
##########
@@ -112,4 +99,97 @@ class VersionComparator implements Comparator<String> {
protected boolean isSnapshot(String version) {
SNAPSHOT_SUFFIXES.any { String it -> version?.endsWith(it) }
}
+
+ /**
+ * Splits a version into its leading numeric components and an optional
trailing qualifier.
+ * The first token that is not purely numeric ends the numeric section. A
token of the form
+ * {@code <digits>-<qualifier>} (for example {@code 0-RC1} from {@code
7.0.0-RC1}) contributes
+ * its leading digits to the numeric section and the remainder becomes the
qualifier.
+ */
+ private static ParsedVersion parse(String version) {
+ List<Integer> numbers = []
+ String qualifier = null
+ if (version) {
+ for (String token : version.split(/\./)) {
+ if (DIGITS.matcher(token).matches()) {
+ numbers.add(Integer.parseInt(token))
+ continue
+ }
+ Matcher matcher = NUMERIC_PREFIX.matcher(token)
+ if (matcher.matches()) {
+ numbers.add(Integer.parseInt(matcher.group(1)))
+ qualifier = normalizeQualifier(matcher.group(2))
+ } else {
+ qualifier = normalizeQualifier(token)
+ }
+ break
+ }
+ }
+ return new ParsedVersion(numbers, qualifier)
+ }
+
+ private static int compareNumbers(List<Integer> a, List<Integer> b) {
+ int max = Math.max(a.size(), b.size())
+ for (int i = 0; i < max; i++) {
+ int left = i < a.size() ? a.get(i) : 0
+ int right = i < b.size() ? b.get(i) : 0
+ int result = Integer.compare(left, right)
+ if (result != 0) {
+ return result
+ }
+ }
+ return 0
+ }
+
+ private static int compareQualifiers(String q1, String q2) {
+ int tier = Integer.compare(qualifierTier(q1), qualifierTier(q2))
+ if (tier != 0) {
+ return tier
+ }
+ return Integer.compare(qualifierNumber(q1), qualifierNumber(q2))
+ }
Review Comment:
Good catch - fixed in edf2dda0f1. compareQualifiers now only compares the
trailing qualifier number for the milestone and release candidate tiers, so
unrecognised qualifiers stay equal to the final release within their tier.
7.0.0-FOO2 now compares equal to 7.0.0 instead of newer, and explicit spec
coverage was added.
##########
grails-bootstrap/src/main/groovy/grails/plugins/VersionComparator.groovy:
##########
@@ -18,79 +18,66 @@
*/
package grails.plugins
+import java.util.regex.Matcher
+import java.util.regex.Pattern
+
import groovy.transform.CompileStatic
/**
- * A comparator capable of sorting versions from from newest to oldest
+ * A comparator capable of sorting versions from newest to oldest.
+ *
Review Comment:
Fixed in edf2dda0f1 - the class Javadoc now states the comparator orders
versions from oldest to newest (a negative result means the first version is
older), matching the Comparator contract and the sort spec.
##########
grails-bootstrap/src/main/groovy/grails/plugins/VersionComparator.groovy:
##########
@@ -18,79 +18,66 @@
*/
package grails.plugins
+import java.util.regex.Matcher
+import java.util.regex.Pattern
+
import groovy.transform.CompileStatic
/**
- * A comparator capable of sorting versions from from newest to oldest
+ * A comparator capable of sorting versions from newest to oldest.
+ *
Review Comment:
Fixed in edf2dda0f1 - the class Javadoc now states the comparator orders
versions from oldest to newest (a negative result means the first version is
older), matching the Comparator contract and the sort spec.
##########
grails-core/src/test/groovy/grails/plugins/VersionComparatorSpec.groovy:
##########
@@ -44,5 +44,48 @@ class VersionComparatorSpec extends Specification {
"3.0.0" | "3.0.0" || 0
"4.0.1" | "3.1.110" || 1
"4.0.1" | "3.0.0.BUILD-SNAPSHOT" || 1
+
+ // A pre-release (milestone/rc/snapshot) is older than the final
release of the same number
+ "7.0.0-M1" | "7.0.0" || -1
+ "7.0.0" | "7.0.0-M1" || 1
+ "7.0.0-RC1" | "7.0.0" || -1
+ "7.0.0-SNAPSHOT" | "7.0.0" || -1
+ "7.0.0" | "7.0.0-SNAPSHOT" || 1
+
+ // The numeric version is compared before the qualifier, so the patch
number is never lost
+ "7.0.5-M1" | "7.0.0" || 1
+ "7.0.0" | "7.0.5-M1" || -1
+ "7.0.1-M1" | "7.0.0" || 1
+ "7.0.0-RC1" | "6.9.9" || 1
+ "6.9.9" | "7.0.0-RC1" || -1
+
+ // Milestones and release candidates are ordered by their number,
numerically not lexically
+ "7.0.0-M1" | "7.0.0-M2" || -1
+ "7.0.0-M2" | "7.0.0-M1" || 1
+ "7.0.0-RC1" | "7.0.0-RC2" || -1
+ "7.0.0-RC10" | "7.0.0-RC2" || 1
+
+ // Qualifier tiers: milestone < release candidate < snapshot < final
+ "7.0.0-M2" | "7.0.0-RC1" || -1
+ "7.0.0-RC1" | "7.0.0-SNAPSHOT" || -1
+ "7.0.0-M9" | "7.0.0-SNAPSHOT" || -1
+
+ // The dotted and hyphenated qualifier forms are equivalent, and
matching is case insensitive
+ "7.0.0.M1" | "7.0.0-M1" || 0
+ "7.0.0.RC1" | "7.0.0-RC1" || 0
+ "7.0.0.BUILD-SNAPSHOT" | "7.0.0-SNAPSHOT" || 0
+ "7.0.0-rc3" | "7.0.0-RC3" || 0
Review Comment:
Added in edf2dda0f1 - VersionComparatorSpec now asserts that an unrecognised
qualifier, including one with a trailing number such as 7.0.0-FOO2, compares
equal to the final 7.0.0.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]