diff options
Diffstat (limited to 'deps/npm/lib/utils')
-rw-r--r-- | deps/npm/lib/utils/convert-line-endings.js | 49 | ||||
-rw-r--r-- | deps/npm/lib/utils/error-message.js | 86 | ||||
-rw-r--r-- | deps/npm/lib/utils/gently-rm.js | 271 | ||||
-rw-r--r-- | deps/npm/lib/utils/is-hashbang-file.js | 19 | ||||
-rw-r--r-- | deps/npm/lib/utils/is-registry.js | 11 | ||||
-rw-r--r-- | deps/npm/lib/utils/link.js | 71 |
6 files changed, 62 insertions, 445 deletions
diff --git a/deps/npm/lib/utils/convert-line-endings.js b/deps/npm/lib/utils/convert-line-endings.js deleted file mode 100644 index b05d328aac..0000000000 --- a/deps/npm/lib/utils/convert-line-endings.js +++ /dev/null @@ -1,49 +0,0 @@ -'use strict' - -const Transform = require('stream').Transform -const Bluebird = require('bluebird') -const fs = require('graceful-fs') -const stat = Bluebird.promisify(fs.stat) -const chmod = Bluebird.promisify(fs.chmod) -const fsWriteStreamAtomic = require('fs-write-stream-atomic') - -module.exports.dos2Unix = dos2Unix - -function dos2Unix (file) { - return stat(file).then((stats) => { - let previousChunkEndedInCR = false - return new Bluebird((resolve, reject) => { - fs.createReadStream(file) - .on('error', reject) - .pipe(new Transform({ - transform: function (chunk, encoding, done) { - let data = chunk.toString() - if (previousChunkEndedInCR) { - data = '\r' + data - } - if (data[data.length - 1] === '\r') { - data = data.slice(0, -1) - previousChunkEndedInCR = true - } else { - previousChunkEndedInCR = false - } - done(null, data.replace(/\r\n/g, '\n')) - }, - flush: function (done) { - if (previousChunkEndedInCR) { - this.push('\r') - } - done() - } - })) - .on('error', reject) - .pipe(fsWriteStreamAtomic(file)) - .on('error', reject) - .on('finish', function () { - resolve(chmod(file, stats.mode)) - }) - }) - }) -} - -// could add unix2Dos and legacy Mac functions if need be diff --git a/deps/npm/lib/utils/error-message.js b/deps/npm/lib/utils/error-message.js index 028a18bbb6..85504f5edc 100644 --- a/deps/npm/lib/utils/error-message.js +++ b/deps/npm/lib/utils/error-message.js @@ -67,49 +67,53 @@ function errorMessage (er) { break case 'EOTP': - short.push(['', 'This operation requires a one-time password from your authenticator.']) - detail.push([ - '', - [ - 'You can provide a one-time password by passing --otp=<code> to the command you ran.', - 'If you already provided a one-time password then it is likely that you either typoed', - 'it, or it timed out. Please try again.' - ].join('\n') - ]) - break - case 'E401': - // npm ERR! code E401 - // npm ERR! Unable to authenticate, need: Basic - if (er.headers && er.headers['www-authenticate']) { - const auth = er.headers['www-authenticate'] - if (auth.indexOf('Bearer') !== -1) { - short.push(['', 'Unable to authenticate, your authentication token seems to be invalid.']) - detail.push([ - '', - [ - 'To correct this please trying logging in again with:', - ' npm login' - ].join('\n') - ]) - break - } else if (auth.indexOf('Basic') !== -1) { - short.push(['', 'Incorrect or missing password.']) - detail.push([ - '', - [ - 'If you were trying to login, change your password, create an', - 'authentication token or enable two-factor authentication then', - 'that means you likely typed your password in incorectly.', - 'Please try again, or recover your password at:', - ' https://www.npmjs.com/forgot', + // the E401 message checking is a hack till we replace npm-registry-client with something + // OTP aware. + if (er.code === 'EOTP' || (er.code === 'E401' && /one-time pass/.test(er.message))) { + short.push(['', 'This operation requires a one-time password from your authenticator.']) + detail.push([ + '', + [ + 'You can provide a one-time password by passing --otp=<code> to the command you ran.', + 'If you already provided a one-time password then it is likely that you either typoed', + 'it, or it timed out. Please try again.' + ].join('\n') + ]) + break + } else { + // npm ERR! code E401 + // npm ERR! Unable to authenticate, need: Basic + if (er.headers && er.headers['www-authenticate']) { + const auth = er.headers['www-authenticate'].map((au) => au.split(/,\s*/))[0] || [] + if (auth.indexOf('Bearer') !== -1) { + short.push(['', 'Unable to authenticate, your authentication token seems to be invalid.']) + detail.push([ + '', + [ + 'To correct this please trying logging in again with:', + ' npm login' + ].join('\n') + ]) + break + } else if (auth.indexOf('Basic') !== -1) { + short.push(['', 'Incorrect or missing password.']) + detail.push([ '', - 'If you were doing some other operation then your saved credentials are', - 'probably out of date. To correct this please try logging in again with:', - ' npm login' - ].join('\n') - ]) - break + [ + 'If you were trying to login, change your password, create an', + 'authentication token or enable two-factor authentication then', + 'that means you likely typed your password in incorrectly.', + 'Please try again, or recover your password at:', + ' https://www.npmjs.com/forgot', + '', + 'If you were doing some other operation then your saved credentials are', + 'probably out of date. To correct this please try logging in again with:', + ' npm login' + ].join('\n') + ]) + break + } } } diff --git a/deps/npm/lib/utils/gently-rm.js b/deps/npm/lib/utils/gently-rm.js index 7253e873c6..16d0aa9bd7 100644 --- a/deps/npm/lib/utils/gently-rm.js +++ b/deps/npm/lib/utils/gently-rm.js @@ -3,20 +3,8 @@ exports = module.exports = gentlyRm -var resolve = require('path').resolve -var dirname = require('path').dirname -var normalize = require('path').normalize -var validate = require('aproba') -var log = require('npmlog') -var lstat = require('graceful-fs').lstat -var readlink = require('graceful-fs').readlink -var isInside = require('path-is-inside') -var vacuum = require('fs-vacuum') -var chain = require('slide').chain -var asyncMap = require('slide').asyncMap -var readCmdShim = require('read-cmd-shim') -var iferr = require('iferr') -var npm = require('../npm.js') +var gentleFS = require('gentle-fs') +var gentleFSOpts = require('../config/gentle-fs.js') function gentlyRm (target, gently, base, cb) { if (!cb) { @@ -29,258 +17,5 @@ function gentlyRm (target, gently, base, cb) { gently = false } - // never rm the root, prefix, or bin dirs - // - // globals included because of `npm link` -- as far as the package - // requesting the link is concerned, the linked package is always - // installed globally - var prefixes = [ - npm.prefix, - npm.globalPrefix, - npm.dir, - npm.root, - npm.globalDir, - npm.bin, - npm.globalBin - ] - - var targetPath = normalize(resolve(npm.prefix, target)) - if (prefixes.indexOf(targetPath) !== -1) { - return cb(new Error('May not delete: ' + targetPath)) - } - var options = { } - if (npm.config.get('force') || !gently) options.purge = true - if (base) options.base = normalize(resolve(npm.prefix, base)) - - if (!gently) { - return vacuum(targetPath, options, cb) - } - - var parent = options.base = options.base || normalize(npm.prefix) - - // Do all the async work we'll need to do in order to tell if this is a - // safe operation - chain([ - [isEverInside, parent, prefixes], - [readLinkOrShim, targetPath], - [isEverInside, targetPath, prefixes], - [isEverInside, targetPath, [parent]] - ], function (er, results) { - if (er) { - if (er.code === 'ENOENT') return cb() - return cb(er) - } - var parentInfo = { - path: parent, - managed: results[0] - } - var targetInfo = { - path: targetPath, - symlink: results[1], - managed: results[2], - inParent: results[3] - } - - isSafeToRm(parentInfo, targetInfo, iferr(cb, thenRemove)) - - function thenRemove (toRemove, removeBase) { - if (!toRemove) return cb() - if (removeBase) options.base = removeBase - return vacuum(toRemove, options, cb) - } - }) -} - -exports._isSafeToRm = isSafeToRm -function isSafeToRm (parent, target, cb) { - log.silly('gentlyRm', 'parent.path =', parent.path) - log.silly('gentlyRm', 'parent.managed =', - parent.managed && parent.managed.target + ' is in ' + parent.managed.path) - log.silly('gentlyRm', 'target.path = ', target.path) - log.silly('gentlyRm', 'target.symlink =', target.symlink) - log.silly('gentlyRm', 'target.managed =', - target.managed && target.managed.target + ' is in ' + target.managed.path) - log.silly('gentlyRm', 'target.inParent = ', target.inParent) - - // The parent directory or something it symlinks to must eventually be in - // a folder that npm maintains. - if (!parent.managed) { - log.info('gentlyRm', parent.path, - 'is not contained in any diretory npm is known to control or ' + - 'any place they link to') - return cb(clobberFail(target.path, 'containing path ' + parent.path + - " isn't under npm's control")) - } - - // The target or something it symlinks to must eventually be in the parent - // or something the parent symlinks to - if (target.inParent) { - var actualTarget = target.inParent.target - var targetsParent = target.inParent.path - // if the target.path was what we found in some version of parent, remove - // using that parent as the base - if (target.path === actualTarget) { - return cb(null, target.path, targetsParent) - } else { - // If something the target.path links to was what was found, just - // remove target.path in the location it was found. - return cb(null, target.path, dirname(target.path)) - } - } - - // If the target is in a managed directory and is in a symlink, but was - // not in our parent that usually means someone else installed a bin file - // with the same name as one of our bin files. - if (target.managed && target.symlink) { - log.warn('gentlyRm', 'not removing', target.path, - "as it wasn't installed by", parent.path) - return cb() - } - - if (target.symlink) { - return cb(clobberFail(target.path, target.symlink + - ' symlink target is not controlled by npm ' + parent.path)) - } else { - return cb(clobberFail(target.path, 'is outside ' + parent.path + - ' and not a link')) - } -} - -function clobberFail (target, msg) { - validate('SS', arguments) - var er = new Error('Refusing to delete ' + target + ': ' + msg) - er.code = 'EEXIST' - er.path = target - return er -} - -function isENOENT (err) { - return err && err.code === 'ENOENT' -} - -function notENOENT (err) { - return !isENOENT(err) -} - -function skipENOENT (cb) { - return function (err, value) { - if (isENOENT(err)) { - return cb(null, false) - } else { - return cb(err, value) - } - } -} - -function errorsToValues (fn) { - return function () { - var args = Array.prototype.slice.call(arguments) - var cb = args.pop() - args.push(function (err, value) { - if (err) { - return cb(null, err) - } else { - return cb(null, value) - } - }) - fn.apply(null, args) - } -} - -function isNotError (value) { - return !(value instanceof Error) -} - -exports._isEverInside = isEverInside -// return the first of path, where target (or anything it symlinks to) -// isInside the path (or anything it symlinks to) -function isEverInside (target, paths, cb) { - validate('SAF', arguments) - asyncMap(paths, errorsToValues(readAllLinks), iferr(cb, function (resolvedPaths) { - var errorFree = resolvedPaths.filter(isNotError) - if (errorFree.length === 0) { - var badErrors = resolvedPaths.filter(notENOENT) - if (badErrors.length === 0) { - return cb(null, false) - } else { - return cb(badErrors[0]) - } - } - readAllLinks(target, iferr(skipENOENT(cb), function (targets) { - cb(null, areAnyInsideAny(targets, errorFree)) - })) - })) -} - -exports._areAnyInsideAny = areAnyInsideAny -// Return the first path found that any target is inside -function areAnyInsideAny (targets, paths) { - validate('AA', arguments) - var toCheck = [] - paths.forEach(function (path) { - targets.forEach(function (target) { - toCheck.push([target, path]) - }) - }) - for (var ii = 0; ii < toCheck.length; ++ii) { - var target = toCheck[ii][0] - var path = toCheck[ii][1] - var inside = isInside(target, path) - if (!inside) log.silly('isEverInside', target, 'is not inside', path) - if (inside && path) return inside && path && {target: target, path: path} - } - return false -} - -exports._readAllLinks = readAllLinks -// resolves chains of symlinks of unlimited depth, returning a list of paths -// it's seen in the process when it hits either a symlink cycle or a -// non-symlink -function readAllLinks (path, cb) { - validate('SF', arguments) - var seen = {} - _readAllLinks(path) - - function _readAllLinks (path) { - if (seen[path]) return cb(null, Object.keys(seen)) - seen[path] = true - resolveSymlink(path, iferr(cb, _readAllLinks)) - } -} - -exports._resolveSymlink = resolveSymlink -var resolvedPaths = {} -function resolveSymlink (symlink, cb) { - validate('SF', arguments) - var cached = resolvedPaths[symlink] - if (cached) return cb(null, cached) - - readLinkOrShim(symlink, iferr(cb, function (symlinkTarget) { - if (symlinkTarget) { - resolvedPaths[symlink] = resolve(dirname(symlink), symlinkTarget) - } else { - resolvedPaths[symlink] = symlink - } - return cb(null, resolvedPaths[symlink]) - })) -} - -exports._readLinkOrShim = readLinkOrShim -function readLinkOrShim (path, cb) { - validate('SF', arguments) - lstat(path, iferr(cb, function (stat) { - if (stat.isSymbolicLink()) { - readlink(path, cb) - } else { - readCmdShim(path, function (er, source) { - if (!er) return cb(null, source) - // lstat wouldn't return an error on these, so we don't either. - if (er.code === 'ENOTASHIM' || er.code === 'EISDIR') { - return cb(null, null) - } else { - return cb(er) - } - }) - } - })) + return gentleFS.rm(target, gentleFSOpts(gently, base), cb) } diff --git a/deps/npm/lib/utils/is-hashbang-file.js b/deps/npm/lib/utils/is-hashbang-file.js deleted file mode 100644 index f1677381fa..0000000000 --- a/deps/npm/lib/utils/is-hashbang-file.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' -const Bluebird = require('bluebird') -const fs = require('graceful-fs') -const open = Bluebird.promisify(fs.open) -const close = Bluebird.promisify(fs.close) - -module.exports = isHashbangFile - -function isHashbangFile (file) { - return open(file, 'r').then((fileHandle) => { - return new Bluebird((resolve, reject) => { - fs.read(fileHandle, new Buffer(new Array(2)), 0, 2, 0, function (err, bytesRead, buffer) { - close(fileHandle).then(() => { - resolve(!err && buffer.toString() === '#!') - }).catch(reject) - }) - }) - }) -} diff --git a/deps/npm/lib/utils/is-registry.js b/deps/npm/lib/utils/is-registry.js new file mode 100644 index 0000000000..e5f08e16a0 --- /dev/null +++ b/deps/npm/lib/utils/is-registry.js @@ -0,0 +1,11 @@ +'use strict' +module.exports = isRegistry + +function isRegistry (req) { + if (req == null) return false + // modern metadata + if ('registry' in req) return req.registry + // legacy metadata + if (req.type === 'range' || req.type === 'version' || req.type === 'tag') return true + return false +} diff --git a/deps/npm/lib/utils/link.js b/deps/npm/lib/utils/link.js index 15331740a4..c264248144 100644 --- a/deps/npm/lib/utils/link.js +++ b/deps/npm/lib/utils/link.js @@ -1,73 +1,8 @@ module.exports = link -link.ifExists = linkIfExists -var fs = require('graceful-fs') -var chain = require('slide').chain -var mkdir = require('mkdirp') -var rm = require('./gently-rm.js') -var path = require('path') -var npm = require('../npm.js') - -function linkIfExists (from, to, gently, cb) { - fs.stat(from, function (er) { - if (er) return cb() - fs.readlink(to, function (er, fromOnDisk) { - // if the link already exists and matches what we would do, - // we don't need to do anything - if (!er) { - var toDir = path.dirname(to) - var absoluteFrom = path.resolve(toDir, from) - var absoluteFromOnDisk = path.resolve(toDir, fromOnDisk) - if (absoluteFrom === absoluteFromOnDisk) return cb() - } - link(from, to, gently, cb) - }) - }) -} - -function resolveIfSymlink (maybeSymlinkPath, cb) { - fs.lstat(maybeSymlinkPath, function (err, stat) { - if (err) return cb.apply(this, arguments) - if (!stat.isSymbolicLink()) return cb(null, maybeSymlinkPath) - fs.readlink(maybeSymlinkPath, cb) - }) -} - -function ensureFromIsNotSource (from, to, cb) { - resolveIfSymlink(from, function (err, fromDestination) { - if (err) return cb.apply(this, arguments) - if (path.resolve(path.dirname(from), fromDestination) === path.resolve(to)) { - return cb(new Error('Link target resolves to the same directory as link source: ' + to)) - } - cb.apply(this, arguments) - }) -} +var gentleFS = require('gentle-fs') +var gentleFSOpts = require('../config/gentle-fs.js') function link (from, to, gently, abs, cb) { - if (typeof cb !== 'function') { - cb = abs - abs = false - } - if (typeof cb !== 'function') { - cb = gently - gently = null - } - if (npm.config.get('force')) gently = false - - to = path.resolve(to) - var toDir = path.dirname(to) - var absTarget = path.resolve(toDir, from) - var relativeTarget = path.relative(toDir, absTarget) - var target = abs ? absTarget : relativeTarget - - chain( - [ - [ensureFromIsNotSource, absTarget, to], - [fs, 'stat', absTarget], - [rm, to, gently, path.dirname(to)], - [mkdir, path.dirname(to)], - [fs, 'symlink', target, to, 'junction'] - ], - cb - ) + return gentleFS.link(from, to, gentleFSOpts(gently, undefined, abs), cb) } |