fix(git-resolver): git URLs with a colon should work (#3882)

ref #2352
This commit is contained in:
Zoltan Kochan
2021-10-18 15:55:48 +03:00
committed by GitHub
parent 68b1bf20ec
commit 930e104da3
4 changed files with 36 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/git-resolver": patch
---
Git URLs containing a colon should work.

View File

@@ -38,7 +38,7 @@ export default async function parsePref (pref: string): Promise<HostedPackageSpe
if (colonsPos === -1) return null
const protocol = pref.substr(0, colonsPos)
if (protocol && gitProtocols.has(protocol.toLocaleLowerCase())) {
const urlparse = new URL(pref)
const urlparse = new URL(escapeColon(pref))
if (!urlparse || !urlparse.protocol) return null
const match = urlparse.protocol === 'git+ssh:' && matchGitScp(pref)
if (match) {
@@ -58,6 +58,13 @@ export default async function parsePref (pref: string): Promise<HostedPackageSpe
return null
}
function escapeColon (url: string) {
if (!url.includes('@')) return url
const [front, ...backs] = url.split('@')
const escapedBacks = backs.map(e => e.replace(/:([^/])/, ':/$1'))
return [front, ...escapedBacks].join('@')
}
function urlToFetchSpec (urlparse: URL) {
urlparse.hash = ''
const fetchSpec = url.format(urlparse)

View File

@@ -259,6 +259,20 @@ test.skip('resolveFromGit() bitbucket with tag', async () => {
})
})
test('resolveFromGit() gitlab with colon in the URL', async () => {
const resolveResult = await resolveFromGit({ pref: 'ssh://git@gitlab:pnpm/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc' })
expect(resolveResult).toStrictEqual({
id: 'gitlab/pnpm/git-resolver/988c61e11dc8d9ca0b5580cb15291951812549dc',
normalizedPref: 'ssh://git@gitlab:pnpm/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc',
resolution: {
commit: '988c61e11dc8d9ca0b5580cb15291951812549dc',
repo: 'ssh://git@gitlab/pnpm/git-resolver',
type: 'git',
},
resolvedVia: 'git-repository',
})
})
test('resolveFromGit() gitlab with commit', async () => {
const resolveResult = await resolveFromGit({ pref: 'gitlab:pnpm/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc' })
expect(resolveResult).toStrictEqual({

View File

@@ -0,0 +1,9 @@
import parsePref from '@pnpm/git-resolver/lib/parsePref'
test.each([
['ssh://username:password@example.com:repo.git', 'ssh://username:password@example.com/repo.git'],
['ssh://username:password@example.com:repo/@foo.git', 'ssh://username:password@example.com/repo/@foo.git'],
])('the right colon is escaped', async (input, output) => {
const parsed = await parsePref(input)
expect(parsed?.fetchSpec).toBe(output)
})