diff --git a/__tests__/resolvers/exotics/bitbucket-resolver.js b/__tests__/resolvers/exotics/bitbucket-resolver.js index a3a5d151a6..168be27b39 100644 --- a/__tests__/resolvers/exotics/bitbucket-resolver.js +++ b/__tests__/resolvers/exotics/bitbucket-resolver.js @@ -1,11 +1,13 @@ /* @flow */ - +import {explodeHostedGitFragment} from '../../../src/resolvers/exotics/hosted-git-resolver.js'; import BitBucketResolver from '../../../src/resolvers/exotics/bitbucket-resolver.js'; import type {ExplodedFragment} from '../../../src/resolvers/exotics/hosted-git-resolver.js'; import Git from '../../../src/util/git.js'; +import * as reporters from '../../../src/reporters/index.js'; const url = require('url'); const _bitBucketBase = 'https://bitbucket.org/'; +const reporter = new reporters.NoopReporter({}); test('hostname should be "bitbucket.org" ', () => { expect(BitBucketResolver.hostname).toBe('bitbucket.org'); @@ -15,6 +17,54 @@ test('protocol should be "bitbucket" ', () => { expect(BitBucketResolver.protocol).toBe('bitbucket'); }); +test('explodeHostedGitFragment should work for colon separator after host', () => { + const fragmentString = 'git@bitbucket.org:team2/repo.git'; + + const expectedFragment: ExplodedFragment = { + user: 'team2', + repo: 'repo', + hash: '', + }; + + expect(explodeHostedGitFragment(fragmentString, reporter)).toEqual(expectedFragment); +}); + +test('explodeHostedGitFragment should work for colon separator after host and with protocol before', () => { + const fragmentString = 'git+ssh://git@bitbucket.org:team/repo.git'; + + const expectedFragment: ExplodedFragment = { + user: 'team', + repo: 'repo', + hash: '', + }; + + expect(explodeHostedGitFragment(fragmentString, reporter)).toEqual(expectedFragment); +}); + +test('explodeHostedGitFragment should work for slash separator after host', () => { + const fragmentString = 'git@bitbucket.org/team/repo.git'; + + const expectedFragment: ExplodedFragment = { + user: 'team', + repo: 'repo', + hash: '', + }; + + expect(explodeHostedGitFragment(fragmentString, reporter)).toEqual(expectedFragment); +}); + +test('explodeHostedGitFragment should work for package name and colon separator after host', () => { + const fragmentString = 'package@git@bitbucket.org:team/repo.git'; + + const expectedFragment: ExplodedFragment = { + user: 'team', + repo: 'repo', + hash: '', + }; + + expect(explodeHostedGitFragment(fragmentString, reporter)).toEqual(expectedFragment); +}); + test('getTarballUrl should return the correct bitbucket tarball url', () => { const fragment: ExplodedFragment = { user: 'foo', diff --git a/src/resolvers/exotics/git-resolver.js b/src/resolvers/exotics/git-resolver.js index 933df367d9..bc2e32877a 100644 --- a/src/resolvers/exotics/git-resolver.js +++ b/src/resolvers/exotics/git-resolver.js @@ -15,7 +15,7 @@ const urlParse = require('url').parse; // we purposefully omit https and http as those are only valid if they end in the .git extension const GIT_PROTOCOLS = ['git:', 'git+ssh:', 'git+https:', 'ssh:']; -const GIT_HOSTS = ['github.com', 'gitlab.com', 'bitbucket.com']; +const GIT_HOSTS = ['github.com', 'gitlab.com', 'bitbucket.com', 'bitbucket.org']; export default class GitResolver extends ExoticResolver { constructor(request: PackageRequest, fragment: string) { diff --git a/src/resolvers/exotics/hosted-git-resolver.js b/src/resolvers/exotics/hosted-git-resolver.js index 76bf36dcda..0be7d9c49e 100644 --- a/src/resolvers/exotics/hosted-git-resolver.js +++ b/src/resolvers/exotics/hosted-git-resolver.js @@ -15,21 +15,45 @@ export type ExplodedFragment = { hash: string, }; -export function explodeHostedGitFragment(fragment: string, reporter: Reporter): ExplodedFragment { - // TODO: make sure this only has a length of 2 +export function explodeHostedGitFragment(fragment: string, reporter: Reporter): ExplodedFragment { + + const preParts = fragment.split('@'); + if (preParts.length > 2) { + fragment = preParts[1] + '@' + preParts[2]; + } + const parts = fragment.split(':'); - fragment = parts.pop(); - const userParts = fragment.split('/'); + if (parts.length == 3) { // protocol + host + folder + parts[1] = parts[1].indexOf('//') >= 0 ? parts[1].substr(2) : parts[1]; + fragment = parts[1] + '/' + parts[2]; + } else if (parts.length == 2) { + if (parts[0].indexOf('@') == -1) { // protocol + host + fragment = parts[1]; + } else { // host + folder + fragment = parts[0] + '/' + parts[1]; + } + } else if (parts.length == 1) { + fragment = parts[0]; + } else { + throw new MessageError(reporter.lang('invalidHostedGitFragment', fragment)); + } + + const userParts = fragment.split('/'); if (userParts.length >= 2) { + + if (userParts[0].indexOf('@') >= 0) { + userParts.shift(); + } + const user = userParts.shift(); const repoParts = userParts.join('/').split(/(?:[.]git)?#(.*)/); if (repoParts.length <= 3) { return { user, - repo: repoParts[0], + repo: repoParts[0].replace('.git', ''), hash: repoParts[1] || '', }; }