diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index a605eec7..2e01b017 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -45,8 +45,8 @@ function getConstructor(source, config, registryClient) { }); } - // SVN case: svn, svn+ssh - if (/^svn(\+ssh)?:\/\//i.test(source)) { + // SVN case: svn, svn+ssh, svn+http, svn+https, svn+file + if (/^svn(\+(ssh|https?|file))?:\/\//i.test(source)) { return Q.fcall(function () { return [resolvers.Svn, source]; }); diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index 137d97a6..bc484e10 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -365,12 +365,10 @@ SvnResolver.clearRuntimeCache = function () { // source url cleaning utility function // reason: the constructor is not called when using commands such as "list" SvnResolver.sourceUrl = function (source) { - if (!mout.string.startsWith(source, 'http://')) { - // force use http urls - return source.replace('svn://', 'http://').replace(/\/+$/, ''); - } - - return source; + return source + .replace(/^svn\+(https?|file):\/\//i, '$1://') // Change svn+http or svn+https or svn+file to http(s), file respectively + .replace('svn://', 'http://') // Change svn to http + .replace(/\/+$/, ''); // Remove trailing slashes }; SvnResolver._cache = { diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 0f953fc3..ee733ae3 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -339,6 +339,83 @@ describe('resolverFactory', function () { .done(); }); + it('should recognize svn remote endpoints correctly', function (next) { + var promise = Q.resolve(); + var endpoints; + + endpoints = { + // svn: + 'svn://hostname.com/user/project': 'http://hostname.com/user/project', + 'svn://hostname.com/user/project/': 'http://hostname.com/user/project', + + // svn@: + 'svn://svn@hostname.com:user/project': 'http://svn@hostname.com:user/project', + 'svn://svn@hostname.com:user/project/': 'http://svn@hostname.com:user/project', + + // svn+http + 'svn+http://hostname.com/project/blah': 'http://hostname.com/project/blah', + 'svn+http://hostname.com/project/blah/': 'http://hostname.com/project/blah', + 'svn+http://user@hostname.com/project/blah': 'http://user@hostname.com/project/blah', + 'svn+http://user@hostname.com/project/blah/': 'http://user@hostname.com/project/blah', + + // svn+https + 'svn+https://hostname.com/project/blah': 'https://hostname.com/project/blah', + 'svn+https://hostname.com/project/blah/': 'https://hostname.com/project/blah', + 'svn+https://user@hostname.com/project/blah': 'https://user@hostname.com/project/blah', + 'svn+https://user@hostname.com/project/blah/': 'https://user@hostname.com/project/blah', + + // svn+ssh + 'svn+ssh://hostname.com/project/blah': 'svn+ssh://hostname.com/project/blah', + 'svn+ssh://hostname.com/project/blah/': 'svn+ssh://hostname.com/project/blah', + 'svn+ssh://user@hostname.com/project/blah': 'svn+ssh://user@hostname.com/project/blah', + 'svn+ssh://user@hostname.com/project/blah/': 'svn+ssh://user@hostname.com/project/blah', + + // svn+file + 'svn+file:///project/blah': 'file:///project/blah', + 'svn+file:///project/blah/': 'file:///project/blah' + }; + + mout.object.forOwn(endpoints, function (value, key) { + // Test without name and target + promise = promise.then(function () { + return callFactory({ source: key }); + }) + .then(function (resolver) { + expect(resolver).to.be.a(resolvers.Svn); + expect(resolver).to.not.be(resolvers.GitHub); + expect(resolver.getSource()).to.equal(value); + expect(resolver.getTarget()).to.equal('*'); + }); + + // Test with target + promise = promise.then(function () { + return callFactory({ source: key, target: 'commit-ish' }); + }) + .then(function (resolver) { + expect(resolver).to.be.a(resolvers.Svn); + expect(resolver).to.not.be(resolvers.GitHub); + expect(resolver.getSource()).to.equal(value); + expect(resolver.getTarget()).to.equal('commit-ish'); + }); + + // Test with name + promise = promise.then(function () { + return callFactory({ name: 'foo', source: key }); + }) + .then(function (resolver) { + expect(resolver).to.be.a(resolvers.Svn); + expect(resolver).to.not.be(resolvers.GitHub); + expect(resolver.getSource()).to.equal(value); + expect(resolver.getName()).to.equal('foo'); + expect(resolver.getTarget()).to.equal('*'); + }); + }); + + promise + .then(next.bind(next, null)) + .done(); + }); + it('should recognize local fs files/folder endpoints correctly', function (next) { var promise = Q.resolve(); var endpoints; diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index b2ddcc32..92e477a3 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -1167,21 +1167,21 @@ describe('GitResolver', function () { describe('#tags', function () { afterEach(clearResolverRuntimeCache); - it('should resolve to an empty array if no tags are found', function (next) { + it('should resolve to an empty hash if no tags are found', function (next) { GitResolver.refs = function () { return Q.resolve([]); }; GitResolver.tags('foo') .then(function (tags) { - expect(tags).to.be.an('array'); - expect(tags).to.eql([]); + expect(tags).to.be.an('object'); + expect(tags).to.eql({}); next(); }) .done(); }); - it('should resolve to an array of tags', function (next) { + it('should resolve to an hash of tags', function (next) { GitResolver.refs = function () { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master',