Last active
August 29, 2015 14:24
-
-
Save harrishancock/d4c59027b0c3aeb4bc26 to your computer and use it in GitHub Desktop.
Some version parsing, generating, and comparison functions
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
// If a string begins with 'v' and ends with a dotted sequence of numbers, | |
// return an array of those numbers. Otherwise, return null. | |
// Examples: | |
// 'v1' -> [ 1 ] | |
// 'v1.2' -> [ 1, 2 ] | |
// 'v1.2.3' -> [ 1, 2, 3 ] | |
// '1.2.3' -> null | |
function parseVersion (v) { | |
function parseDecInt (a) { | |
return parseInt(a, 10); | |
} | |
var result = /^v(\d+(?:\.\d+)*)$/.exec(v); | |
return result | |
? result[1].split('.').map(parseDecInt) | |
: null; | |
} | |
// The inverse operation of parseVersion: given an array of numbers, return a | |
// string beginning with 'v' and ending with the sequence of numbers in dotted | |
// format. | |
function generateVersion (v) { | |
return 'v' + v.reduce(function (p, v) { | |
// Force numbers to be integers with |0 so we don't end up with floating | |
// points in the version string. Perhaps paranoid? | |
return (p|0).toString() + '.' + (v|0); | |
}); | |
} | |
// Compare two arrays of numbers lexicographically. Return less than zero if a | |
// is ordered before b, greater than zero if b is ordered before a, and zero if | |
// the two arguments compare equal. If one array is a prefix of the other, the | |
// shorter of the two arrays is ordered before the longer. Suitable for use | |
// with Array.sort(). | |
function lexicographicCompare (a, b) { | |
for (var i = 0; i < Math.max(a.length, b.length); ++i) { | |
if (a[i] != b[i]) { | |
return undefined === a[i] || a[i] < b[i] | |
? -1 : 1; | |
} | |
} | |
return 0; | |
} | |
// Choose the maximum version among an array of version arrays and return it. | |
function maxVersion (versions) { | |
function chooseGreaterVersion (p, v) { | |
return lexicographicCompare(p, v) > 0 ? p : v; | |
} | |
var versionArrays = versions.map(parseVersion).filter(Boolean); | |
return versionArrays.length | |
? generateVersion(versionArrays.reduce(chooseGreaterVersion)) | |
: null; | |
} | |
// Split a filename into its stem and extension, if present. The extension's | |
// dot is retained to distinguish no extension from an empty extension. | |
// Examples: | |
// 'a.b.c' -> { stem: 'a.b', extension: '.c' } | |
// 'a.' -> { stem: 'a', extension: '.' } | |
// 'a' -> { stem: 'a', extension: null } | |
function splitFilename (a) { | |
var i = a.lastIndexOf('.'); | |
return i > 0 | |
? { stem: a.slice(0, i), extension: a.slice(i) } | |
: { stem: a.slice(0), extension: null }; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment