@@ -4,7 +4,7 @@ module.exports.resolve = resolve
4
4
module . exports . toPurl = toPurl
5
5
module . exports . Result = Result
6
6
7
- const url = require ( 'url' )
7
+ const { URL } = require ( 'url' )
8
8
const HostedGit = require ( 'hosted-git-info' )
9
9
const semver = require ( 'semver' )
10
10
const path = global . FAKE_WINDOWS ? require ( 'path' ) . win32 : require ( 'path' )
@@ -245,8 +245,8 @@ function fromFile (res, where) {
245
245
const rawWithPrefix = prefix + res . rawSpec
246
246
let rawNoPrefix = rawWithPrefix . replace ( / ^ f i l e : / , '' )
247
247
try {
248
- resolvedUrl = new url . URL ( rawWithPrefix , `file://${ path . resolve ( where ) } /` )
249
- specUrl = new url . URL ( rawWithPrefix )
248
+ resolvedUrl = new URL ( rawWithPrefix , `file://${ path . resolve ( where ) } /` )
249
+ specUrl = new URL ( rawWithPrefix )
250
250
} catch ( originalError ) {
251
251
const er = new Error ( 'Invalid file: URL, must comply with RFC 8909' )
252
252
throw Object . assign ( er , {
@@ -260,17 +260,17 @@ function fromFile (res, where) {
260
260
// XXX backwards compatibility lack of compliance with RFC 8909
261
261
if ( resolvedUrl . host && resolvedUrl . host !== 'localhost' ) {
262
262
const rawSpec = res . rawSpec . replace ( / ^ f i l e : \/ \/ / , 'file:///' )
263
- resolvedUrl = new url . URL ( rawSpec , `file://${ path . resolve ( where ) } /` )
264
- specUrl = new url . URL ( rawSpec )
263
+ resolvedUrl = new URL ( rawSpec , `file://${ path . resolve ( where ) } /` )
264
+ specUrl = new URL ( rawSpec )
265
265
rawNoPrefix = rawSpec . replace ( / ^ f i l e : / , '' )
266
266
}
267
267
// turn file:/../foo into file:../foo
268
268
// for 1, 2 or 3 leading slashes since we attempted
269
269
// in the previous step to make it a file protocol url with a leading slash
270
270
if ( / ^ \/ { 1 , 3 } \. \. ? ( \/ | $ ) / . test ( rawNoPrefix ) ) {
271
271
const rawSpec = res . rawSpec . replace ( / ^ f i l e : \/ { 1 , 3 } / , 'file:' )
272
- resolvedUrl = new url . URL ( rawSpec , `file://${ path . resolve ( where ) } /` )
273
- specUrl = new url . URL ( rawSpec )
272
+ resolvedUrl = new URL ( rawSpec , `file://${ path . resolve ( where ) } /` )
273
+ specUrl = new URL ( rawSpec )
274
274
rawNoPrefix = rawSpec . replace ( / ^ f i l e : / , '' )
275
275
}
276
276
// XXX end RFC 8909 violation backwards compatibility section
@@ -312,28 +312,29 @@ function unsupportedURLType (protocol, spec) {
312
312
return err
313
313
}
314
314
315
- function matchGitScp ( spec ) {
316
- // git ssh specifiers are overloaded to also use scp-style git
317
- // specifiers, so we have to parse those out and treat them special.
318
- // They are NOT true URIs, so we can't hand them to `url.parse`.
319
- //
320
- // This regex looks for things that look like:
321
- // git+ssh://[email protected] :username/project.git#deadbeef
322
- //
323
- // ...and various combinations. The username in the beginning is *required*.
324
- const matched = spec . match ( / ^ g i t \+ s s h : \/ \/ ( [ ^ : # ] + : [ ^ # ] + (?: \. g i t ) ? ) (?: # ( .* ) ) ? $ / i)
325
- return matched && ! matched [ 1 ] . match ( / : [ 0 - 9 ] + \/ ? .* $ / i) && {
326
- fetchSpec : matched [ 1 ] ,
327
- gitCommittish : matched [ 2 ] == null ? null : matched [ 2 ] ,
328
- }
329
- }
330
-
331
315
function fromURL ( res ) {
316
+ let rawSpec = res . rawSpec
317
+ res . saveSpec = rawSpec
318
+ if ( rawSpec . startsWith ( 'git+ssh:' ) ) {
319
+ // git ssh specifiers are overloaded to also use scp-style git
320
+ // specifiers, so we have to parse those out and treat them special.
321
+ // They are NOT true URIs, so we can't hand them to URL.
322
+ const matched = rawSpec . match ( / ^ g i t \+ s s h : \/ \/ ( [ ^ : # ] + : [ ^ # ] + (?: \. g i t ) ? ) (?: # ( .* ) ) ? $ / i)
323
+ if ( matched && ! matched [ 1 ] . match ( / : [ 0 - 9 ] + \/ ? .* $ / i) ) {
324
+ res . type = 'git'
325
+ setGitCommittish ( res , matched [ 2 ] )
326
+ res . fetchSpec = matched [ 1 ]
327
+ return res
328
+ }
329
+ } else if ( rawSpec . startsWith ( 'git+file://' ) ) {
330
+ // URL can't handle windows paths
331
+ const noProtocol = rawSpec . slice ( 11 ) . replace ( / \\ / g, '/' )
332
+ rawSpec = `git+file://${ noProtocol } `
333
+ }
332
334
// eslint-disable-next-line node/no-deprecated-api
333
- const urlparse = url . parse ( res . rawSpec )
334
- res . saveSpec = res . rawSpec
335
+ const parsedUrl = new URL ( rawSpec )
335
336
// check the protocol, and then see if it's git or not
336
- switch ( urlparse . protocol ) {
337
+ switch ( parsedUrl . protocol ) {
337
338
case 'git:' :
338
339
case 'git+http:' :
339
340
case 'git+https:' :
@@ -342,21 +343,16 @@ function fromURL (res) {
342
343
case 'git+file:' :
343
344
case 'git+ssh:' : {
344
345
res . type = 'git'
345
- const match = urlparse . protocol === 'git+ssh:' ? matchGitScp ( res . rawSpec )
346
- : null
347
- if ( match ) {
348
- setGitCommittish ( res , match . gitCommittish )
349
- res . fetchSpec = match . fetchSpec
346
+ setGitCommittish ( res , parsedUrl . hash . slice ( 1 ) )
347
+ if ( parsedUrl . protocol === 'git+file:' && / ^ g i t \+ f i l e : \/ \/ [ a - z ] : / i. test ( rawSpec ) ) {
348
+ // URL can't handle drive letters on windows file paths, the host can't contain a :
349
+ res . fetchSpec = `git+file://${ parsedUrl . host . toLowerCase ( ) } :${ parsedUrl . pathname } `
350
350
} else {
351
- setGitCommittish ( res , urlparse . hash != null ? urlparse . hash . slice ( 1 ) : '' )
352
- urlparse . protocol = urlparse . protocol . replace ( / ^ g i t [ + ] / , '' )
353
- if ( urlparse . protocol === 'file:' && / ^ g i t \+ f i l e : \/ \/ [ a - z ] : / i. test ( res . rawSpec ) ) {
354
- // keep the drive letter : on windows file paths
355
- urlparse . host += ':'
356
- urlparse . hostname += ':'
357
- }
358
- delete urlparse . hash
359
- res . fetchSpec = url . format ( urlparse )
351
+ parsedUrl . hash = ''
352
+ res . fetchSpec = parsedUrl . toString ( )
353
+ }
354
+ if ( res . fetchSpec . startsWith ( 'git+' ) ) {
355
+ res . fetchSpec = res . fetchSpec . slice ( 4 )
360
356
}
361
357
break
362
358
}
@@ -367,7 +363,7 @@ function fromURL (res) {
367
363
break
368
364
369
365
default :
370
- throw unsupportedURLType ( urlparse . protocol , res . rawSpec )
366
+ throw unsupportedURLType ( parsedUrl . protocol , rawSpec )
371
367
}
372
368
373
369
return res
0 commit comments