diff options
Diffstat (limited to 'deps/npm/node_modules/bin-links/index.js')
-rw-r--r-- | deps/npm/node_modules/bin-links/index.js | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/deps/npm/node_modules/bin-links/index.js b/deps/npm/node_modules/bin-links/index.js index 5f86755475..4f6d3c055c 100644 --- a/deps/npm/node_modules/bin-links/index.js +++ b/deps/npm/node_modules/bin-links/index.js @@ -3,18 +3,22 @@ const path = require('path') const fs = require('graceful-fs') const BB = require('bluebird') -const linkIfExists = BB.promisify(require('gentle-fs').linkIfExists) -const cmdShimIfExists = BB.promisify(require('cmd-shim').ifExists) +const gentleFs = require('gentle-fs') +const linkIfExists = BB.promisify(gentleFs.linkIfExists) +const gentleFsBinLink = BB.promisify(gentleFs.binLink) const open = BB.promisify(fs.open) const close = BB.promisify(fs.close) const read = BB.promisify(fs.read, {multiArgs: true}) const chmod = BB.promisify(fs.chmod) const readFile = BB.promisify(fs.readFile) const writeFileAtomic = BB.promisify(require('write-file-atomic')) +const normalize = require('npm-normalize-package-bin') module.exports = BB.promisify(binLinks) function binLinks (pkg, folder, global, opts, cb) { + pkg = normalize(pkg) + // if it's global, and folder is in {prefix}/node_modules, // then bins are in {prefix}/bin // otherwise, then bins are in folder/../.bin @@ -39,9 +43,9 @@ function isHashbangFile (file) { return read(fileHandle, Buffer.alloc(2), 0, 2, 0).spread((_, buf) => { if (!hasHashbang(buf)) return [] return read(fileHandle, Buffer.alloc(2048), 0, 2048, 0) - }).spread((_, buf) => buf && hasCR(buf), () => false) + }).spread((_, buf) => buf && hasCR(buf), /* istanbul ignore next */ () => false) .finally(() => close(fileHandle)) - }).catch(() => false) + }).catch(/* istanbul ignore next */ () => false) } function hasHashbang (buf) { @@ -77,6 +81,12 @@ function linkBins (pkg, folder, parent, gtop, opts) { var dest = path.resolve(binRoot, bin) var src = path.resolve(folder, pkg.bin[bin]) + /* istanbul ignore if - that unpossible */ + if (src.indexOf(folder) !== 0) { + throw new Error('invalid bin entry for package ' + + pkg._id + '. key=' + bin + ', value=' + pkg.bin[bin]) + } + return linkBin(src, dest, linkOpts).then(() => { // bins should always be executable. // XXX skip chmod on windows? @@ -100,6 +110,7 @@ function linkBins (pkg, folder, parent, gtop, opts) { opts.log.showProgress() } }).catch(err => { + /* istanbul ignore next */ if (err.code === 'ENOENT' && opts.ignoreScripts) return throw err }) @@ -107,11 +118,11 @@ function linkBins (pkg, folder, parent, gtop, opts) { } function linkBin (from, to, opts) { - if (process.platform !== 'win32') { - return linkIfExists(from, to, opts) - } else { - return cmdShimIfExists(from, to) + // do not clobber global bins + if (opts.globalBin && to.indexOf(opts.globalBin) === 0) { + opts.clobberLinkGently = true } + return gentleFsBinLink(from, to, opts) } function linkMans (pkg, folder, parent, gtop, opts) { @@ -123,15 +134,22 @@ function linkMans (pkg, folder, parent, gtop, opts) { // make sure that the mans are unique. // otherwise, if there are dupes, it'll fail with EEXIST var set = pkg.man.reduce(function (acc, man) { - acc[path.basename(man)] = man + if (typeof man !== 'string') { + return acc + } + const cleanMan = path.join('/', man).replace(/\\|:/g, '/').substr(1) + acc[path.basename(man)] = cleanMan return acc }, {}) var manpages = pkg.man.filter(function (man) { - return set[path.basename(man)] === man + if (typeof man !== 'string') { + return false + } + const cleanMan = path.join('/', man).replace(/\\|:/g, '/').substr(1) + return set[path.basename(man)] === cleanMan }) return BB.map(manpages, man => { - if (typeof man !== 'string') return opts.log.silly('linkMans', 'preparing to link', man) var parseMan = man.match(/(.*\.([0-9]+)(\.gz)?)$/) if (!parseMan) { @@ -146,8 +164,19 @@ function linkMans (pkg, folder, parent, gtop, opts) { var sxn = parseMan[2] var bn = path.basename(stem) var manSrc = path.resolve(folder, man) + /* istanbul ignore if - that unpossible */ + if (manSrc.indexOf(folder) !== 0) { + throw new Error('invalid man entry for package ' + + pkg._id + '. man=' + manSrc) + } + var manDest = path.join(manRoot, 'man' + sxn, bn) + // man pages should always be clobbering gently, because they are + // only installed for top-level global packages, so never destroy + // a link if it doesn't point into the folder we're linking + opts.clobberLinkGently = true + return linkIfExists(manSrc, manDest, getLinkOpts(opts, gtop && folder)) }) } |