From cdb9fbe8cc48c8933e6d6c6152661afe260079c3 Mon Sep 17 00:00:00 2001 From: Peter Chanthamynavong Date: Sun, 12 Jul 2015 11:51:44 -0700 Subject: [PATCH] upgrade to newer semver, fixes #1817,#1845,#1851 Upgrading to latest version of semver to fix (#1817, #1845, #1851). Possible breaking changes in regards to the way semvers handles pre-releases. If a version has a prerelease tags (for example, 1.2.3-alpha.3) then it will only be allowed to satisfy comparator sets if at least one comparator with the same [major, minor, patch] tuple also has a prerelease tag. For example, the range >1.2.3-alpha.0 would be allowed to match the version 1.2.3-alpha.7, but it would not be satisfied by * or 1.2.3. See [semvers](https://github.com/npm/node-semver#prerelease-tags) additional details. --- package.json | 3 ++- test/core/resolveCache.js | 32 +++++++++++++++++++++++++++++- test/core/resolvers/gitResolver.js | 31 ++++++++++++++++++++++++++--- test/core/resolvers/svnResolver.js | 28 ++++++++++++++++++++++++-- 4 files changed, 87 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 447c1cb76..e855e7737 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "request-progress": "0.3.1", "retry": "0.6.1", "rimraf": "^2.2.8", - "semver": "^2.3.0", + "semver": "^5.0.0", "shell-quote": "^1.4.2", "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", @@ -73,6 +73,7 @@ "nock": "^0.56.0", "node-uuid": "^1.4.2", "proxyquire": "^1.3.0", + "semver": "^5.0.0", "spawn-sync": "^1.0.5" }, "scripts": { diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index 9ea798ede..7f7830bef 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -513,7 +513,7 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.1.0-rc.2')); fs.writeFileSync(path.join(sourceDir, '0.1.0-rc.2', '.bower.json'), JSON.stringify(json, null, ' ')); - resolveCache.retrieve(source, '~0.1.0') + resolveCache.retrieve(source, '~0.1.0 || ~0.1.0-rc.0') .spread(function (canonicalDir, pkgMeta) { expect(pkgMeta).to.be.an('object'); expect(pkgMeta.version).to.equal('0.1.0-rc.2'); @@ -524,6 +524,36 @@ describe('ResolveCache', function () { .done(); }); + it('should resolve to the highest package that matches an x-range target, ignoring pre-releases versions', function (next) { + var source = String(Math.random()); + var sourceId = md5(source); + var sourceDir = path.join(cacheDir, sourceId); + var json = { name: 'foo' }; + + // Create some versions + fs.mkdirSync(sourceDir); + + // fix #1817 : >=1.2.x <=1.4.x which resolved to 1.3.16 + + json.version = '1.3.16-rc.1'; + fs.mkdirSync(path.join(sourceDir, json.version)); + fs.writeFileSync(path.join(sourceDir, json.version, '.bower.json'), JSON.stringify(json, null, ' ')); + + json.version = '1.3.16'; + fs.mkdirSync(path.join(sourceDir, json.version)); + fs.writeFileSync(path.join(sourceDir, json.version, '.bower.json'), JSON.stringify(json, null, ' ')); + + resolveCache.retrieve(source, '>=1.2.x <=1.4.x') + .spread(function (canonicalDir, pkgMeta) { + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.version).to.equal('1.3.16'); + expect(canonicalDir).to.equal(path.join(sourceDir, '1.3.16')); + + next(); + }) + .done(); + }); + it('should resolve to exact match (including build metadata) if available', function (next) { var source = String(Math.random()); var sourceId = md5(source); diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index cb74e9822..b7d0dbeb2 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -506,7 +506,7 @@ describe('GitResolver', function () { .done(); }); - it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { + it('should fail to resolve "*" if a repository has valid semver tags, ignoring pre-releases if they are the only versions', function (next) { var resolver; GitResolver.refs = function () { @@ -519,6 +519,31 @@ describe('GitResolver', function () { resolver = create('foo'); resolver._findResolution('*') + .then(function () { + next(new Error('Should have failed')); + }, function (err) { + expect(err).to.be.an(Error); + expect(err.message).to.match(/no tag found that was able to satisfy/i); + expect(err.details).to.match(/0.1.0-rc/i); + expect(err.code).to.equal('ENORESTARGET'); + next(); + }) + .done(); + }); + + it('should resolve "* || >=0.1.0-rc.0" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { + var resolver; + + GitResolver.refs = function () { + return Q.resolve([ + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.0-rc.1', + 'cccccccccccccccccccccccccccccccccccccccc refs/tags/0.1.0-rc.2' + ]); + }; + + resolver = create('foo'); + resolver._findResolution('* || >=0.1.0-rc.0') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', @@ -542,7 +567,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('0.1.*') + resolver._findResolution('0.1.* || >=0.1.0-rc.1') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', @@ -642,7 +667,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('~0.2.1') + resolver._findResolution('~0.2.1-rc.0') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index 47a8a5a37..259aa1e47 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -362,7 +362,7 @@ else describe('SvnResolver', function () { .done(); }); - it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { + it('should fail to resolve "*" if a repository has valid semver tags, ignoring pre-releases if they are the only versions', function (next) { var resolver; SvnResolver.tags = function () { @@ -374,6 +374,30 @@ else describe('SvnResolver', function () { resolver = create('foo'); resolver._findResolution('*') + .then(function () { + next(new Error('Should have failed')); + }, function (err) { + expect(err).to.be.an(Error); + expect(err.message).to.match(/no tag found that was able to satisfy/i); + expect(err.details).to.match(/0.1.0-rc/i); + expect(err.code).to.equal('ENORESTARGET'); + next(); + }) + .done(); + }); + + it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + '0.1.0-rc.1': 1, + '0.1.0-rc.2': 2 + }); + }; + + resolver = create('foo'); + resolver._findResolution('* || >=0.1.0-rc.0') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', @@ -445,7 +469,7 @@ else describe('SvnResolver', function () { }; resolver = create('foo'); - resolver._findResolution('~0.2.1') + resolver._findResolution('~0.2.1 || ~0.2.1-rc.0') .then(function (resolution) { expect(resolution).to.eql({ type: 'version',