From 7dc09e2e8df1da93c22f99043743cc98aa64d150 Mon Sep 17 00:00:00 2001 From: Thaddee Tyl Date: Tue, 5 Apr 2016 22:21:23 +0200 Subject: [PATCH] Added dotted-version comparator & latest version As planned in https://github.com/badges/shields/issues/490#issuecomment-205550621. Fixes #490. --- server.js | 60 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/server.js b/server.js index 13eab15..0a71903 100644 --- a/server.js +++ b/server.js @@ -5245,27 +5245,52 @@ function versionColor(version) { } } +// Take string versions. +// -1 if v1 < v2, 1 if v1 > v2, 0 otherwise. +function compareDottedVersion(v1, v2) { + var parts1 = /([0-9\.]+)(.*)$/.exec(v1); + var parts2 = /([0-9\.]+)(.*)$/.exec(v2); + if (parts1 != null && parts2 != null) { + var numbers1 = parts1[1]; + var numbers2 = parts2[1]; + var distinguisher1 = parts1[2]; + var distinguisher2 = parts2[2]; + var numlist1 = numbers1.split('.').map(function(e) { return +e; }); + var numlist2 = numbers2.split('.').map(function(e) { return +e; }); + var cmp = listCompare(numlist1, numlist2); + if (cmp !== 0) { return cmp; } + else { return distinguisher1 < distinguisher2? -1: + distinguisher1 > distinguisher2? 1: 0; } + } + return v1 < v2? -1: v1 > v2? 1: 0; +} + +// Take a list of string versions. +// Return the latest, or undefined, if there are none. +function latestDottedVersion(versions) { + var len = versions.length; + if (len === 0) { return; } + var version = versions[0]; + for (var i = 1; i < len; i++) { + if (compareDottedVersion(version, versions[i]) < 0) { + version = versions[i]; + } + } + return version; +} + // Given a list of versions (as strings), return the latest version. +// Return undefined if no version could be found. function latestVersion(versions) { var version = ''; var origVersions = versions; versions = versions.filter(function(version) { return (/^v?[0-9]/).test(version); }); - semver_versions = versions.map(function(version) { - var matches = /^(v?[0-9]+)(\.[0-9]+)?(-.*)?$/.exec(version); - if (matches) { - version = matches[1] + (matches[2] ? matches[2] : '.0') + '.0' + - (matches[3] ? matches[3] : ''); - } - return version; - }); try { - version = semver.maxSatisfying(semver_versions, ''); - version = versions[semver_versions.indexOf(version)]; + version = semver.maxSatisfying(versions, ''); } catch(e) { - versions = versions.sort(); - version = versions[versions.length - 1]; + version = latestDottedVersion(versions); } if (version === undefined) { origVersions = origVersions.sort(); @@ -5381,20 +5406,15 @@ function phpNumberedVersionData(version) { } function listCompare(a, b) { - for (var i = 0; i < a.length; i++) { + var alen = a.length, blen = b.length; + for (var i = 0; i < alen; i++) { if (a[i] < b[i]) { return -1; } else if (a[i] > b[i]) { return 1; } } - if (a.length < b.length) { - return -1; - } else if (a.length > b.length) { - return 1; - } else { - return 0; - } + return alen - blen; } // Return a negative value if v1 < v2,