From 91d3729b3735f7645e1fab7e55e1c4ab9a567a98 Mon Sep 17 00:00:00 2001 From: Rhys Arkins <rhys@arkins.net> Date: Sat, 6 Oct 2018 09:43:25 +0200 Subject: [PATCH] feat: hashicorp semver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hashicorp’s semver is same as npm’s except for handling of “~> 1.2â€. For Hashicorp it means ^1.2 whereas for Hashicorp is means ~1.2. --- lib/versioning/index.js | 2 + lib/versioning/semver-hashicorp/index.js | 45 +++++++++++++++++++++ test/versioning/semver-hashicorp.spec.js | 50 ++++++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 lib/versioning/semver-hashicorp/index.js create mode 100644 test/versioning/semver-hashicorp.spec.js diff --git a/lib/versioning/index.js b/lib/versioning/index.js index cab16eeefa..d23484d1c1 100644 --- a/lib/versioning/index.js +++ b/lib/versioning/index.js @@ -1,12 +1,14 @@ const docker = require('./docker'); const semver = require('./semver'); const semverComposer = require('./semver-composer'); +const semverHashicorp = require('./semver-hashicorp'); const pep440 = require('./pep440'); const schemes = { docker, semver, semverComposer, + semverHashicorp, pep440, }; diff --git a/lib/versioning/semver-hashicorp/index.js b/lib/versioning/semver-hashicorp/index.js new file mode 100644 index 0000000000..66012a6f95 --- /dev/null +++ b/lib/versioning/semver-hashicorp/index.js @@ -0,0 +1,45 @@ +const semver = require('../semver'); + +function hashicorp2npm(input) { + // The only case incompatible with semver is a "short" ~>, e.g. ~> 1.2 + return input.replace(/~>(\s*\d+\.\d+$)/, '^$1'); +} + +const matches = (version, range) => + semver.matches(hashicorp2npm(version), hashicorp2npm(range)); + +const maxSatisfyingVersion = (versions, range) => + semver.maxSatisfyingVersion( + versions.map(hashicorp2npm), + hashicorp2npm(range) + ); + +const minSatisfyingVersion = (versions, range) => + semver.minSatisfyingVersion( + versions.map(hashicorp2npm), + hashicorp2npm(range) + ); + +function getNewValue(currentValue, rangeStrategy, fromVersion, toVersion) { + // handle specia. ~> 1.2 case + if (currentValue.match(/(~>\s*)\d+\.\d+$/)) { + return currentValue.replace( + /(~>\s*)\d+\.\d+$/, + `$1${semver.getMajor(toVersion)}.0` + ); + } + return semver.getNewValue( + currentValue, + rangeStrategy, + fromVersion, + toVersion + ); +} + +module.exports = { + ...semver, + matches, + maxSatisfyingVersion, + minSatisfyingVersion, + getNewValue, +}; diff --git a/test/versioning/semver-hashicorp.spec.js b/test/versioning/semver-hashicorp.spec.js new file mode 100644 index 0000000000..9ded6fc12f --- /dev/null +++ b/test/versioning/semver-hashicorp.spec.js @@ -0,0 +1,50 @@ +const semver = require('../../lib/versioning')('semverHashicorp'); + +describe('semver.matches()', () => { + it('handles tilde greater than', () => { + expect(semver.matches('4.2.0', '~> 4.0')).toBe(true); + expect(semver.matches('4.2.0', '~> 4.0.0')).toBe(false); + }); +}); +describe('semver.maxSatisfyingVersion()', () => { + it('handles tilde greater than', () => { + expect( + semver.maxSatisfyingVersion( + ['0.4.0', '0.5.0', '4.0.0', '4.2.0', '5.0.0'], + '~> 4.0' + ) + ).toBe('4.2.0'); + expect( + semver.maxSatisfyingVersion( + ['0.4.0', '0.5.0', '4.0.0', '4.2.0', '5.0.0'], + '~> 4.0.0' + ) + ).toBe('4.0.0'); + }); +}); +describe('semver.minSatisfyingVersion()', () => { + it('handles tilde greater than', () => { + expect( + semver.minSatisfyingVersion( + ['0.4.0', '0.5.0', '4.2.0', '5.0.0'], + '~> 4.0' + ) + ).toBe('4.2.0'); + expect( + semver.minSatisfyingVersion( + ['0.4.0', '0.5.0', '4.2.0', '5.0.0'], + '~> 4.0.0' + ) + ).toBe(null); + }); +}); +describe('semver.getNewValue()', () => { + it('handles tilde greater than', () => { + expect(semver.getNewValue('~> 1.2', 'replace', '1.2.3', '2.0.7')).toEqual( + '~> 2.0' + ); + expect(semver.getNewValue('~> 1.2.0', 'replace', '1.2.3', '2.0.7')).toEqual( + '~> 2.0.0' + ); + }); +}); -- GitLab