diff --git a/lib/npa.js b/lib/npa.js index 8094b3e..e926058 100644 --- a/lib/npa.js +++ b/lib/npa.js @@ -17,6 +17,7 @@ const hasSlashes = isWindows ? /\\|[/]/ : /[/]/ const isURL = /^(?:git[+])?[a-z]+:/i const isGit = /^[^@]+@[^:.]+\.[^:]+:.+$/i const isFilename = /[.](?:tgz|tar.gz|tar)$/i +const isPortNumber = /:[0-9]+(\/|$)/i function npa (arg, where) { let name @@ -324,7 +325,9 @@ function fromURL (res) { // git+ssh://git@my.custom.git.com:username/project.git#deadbeef // ...and various combinations. The username in the beginning is *required*. const matched = rawSpec.match(/^git\+ssh:\/\/([^:#]+:[^#]+(?:\.git)?)(?:#(.*))?$/i) - if (matched && !matched[1].match(/:[0-9]+\/?.*$/i)) { + // Filter out all-number "usernames" which are really port numbers + // They can either be :1234 :1234/ or :1234/path but not :12abc + if (matched && !matched[1].match(isPortNumber)) { res.type = 'git' setGitAttrs(res, matched[2]) res.fetchSpec = matched[1] diff --git a/test/github.js b/test/github.js index f4fa1f0..bd3d2a4 100644 --- a/test/github.js +++ b/test/github.js @@ -89,12 +89,37 @@ require('tap').test('basic', function (t) { raw: 'foo@bar/foo', }, + 'git@github.com:12345': { + name: undefined, + type: 'git', + saveSpec: 'git+ssh://git@github.com:12345', + fetchSpec: 'ssh://git@github.com:12345', + raw: 'git@github.com:12345', + }, + + 'git@github.com:12345/': { + name: undefined, + type: 'git', + saveSpec: 'git+ssh://git@github.com:12345/', + fetchSpec: 'ssh://git@github.com:12345/', + raw: 'git@github.com:12345/', + }, + 'git@github.com:12345/foo': { name: undefined, type: 'git', saveSpec: 'git+ssh://git@github.com:12345/foo', + fetchSpec: 'ssh://git@github.com:12345/foo', raw: 'git@github.com:12345/foo', }, + + 'git@github.com:12345foo': { + name: undefined, + type: 'git', + saveSpec: 'git+ssh://git@github.com:12345foo', + fetchSpec: 'git@github.com:12345foo', + raw: 'git@github.com:12345foo', + }, } Object.keys(tests).forEach(function (arg) {