From 94491ba0d0e18dd4ef475b3b061cf30415e5ebda Mon Sep 17 00:00:00 2001 From: Sergio Zharinov <zharinov@users.noreply.github.com> Date: Sat, 5 Jan 2019 20:32:55 +0400 Subject: [PATCH] feat: Implement auxiliary functions for maven versioning (#3028) --- lib/versioning/maven/compare.js | 20 ++++++-- lib/versioning/maven/index.js | 82 ++++++++++++++++++++++++++++----- test/versioning/maven.spec.js | 62 +++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 16 deletions(-) diff --git a/lib/versioning/maven/compare.js b/lib/versioning/maven/compare.js index 865f1830f0..fa6e77f206 100644 --- a/lib/versioning/maven/compare.js +++ b/lib/versioning/maven/compare.js @@ -79,10 +79,17 @@ function isNull(token) { return val === 0 || val === '' || val === 'final' || val === 'ga'; } +const zeroToken = { + prefix: PREFIX_HYPHEN, + type: TYPE_NUMBER, + val: 0, + isTransition: false, +}; + function tokenize(versionStr) { let buf = []; let result = []; - iterateTokens(versionStr, token => { + iterateTokens(versionStr.toLowerCase().replace(/^v/i, ''), token => { if (token.prefix === PREFIX_HYPHEN) { buf = []; } @@ -92,7 +99,7 @@ function tokenize(versionStr) { buf = []; } }); - return result; + return result.length ? result : [zeroToken]; } function nullFor(token) { @@ -196,8 +203,8 @@ function tokenCmp(left, right) { } function compare(left, right) { - const leftTokens = tokenize(left.toLowerCase()); - const rightTokens = tokenize(right.toLowerCase()); + const leftTokens = tokenize(left); + const rightTokens = tokenize(right); const length = Math.max(leftTokens.length, rightTokens.length); for (let idx = 0; idx < length; idx += 1) { const leftToken = leftTokens[idx] || nullFor(rightTokens[idx]); @@ -209,5 +216,10 @@ function compare(left, right) { } module.exports = { + PREFIX_DOT, + PREFIX_HYPHEN, + TYPE_NUMBER, + TYPE_QUALIFIER, + tokenize, compare, }; diff --git a/lib/versioning/maven/index.js b/lib/versioning/maven/index.js index 3ce865ec75..1a2d0971fe 100644 --- a/lib/versioning/maven/index.js +++ b/lib/versioning/maven/index.js @@ -1,25 +1,83 @@ /* istanbul ignore file */ -const { compare } = require('./compare'); +const { tokenize, compare, TYPE_NUMBER, TYPE_QUALIFIER } = require('./compare'); + +const isVersion = version => { + if (!version) return false; + if (!version.length) return false; + if (!/^v?\d[a-z0-9.-]*$/i.test(version)) return false; + const tokens = tokenize(version); + const majorToken = tokens[0]; + return !!majorToken && majorToken.type === TYPE_NUMBER; +}; const equals = (a, b) => compare(a, b) === 0; -// TODO getMajor -const getMajor = () => 0; +const getMajor = version => { + if (isVersion(version)) { + const tokens = tokenize(version); + const majorToken = tokens[0]; + return majorToken.val; + } + return null; +}; -// TODO getMinor -const getMinor = () => 0; +const getMinor = version => { + if (isVersion(version)) { + const tokens = tokenize(version); + const minorToken = tokens[1]; + if (minorToken && minorToken.type === TYPE_NUMBER) { + return minorToken.val; + } + return 0; + } + return null; +}; -// TODO getPatch -const getPatch = () => 0; +const getPatch = version => { + if (isVersion(version)) { + const tokens = tokenize(version); + const minorToken = tokens[1]; + const patchToken = tokens[2]; + if ( + patchToken && + minorToken.type === TYPE_NUMBER && + patchToken.type === TYPE_NUMBER + ) { + return patchToken.val; + } + return 0; + } + return null; +}; const isGreaterThan = (a, b) => compare(a, b) === 1; -// TODO isStable -const isStable = () => true; - -// TODO isVersion -const isVersion = () => true; +const isStable = version => { + if (isVersion(version)) { + const tokens = tokenize(version); + const qualToken = tokens.find(token => token.type === TYPE_QUALIFIER); + if (qualToken) { + const val = qualToken.val; + if (val === 'final') { + return true; + } + if (val === 'ga') { + return true; + } + if (val === 'release') { + return true; + } + if (val === 'sp') { + return true; + } + // istanbul ignore next + return false; + } + return true; + } + return null; +}; const maxSatisfyingVersion = (versions, range) => versions.find(version => equals(version, range)); diff --git a/test/versioning/maven.spec.js b/test/versioning/maven.spec.js index a3ef2208ec..dc4967c7f0 100644 --- a/test/versioning/maven.spec.js +++ b/test/versioning/maven.spec.js @@ -1,4 +1,11 @@ const { compare } = require('../../lib/versioning/maven/compare'); +const { + isVersion, + isStable, + getMajor, + getMinor, + getPatch, +} = require('../../lib/versioning/maven/index'); describe('versioning/maven/compare', () => { it('returns equality', () => { @@ -36,6 +43,7 @@ describe('versioning/maven/compare', () => { expect(compare('1-0-ga', '1.0')).toEqual(0); expect(compare('1-0-final', '1-0')).toEqual(0); expect(compare('1-0', '1.0')).toEqual(0); + expect(compare('v1.2.3', '1.2.3')).toEqual(0); }); it('returns less than', () => { expect(compare('1', '1.1')).toEqual(-1); @@ -70,3 +78,57 @@ describe('versioning/maven/compare', () => { expect(compare('1', '1-cr1')).toEqual(1); }); }); + +describe('versioning/maven/index', () => { + it('validates version string', () => { + expect(isVersion('')).toEqual(false); + expect(isVersion('1.0.0')).toEqual(true); + expect(isVersion('0')).toEqual(true); + expect(isVersion('0.1-2-sp')).toEqual(true); + expect(isVersion('1-final')).toEqual(true); + expect(isVersion('v1.0.0')).toEqual(true); + expect(isVersion('x1.0.0')).toEqual(false); + }); + it('checks if version is stable', () => { + expect(isStable('')).toEqual(null); + expect(isStable('foobar')).toEqual(null); + expect(isStable('1')).toEqual(true); + expect(isStable('1.2')).toEqual(true); + expect(isStable('1.2.3')).toEqual(true); + expect(isStable('1.2.3.4')).toEqual(true); + expect(isStable('v1.2.3.4')).toEqual(true); + expect(isStable('1-alpha-1')).toEqual(false); + expect(isStable('1-b1')).toEqual(false); + expect(isStable('1.final')).toEqual(true); + expect(isStable('1.0milestone1')).toEqual(false); + expect(isStable('1-sp')).toEqual(true); + expect(isStable('1-ga-1')).toEqual(true); + }); + it('returns major version', () => { + expect(getMajor('')).toEqual(null); + expect(getMajor('1')).toEqual(1); + expect(getMajor('1.2')).toEqual(1); + expect(getMajor('1.2.3')).toEqual(1); + expect(getMajor('v1.2.3')).toEqual(1); + expect(getMajor('1rc42')).toEqual(1); + }); + it('returns minor version', () => { + expect(getMinor('')).toEqual(null); + expect(getMinor('1')).toEqual(0); + expect(getMinor('1.2')).toEqual(2); + expect(getMinor('1.2.3')).toEqual(2); + expect(getMinor('v1.2.3')).toEqual(2); + expect(getMinor('1.2.3.4')).toEqual(2); + expect(getMinor('1-rc42')).toEqual(0); + }); + it('returns patch version', () => { + expect(getPatch('')).toEqual(null); + expect(getPatch('1')).toEqual(0); + expect(getPatch('1.2')).toEqual(0); + expect(getPatch('1.2.3')).toEqual(3); + expect(getPatch('v1.2.3')).toEqual(3); + expect(getPatch('1.2.3.4')).toEqual(3); + expect(getPatch('1-rc10')).toEqual(0); + expect(getPatch('1-rc42-1')).toEqual(0); + }); +}); -- GitLab