diff --git a/common.js b/common.js index 001e4064..dfb8a997 100644 --- a/common.js +++ b/common.js @@ -25,6 +25,7 @@ const submodules = [ 'uint64', // Uint64 'units', // Units conversion 'utilities', // Common utilities + 'version', // Version compare and compatibility check ].map(path => require('./lib/' + path)); module.exports = Object.assign({}, ...submodules); diff --git a/lib/version.js b/lib/version.js new file mode 100644 index 00000000..cbd960c0 --- /dev/null +++ b/lib/version.js @@ -0,0 +1,57 @@ +'use strict'; + +// Compare versions +// v1 - , with format `a.b.c` +// v2 - , with format `x.y.z` +// Returns: +// - `0` if `v1` and `v2` are equal +// - `1` if `v1` > `v2` +// - `-1` if `v1` < `v2` +const compareVersions = (v1, v2) => { + if (v1 === v2) return 0; + const arr1 = v1.split('.').map(num => parseInt(num)); + const arr2 = v2.split('.').map(num => parseInt(num)); + + if (arr1.length < arr2.length) { + arr1.push(...Array(arr2.length - arr1.length).fill(0)); + } else if (arr2.length < arr1.length) { + arr2.push(...Array(arr1.length - arr2.length).fill(0)); + } + + for (let i = 0; i < arr1.length; i++) { + if (arr1[i] < arr2[i]) return -1; + if (arr1[i] > arr2[i]) return 1; + } + return 0; +}; + +// Check if first version is equal or bigger than the second one +// v1 - , with format `a.b.c` +// v2 - , with format `x.y.z` +// Returns: +// - `true` if `v1` and `v2` are equal or `v1` < `v2` +// - `false` if `v1` > `v2` +const checkVersion = (v1, v2) => compareVersions(v1, v2) <= 0; + +// Check if `process.versions.node` is equal or bigger than the specified one +// version - , with format `a.b.c` +// Returns: +// - `true` if `version` is less or equal than `process.versions.node` +// - `false` if `version` is bigger than `process.versions.node` +const checkNodeVersion = version => + compareVersions(version, process.versions.node) <= 0; + +// Check if `process.versions.v8` is equal or bigger than the specified one +// version - , with format `a.b.c` +// Returns: +// - `true` if `version` is less or equal than `process.versions.v8` +// - `false` if `version` is bigger than `process.versions.v8` +const checkV8Version = version => + compareVersions(version, process.versions.v8) <= 0; + +module.exports = { + compareVersions, + checkVersion, + checkNodeVersion, + checkV8Version, +}; diff --git a/test/version.js b/test/version.js new file mode 100644 index 00000000..5fb27a8c --- /dev/null +++ b/test/version.js @@ -0,0 +1,67 @@ +'use strict'; + +const metatests = require('metatests'); +const common = require('..'); + +metatests.case( + 'Common / version', + { common }, + { + 'common.compareVersions': [ + ['0', '0', 0], + ['00', '0', 0], + ['0', '00', 0], + ['0.0', '0', 0], + ['0', '0.0', 0], + + ['1', '1', 0], + ['01', '1', 0], + ['1', '01', 0], + ['1.0', '1', 0], + ['1', '1.0', 0], + + ['0', '1', -1], + ['1.2', '1.3', -1], + ['1.2.1', '1.3', -1], + ['1.2', '1.2.3', -1], + ['1.2', '12', -1], + ['2.1', '21', -1], + + ['1', '0', 1], + ['1.3', '1.2', 1], + ['1.3', '1.2.1', 1], + ['1.2.3', '1.2', 1], + ['12', '1.2', 1], + ['21', '2.1', 1], + ], + 'common.checkVersion': [ + ['0', '0', true], + ['00', '0', true], + ['0', '00', true], + ['0.0', '0', true], + ['0', '0.0', true], + + ['1', '1', true], + ['01', '1', true], + ['1', '01', true], + ['1.0', '1', true], + ['1', '1.0', true], + + ['0', '1', true], + ['1.2', '1.3', true], + ['1.2.1', '1.3', true], + ['1.2', '1.2.3', true], + ['1.2', '12', true], + ['2.1', '21', true], + + ['1', '0', false], + ['1.3', '1.2', false], + ['1.3', '1.2.1', false], + ['1.2.3', '1.2', false], + ['12', '1.2', false], + ['21', '2.1', false], + ], + 'common.checkNodeVersion': [[process.versions.node, true]], + 'common.checkV8Version': [[process.versions.v8, true]], + } +);