-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
39d7f04
commit ce9089f
Showing
11 changed files
with
71 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ module.exports.resolve = resolve | |
module.exports.toPurl = toPurl | ||
module.exports.Result = Result | ||
|
||
const url = require('url') | ||
const { URL } = require('url') | ||
const HostedGit = require('hosted-git-info') | ||
const semver = require('semver') | ||
const path = global.FAKE_WINDOWS ? require('path').win32 : require('path') | ||
|
@@ -183,10 +183,11 @@ Result.prototype.toJSON = function () { | |
return result | ||
} | ||
|
||
function setGitCommittish (res, committish) { | ||
// sets res.gitCommittish, res.gitRange, and res.gitSubdir | ||
function setGitAttrs (res, committish) { | ||
if (!committish) { | ||
res.gitCommittish = null | ||
return res | ||
return | ||
} | ||
|
||
// for each :: separated item: | ||
|
@@ -224,8 +225,6 @@ function setGitCommittish (res, committish) { | |
} | ||
log.warn('npm-package-arg', `ignoring unknown key "${name}"`) | ||
} | ||
|
||
return res | ||
} | ||
|
||
function fromFile (res, where) { | ||
|
@@ -245,10 +244,10 @@ function fromFile (res, where) { | |
const rawWithPrefix = prefix + res.rawSpec | ||
let rawNoPrefix = rawWithPrefix.replace(/^file:/, '') | ||
try { | ||
resolvedUrl = new url.URL(rawWithPrefix, `file://${path.resolve(where)}/`) | ||
specUrl = new url.URL(rawWithPrefix) | ||
resolvedUrl = new URL(rawWithPrefix, `file://${path.resolve(where)}/`) | ||
specUrl = new URL(rawWithPrefix) | ||
} catch (originalError) { | ||
const er = new Error('Invalid file: URL, must comply with RFC 8909') | ||
const er = new Error('Invalid file: URL, must comply with RFC 8089') | ||
throw Object.assign(er, { | ||
raw: res.rawSpec, | ||
spec: res, | ||
|
@@ -257,23 +256,23 @@ function fromFile (res, where) { | |
}) | ||
} | ||
|
||
// XXX backwards compatibility lack of compliance with RFC 8909 | ||
// XXX backwards compatibility lack of compliance with RFC 8089 | ||
if (resolvedUrl.host && resolvedUrl.host !== 'localhost') { | ||
const rawSpec = res.rawSpec.replace(/^file:\/\//, 'file:///') | ||
resolvedUrl = new url.URL(rawSpec, `file://${path.resolve(where)}/`) | ||
specUrl = new url.URL(rawSpec) | ||
resolvedUrl = new URL(rawSpec, `file://${path.resolve(where)}/`) | ||
specUrl = new URL(rawSpec) | ||
rawNoPrefix = rawSpec.replace(/^file:/, '') | ||
} | ||
// turn file:/../foo into file:../foo | ||
// for 1, 2 or 3 leading slashes since we attempted | ||
// in the previous step to make it a file protocol url with a leading slash | ||
if (/^\/{1,3}\.\.?(\/|$)/.test(rawNoPrefix)) { | ||
const rawSpec = res.rawSpec.replace(/^file:\/{1,3}/, 'file:') | ||
resolvedUrl = new url.URL(rawSpec, `file://${path.resolve(where)}/`) | ||
specUrl = new url.URL(rawSpec) | ||
resolvedUrl = new URL(rawSpec, `file://${path.resolve(where)}/`) | ||
specUrl = new URL(rawSpec) | ||
rawNoPrefix = rawSpec.replace(/^file:/, '') | ||
} | ||
// XXX end RFC 8909 violation backwards compatibility section | ||
// XXX end RFC 8089 violation backwards compatibility section | ||
|
||
// turn /C:/blah into just C:/blah on windows | ||
let specPath = decodeURIComponent(specUrl.pathname) | ||
|
@@ -303,7 +302,8 @@ function fromHostedGit (res, hosted) { | |
res.hosted = hosted | ||
res.saveSpec = hosted.toString({ noGitPlus: false, noCommittish: false }) | ||
res.fetchSpec = hosted.getDefaultRepresentation() === 'shortcut' ? null : hosted.toString() | ||
return setGitCommittish(res, hosted.committish) | ||
setGitAttrs(res, hosted.committish) | ||
return res | ||
} | ||
|
||
function unsupportedURLType (protocol, spec) { | ||
|
@@ -312,62 +312,59 @@ function unsupportedURLType (protocol, spec) { | |
return err | ||
} | ||
|
||
function matchGitScp (spec) { | ||
// git ssh specifiers are overloaded to also use scp-style git | ||
// specifiers, so we have to parse those out and treat them special. | ||
// They are NOT true URIs, so we can't hand them to `url.parse`. | ||
// | ||
// This regex looks for things that look like: | ||
// git+ssh://[email protected]:username/project.git#deadbeef | ||
// | ||
// ...and various combinations. The username in the beginning is *required*. | ||
const matched = spec.match(/^git\+ssh:\/\/([^:#]+:[^#]+(?:\.git)?)(?:#(.*))?$/i) | ||
return matched && !matched[1].match(/:[0-9]+\/?.*$/i) && { | ||
fetchSpec: matched[1], | ||
gitCommittish: matched[2] == null ? null : matched[2], | ||
} | ||
} | ||
|
||
function fromURL (res) { | ||
// eslint-disable-next-line node/no-deprecated-api | ||
const urlparse = url.parse(res.rawSpec) | ||
res.saveSpec = res.rawSpec | ||
let rawSpec = res.rawSpec | ||
res.saveSpec = rawSpec | ||
if (rawSpec.startsWith('git+ssh:')) { | ||
// git ssh specifiers are overloaded to also use scp-style git | ||
// specifiers, so we have to parse those out and treat them special. | ||
// They are NOT true URIs, so we can't hand them to URL. | ||
|
||
// This regex looks for things that look like: | ||
// git+ssh://[email protected]: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)) { | ||
res.type = 'git' | ||
setGitAttrs(res, matched[2]) | ||
res.fetchSpec = matched[1] | ||
return res | ||
} | ||
} else if (rawSpec.startsWith('git+file://')) { | ||
// URL can't handle windows paths | ||
rawSpec = rawSpec.replace(/\\/g, '/') | ||
} | ||
const parsedUrl = new URL(rawSpec) | ||
// check the protocol, and then see if it's git or not | ||
switch (urlparse.protocol) { | ||
switch (parsedUrl.protocol) { | ||
case 'git:': | ||
case 'git+http:': | ||
case 'git+https:': | ||
case 'git+rsync:': | ||
case 'git+ftp:': | ||
case 'git+file:': | ||
case 'git+ssh:': { | ||
case 'git+ssh:': | ||
res.type = 'git' | ||
const match = urlparse.protocol === 'git+ssh:' ? matchGitScp(res.rawSpec) | ||
: null | ||
if (match) { | ||
setGitCommittish(res, match.gitCommittish) | ||
res.fetchSpec = match.fetchSpec | ||
setGitAttrs(res, parsedUrl.hash.slice(1)) | ||
if (parsedUrl.protocol === 'git+file:' && /^git\+file:\/\/[a-z]:/i.test(rawSpec)) { | ||
// URL can't handle drive letters on windows file paths, the host can't contain a : | ||
res.fetchSpec = `git+file://${parsedUrl.host.toLowerCase()}:${parsedUrl.pathname}` | ||
} else { | ||
setGitCommittish(res, urlparse.hash != null ? urlparse.hash.slice(1) : '') | ||
urlparse.protocol = urlparse.protocol.replace(/^git[+]/, '') | ||
if (urlparse.protocol === 'file:' && /^git\+file:\/\/[a-z]:/i.test(res.rawSpec)) { | ||
// keep the drive letter : on windows file paths | ||
urlparse.host += ':' | ||
urlparse.hostname += ':' | ||
} | ||
delete urlparse.hash | ||
res.fetchSpec = url.format(urlparse) | ||
parsedUrl.hash = '' | ||
res.fetchSpec = parsedUrl.toString() | ||
} | ||
if (res.fetchSpec.startsWith('git+')) { | ||
res.fetchSpec = res.fetchSpec.slice(4) | ||
} | ||
break | ||
} | ||
case 'http:': | ||
case 'https:': | ||
res.type = 'remote' | ||
res.fetchSpec = res.saveSpec | ||
break | ||
|
||
default: | ||
throw unsupportedURLType(urlparse.protocol, res.rawSpec) | ||
throw unsupportedURLType(parsedUrl.protocol, rawSpec) | ||
} | ||
|
||
return res | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters