Created
September 6, 2012 13:59
-
-
Save danielflower/3656539 to your computer and use it in GitHub Desktop.
Javascript comparison function for Maven version strings, where a snapshot is older than a release version. Useful for sorting arrays of Maven versions. Disclaimer: only claims to support the patterns as described by the unit tests.
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
/** | |
* Compares two Maven version strings and returns value suitable for use in Array.sort. | |
* @param {String} v1 | |
* @param {String} v2 | |
* @return {Number} Negative number if v1 is older than v2; positive number if v1 is newer than v2; 0 if equal. | |
*/ | |
exports.mavenVersionSortComparer = function (v1, v2) { | |
// Strategy: pad each part of the version with zeros so strings are same length, then do string compare. | |
// Snapshot version have an extra 0 put on the end, whereas release versions have a 1 on the end | |
// e.g. 1.5-SNAPSHOT vs. 1.10.0 => 1.05.0.a vs. 1.10.0.c | |
// e.g. 1.5 => [1,5] | |
var v1Bits = v1.split("."); | |
var v2Bits = v2.split("."); | |
var v1OriginalLength = v1Bits.length; | |
var v2OriginalLength = v2Bits.length; | |
// equalise the number of parts, e.g. [1, 5] => [1,5,0] | |
while (v1Bits.length < v2Bits.length) { | |
v1Bits.push("0"); | |
} | |
while (v2Bits.length < v1Bits.length) { | |
v2Bits.push("0"); | |
} | |
// Change snapshot versions to have an extra ".0" and release versions to have an extra ".1" | |
function alterBasedOnSnapshotOrReleaseVersion(bits, potentialTextPosition) { | |
if (bits[potentialTextPosition].indexOf("-SNAPSHOT") > 0) { | |
bits[potentialTextPosition] = bits[potentialTextPosition].replace("-SNAPSHOT", ""); | |
bits.push("0"); | |
} else if (bits[potentialTextPosition].indexOf("-") > 0) { | |
bits[potentialTextPosition] = bits[potentialTextPosition].replace(/\-.*/, ""); | |
bits.push("1"); | |
} else { | |
bits.push("2"); | |
} | |
} | |
alterBasedOnSnapshotOrReleaseVersion(v1Bits, v1OriginalLength - 1); | |
alterBasedOnSnapshotOrReleaseVersion(v2Bits, v2OriginalLength - 1); | |
// pad with zeros, e.g. [1,5,0] => [1,05,0] | |
for (var i = 0; i < v1Bits.length; i++) { | |
var targetLength = Math.max(v1Bits[i].length, v2Bits[i].length); | |
while (v1Bits[i].length < targetLength) { | |
v1Bits[i] = "0" + v1Bits[i]; | |
} | |
while (v2Bits[i].length < targetLength) { | |
v2Bits[i] = "0" + v2Bits[i]; | |
} | |
} | |
// back to normal, e.g. [1,05,0] => 1.05.0 | |
var transformed1 = v1Bits.join("."); | |
var transformed2 = v2Bits.join("."); | |
console.log("v1: " + v1 + "=>" + transformed1 + ", v2: " + v2 + "=>" + transformed2); | |
return transformed1.localeCompare(transformed2); | |
}; | |
// Some nodeunit tests | |
function assertOldIsOlderThanNewer(test, oldOne, newOne) { | |
test.ok(convert.mavenVersionSortComparer(oldOne, newOne) < 0, "older (" + oldOne + ") compared to newer (" + newOne + ")"); | |
test.ok(convert.mavenVersionSortComparer(newOne, oldOne) > 0, "newer (" + newOne + ") compared to older (" + oldOne + ")"); | |
} | |
function assertVersionsAreSame(test, v1, v2) { | |
test.strictEqual(convert.mavenVersionSortComparer(v1, v2), 0, "v1 (" + v1 + ") compared to v2 (" + v2 + ")"); | |
test.strictEqual(convert.mavenVersionSortComparer(v2, v1), 0, "v2 (" + v2 + ") compared to v1 (" + v1 + ")"); | |
} | |
exports.majorVersionIsNewerThanMinorVersion = function (test) { | |
assertOldIsOlderThanNewer(test, "1.6.9", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1.996.999", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1.0", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1.0", "2.0.0"); | |
test.done(); | |
}; | |
exports.versionsAreComparedNumerically = function (test) { | |
assertOldIsOlderThanNewer(test, "1.6.0", "1.10.0"); | |
assertOldIsOlderThanNewer(test, "1.6.999999999", "1.100.0"); | |
test.done(); | |
}; | |
exports.snapshotsAreOlderThanReleaseVersionsIfVersionsAreSame = function (test) { | |
assertOldIsOlderThanNewer(test, "1.0.0-SNAPSHOT", "1.0.0"); | |
assertOldIsOlderThanNewer(test, "1.0-SNAPSHOT", "1.0.0"); | |
assertOldIsOlderThanNewer(test, "1-SNAPSHOT", "1.0.0"); | |
test.done(); | |
}; | |
exports.snapshotsAreIgnoredIfVersionsAreDifferent = function (test) { | |
assertOldIsOlderThanNewer(test, "1.6.9-SNAPSHOT", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1.996.999-SNAPSHOT", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1-SNAPSHOT", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1.0-SNAPSHOT", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1.0-SNAPSHOT", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1.6.9", "2.0.0-SNAPSHOT"); | |
assertOldIsOlderThanNewer(test, "1.996.999", "2.0.0-SNAPSHOT"); | |
assertOldIsOlderThanNewer(test, "1", "2.0.0-SNAPSHOT"); | |
assertOldIsOlderThanNewer(test, "1.0", "2.0.0-SNAPSHOT"); | |
assertOldIsOlderThanNewer(test, "1.0", "2.0.0-SNAPSHOT"); | |
test.done(); | |
}; | |
exports.snapshotsAreIgnoredIfVersionsAreDifferent = function (test) { | |
assertOldIsOlderThanNewer(test, "1.6.9-SNAPSHOT", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1.996.999-SNAPSHOT", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1-SNAPSHOT", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1.0-SNAPSHOT", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1.0-SNAPSHOT", "2.0.0"); | |
assertOldIsOlderThanNewer(test, "1.6.9", "2.0.0-SNAPSHOT"); | |
assertOldIsOlderThanNewer(test, "1.996.999", "2.0.0-SNAPSHOT"); | |
assertOldIsOlderThanNewer(test, "1", "2.0.0-SNAPSHOT"); | |
assertOldIsOlderThanNewer(test, "1.0", "2.0.0-SNAPSHOT"); | |
assertOldIsOlderThanNewer(test, "1.0", "2.0.0-SNAPSHOT"); | |
test.done(); | |
}; | |
exports.nonStandardTextIsNewerThanSnapshotButOlderThanReleaseVersion = function (test) { | |
assertOldIsOlderThanNewer(test, "1.6.9-SNAPSHOT", "1.6.9-hotfix"); | |
assertOldIsOlderThanNewer(test, "1.6.9-hotfix", "1.6.9"); | |
test.done(); | |
}; | |
exports.versionsAreSameEvenWithDifferentNumberOfParts = function (test) { | |
assertVersionsAreSame(test, "1.20.300", "1.20.300"); | |
assertVersionsAreSame(test, "1.20", "1.20.0"); | |
assertVersionsAreSame(test, "1", "1.0.0"); | |
test.done(); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment