diff --git a/lib/versioning/index.js b/lib/versioning/index.js index cab16eeefa3a4dd361fb1b0067e657cb7fbd0e1a..d23484d1c137809a1a8b98839c8f0903c6e35fc2 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 0000000000000000000000000000000000000000..66012a6f95a70a8015848728d4559eed8f99c7b8 --- /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 0000000000000000000000000000000000000000..9ded6fc12fbbacb2e191e827c9dc0a00398a4f4f --- /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' + ); + }); +});