Last active
May 10, 2022 04:15
-
-
Save banasiak/9628d1fe2b81164543cde0dd77621631 to your computer and use it in GitHub Desktop.
A version string comparator that adheres to the SemVer standard (https://semver.org)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SemanticVersionComparator: Comparator<String> { | |
private val nonDigits: Regex = Regex("[^\\d.]") | |
private val onPeriods: Regex = Regex("\\.") | |
override fun compare(currentVersion: String, otherVersion: String): Int { | |
// remove everything after the "+" character, sanitize non-digits, then split on the periods | |
val semVerCurrent: MutableList<String> = currentVersion | |
.substringBefore("+") | |
.replace(nonDigits, "") | |
.split(onPeriods) | |
.toMutableList() | |
val semVerOther: MutableList<String> = otherVersion | |
.substringBefore("+") | |
.replace(nonDigits, "") | |
.split(onPeriods) | |
.toMutableList() | |
// version numbers not in the form of MAJOR.MINOR.PATCH violate the SemVer standard, so | |
// add padding zeros to account for legacy conditions (ex: 6.23 -> 6.23.0) | |
for (i in semVerCurrent.size until 3) { | |
semVerCurrent.add("0") | |
} | |
for (i in semVerOther.size until 3) { | |
semVerOther.add("0") | |
} | |
// make a non-mutable defensive copy of the first 3 digits from the list | |
val current: List<String> = semVerCurrent.subList(0, 3).toList() | |
val other: List<String> = semVerOther.subList(0, 3).toList() | |
// iterate through the semantic version digits, | |
// these lists should be the same length, but use 'minOf' for safety | |
for(i in 0 until minOf(current.size, other.size)) { | |
val currentDigit = current[i].toInt() | |
val otherDigit = other[i].toInt() | |
// if the two digits aren't equal, compare them and return the comparison result | |
if(currentDigit != otherDigit) { | |
return currentDigit.compareTo(otherDigit) | |
} | |
} | |
// the two versions are equal | |
return 0 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment