diff options
author | Kat Marchán <kzm@sykosomatic.org> | 2016-05-27 14:07:59 -0700 |
---|---|---|
committer | Jeremiah Senkpiel <fishrock123@rocketmail.com> | 2016-05-28 10:42:48 -0400 |
commit | bd8b1ddb2007dcc8ec2a0a08e16208aa21b83400 (patch) | |
tree | aab54a7bbc42e1477a8a2b175dfc9f9eb36ca9e2 /deps/npm/lib | |
parent | 16f98e589c69ffe6283aa11493fd417368708557 (diff) | |
download | android-node-v8-bd8b1ddb2007dcc8ec2a0a08e16208aa21b83400.tar.gz android-node-v8-bd8b1ddb2007dcc8ec2a0a08e16208aa21b83400.tar.bz2 android-node-v8-bd8b1ddb2007dcc8ec2a0a08e16208aa21b83400.zip |
deps: upgrade npm to 3.9.3
Contains the following npm releases:
- v3.9.0: https://github.com/npm/npm/releases/tag/v3.9.0
- v3.9.1: https://github.com/npm/npm/releases/tag/v3.9.1
- v3.9.2: https://github.com/npm/npm/releases/tag/v3.9.2
- v3.9.3: https://github.com/npm/npm/releases/tag/v3.9.3
PR-URL: https://github.com/nodejs/node/pull/7030
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Diffstat (limited to 'deps/npm/lib')
24 files changed, 285 insertions, 127 deletions
diff --git a/deps/npm/lib/access.js b/deps/npm/lib/access.js index 158ce50544..69527c2aa4 100644 --- a/deps/npm/lib/access.js +++ b/deps/npm/lib/access.js @@ -35,7 +35,6 @@ access.completion = function (opts, cb) { } else { return cb(null, []) } - break case 'public': case 'restricted': case 'ls-packages': diff --git a/deps/npm/lib/cache/add-remote-git.js b/deps/npm/lib/cache/add-remote-git.js index 5fbd8dbeda..d8f64a85be 100644 --- a/deps/npm/lib/cache/add-remote-git.js +++ b/deps/npm/lib/cache/add-remote-git.js @@ -443,7 +443,7 @@ function getResolved (uri, treeish) { // Checks for known protocols: // http:, https:, ssh:, and git:, with optional git+ prefix. if (!parsed.protocol || - !parsed.protocol.match(/^(((git\+)?(https?|ssh))|git|file):$/)) { + !parsed.protocol.match(/^(((git\+)?(https?|ssh|file))|git|file):$/)) { uri = 'git+ssh://' + uri } diff --git a/deps/npm/lib/cache/caching-client.js b/deps/npm/lib/cache/caching-client.js index f06dde0021..a6bcee373d 100644 --- a/deps/npm/lib/cache/caching-client.js +++ b/deps/npm/lib/cache/caching-client.js @@ -75,6 +75,10 @@ function get (uri, params, cb) { return get_.call(this, uri, cachePath, params, cb) } + if (params.skipCache) { + return get_.call(this, uri, cachePath, params, cb) + } + var client = this fs.stat(cachePath, function (er, stat) { if (!er) { @@ -112,6 +116,8 @@ function get_ (uri, cachePath, params, cb) { if (data._etag) etag = data._etag if (data._lastModified) lastModified = data._lastModified + data._cached = true + if (stat && timeout && timeout > 0) { if ((Date.now() - stat.mtime.getTime()) / 1000 < timeout) { log.verbose('get', uri, 'not expired, no request') diff --git a/deps/npm/lib/completion.js b/deps/npm/lib/completion.js index 96f4c3ee55..ae611f918e 100644 --- a/deps/npm/lib/completion.js +++ b/deps/npm/lib/completion.js @@ -1,4 +1,3 @@ - module.exports = completion completion.usage = 'source <(npm completion)' @@ -14,6 +13,7 @@ var configNames = Object.keys(configTypes) var shorthandNames = Object.keys(shorthands) var allConfs = configNames.concat(shorthandNames) var once = require('once') +var isWindowsShell = require('./utils/is-windows-shell.js') completion.completion = function (opts, cb) { if (opts.w > 3) return cb() @@ -45,7 +45,7 @@ completion.completion = function (opts, cb) { } function completion (args, cb) { - if (process.platform === 'win32' && !(/^MINGW(32|64)$/.test(process.env.MSYSTEM))) { + if (isWindowsShell) { var e = new Error('npm completion supported only in MINGW / Git bash on Windows') e.code = 'ENOTSUP' e.errno = require('constants').ENOTSUP diff --git a/deps/npm/lib/config/core.js b/deps/npm/lib/config/core.js index d1306eb4c8..b833b75409 100644 --- a/deps/npm/lib/config/core.js +++ b/deps/npm/lib/config/core.js @@ -10,6 +10,7 @@ var ini = require('ini') var Umask = configDefs.Umask var mkdirp = require('mkdirp') var umask = require('../utils/umask') +var isWindows = require('../utils/is-windows.js') exports.load = load exports.Conf = Conf @@ -391,7 +392,7 @@ function parseField (f, k) { f = envReplace(f) if (isPath) { - var homePattern = process.platform === 'win32' ? /^~(\/|\\)/ : /^~\// + var homePattern = isWindows ? /^~(\/|\\)/ : /^~\// if (f.match(homePattern) && process.env.HOME) { f = path.resolve(process.env.HOME, f.substr(2)) } diff --git a/deps/npm/lib/explore.js b/deps/npm/lib/explore.js index 105ff84cc8..05b5220d5f 100644 --- a/deps/npm/lib/explore.js +++ b/deps/npm/lib/explore.js @@ -9,15 +9,30 @@ var npm = require('./npm.js') var spawn = require('./utils/spawn') var path = require('path') var fs = require('graceful-fs') +var isWindowsShell = require('./utils/is-windows-shell.js') +var escapeExecPath = require('./utils/escape-exec-path.js') +var escapeArg = require('./utils/escape-arg.js') function explore (args, cb) { if (args.length < 1 || !args[0]) return cb(explore.usage) var p = args.shift() - args = args.join(' ').trim() - if (args) args = ['-c', args] - else args = [] var cwd = path.resolve(npm.dir, p) + var opts = {cwd: cwd, stdio: 'inherit'} + + var shellArgs = [] + if (args) { + if (isWindowsShell) { + var execCmd = escapeExecPath(args.shift()) + var execArgs = [execCmd].concat(args.map(escapeArg)) + opts.windowsVerbatimArguments = true + shellArgs = ['/d', '/s', '/c'].concat(execArgs) + } else { + shellArgs.unshift('-c') + shellArgs = ['-c', args.map(escapeArg).join(' ').trim()] + } + } + var sh = npm.config.get('shell') fs.stat(cwd, function (er, s) { if (er || !s.isDirectory()) { @@ -26,17 +41,17 @@ function explore (args, cb) { )) } - if (!args.length) { + if (!shellArgs.length) { console.log( '\nExploring ' + cwd + '\n' + "Type 'exit' or ^D when finished\n" ) } - var shell = spawn(sh, args, { cwd: cwd, stdio: 'inherit' }) + var shell = spawn(sh, shellArgs, opts) shell.on('close', function (er) { // only fail if non-interactive. - if (!args.length) return cb() + if (!shellArgs.length) return cb() cb(er) }) }) diff --git a/deps/npm/lib/fetch-package-metadata.js b/deps/npm/lib/fetch-package-metadata.js index 8965a561aa..d4f02bb278 100644 --- a/deps/npm/lib/fetch-package-metadata.js +++ b/deps/npm/lib/fetch-package-metadata.js @@ -63,26 +63,29 @@ module.exports = function fetchPackageMetadata (spec, where, tracker, done) { fetchOtherPackageData(spec, dep, where, addRequestedAndFinish) } function addRequestedAndFinish (er, pkg) { - if (pkg) { - pkg._requested = dep - pkg._spec = spec - pkg._where = where - if (!pkg._args) pkg._args = [] - pkg._args.push([pkg._spec, pkg._where]) - // non-npm registries can and will return unnormalized data, plus - // even the npm registry may have package data normalized with older - // normalization rules. This ensures we get package data in a consistent, - // stable format. - try { - normalizePackageData(pkg) - } catch (ex) { - // don't care - } - } + if (pkg) annotateMetadata(pkg, dep, spec, where) logAndFinish(er, pkg) } } +var annotateMetadata = module.exports.annotateMetadata = function (pkg, requested, spec, where) { + validate('OOSS', arguments) + pkg._requested = requested + pkg._spec = spec + pkg._where = where + if (!pkg._args) pkg._args = [] + pkg._args.push([requested, where]) + // non-npm registries can and will return unnormalized data, plus + // even the npm registry may have package data normalized with older + // normalization rules. This ensures we get package data in a consistent, + // stable format. + try { + normalizePackageData(pkg) + } catch (ex) { + // don't care + } +} + function fetchOtherPackageData (spec, dep, where, next) { validate('SOSF', arguments) log.silly('fetchOtherPackageData', spec) @@ -150,6 +153,16 @@ function fetchNamedPackageData (dep, next) { } } + // We didn't manage to find a compatible version + // If this package was requested from cache, force hitting the network + if (pkg._cached) { + log.silly('fetchNamedPackageData', 'No valid target from cache, forcing network') + return npm.registry.get(url, { + auth: auth, + skipCache: true + }, pulseTillDone('fetchMetadata', iferr(next, pickVersionFromRegistryDocument))) + } + // And failing that, we error out var targets = versions.length ? 'Valid install targets:\n' + versions.join(', ') + '\n' diff --git a/deps/npm/lib/install/action/extract.js b/deps/npm/lib/install/action/extract.js index 4b627a5c30..60aae036c2 100644 --- a/deps/npm/lib/install/action/extract.js +++ b/deps/npm/lib/install/action/extract.js @@ -30,6 +30,11 @@ function andUpdatePackageJson (pkg, buildpath, next) { function andStageBundledChildren (pkg, buildpath, log, next) { var staging = path.resolve(buildpath, '..') return iferr(next, function () { + for (var i = 0; i < pkg.children.length; ++i) { + var c = pkg.children[i] + if (!c.package.name) return next(c.error) + } + asyncMap(pkg.children, andStageBundledModule(pkg, staging, buildpath), cleanupBundled) }) function cleanupBundled () { diff --git a/deps/npm/lib/install/deps.js b/deps/npm/lib/install/deps.js index e15403545c..edc317f846 100644 --- a/deps/npm/lib/install/deps.js +++ b/deps/npm/lib/install/deps.js @@ -31,30 +31,32 @@ var moduleName = require('../utils/module-name.js') // The export functions in this module mutate a dependency tree, adding // items to them. -function isDep (tree, child) { - if (child.fromShrinkwrap) return true +function isDep (tree, child, cb) { var name = moduleName(child) - var requested = isProdDep(tree, name) - var matches - if (requested) matches = doesChildVersionMatch(child, requested, tree) - if (matches) return matches - requested = isDevDep(tree, name) - if (!requested) return - return doesChildVersionMatch(child, requested, tree) + var prodVer = isProdDep(tree, name) + var devVer = isDevDep(tree, name) + + childDependencySpecifier(tree, name, prodVer, function (er, prodSpec) { + if (er) return cb(child.fromShrinkwrap) + var matches + if (prodSpec) matches = doesChildVersionMatch(child, prodSpec, tree) + if (matches) return cb(true, prodSpec) + if (devVer === prodVer) return cb(child.fromShrinkwrap) + childDependencySpecifier(tree, name, devVer, function (er, devSpec) { + if (er) return cb(child.fromShrinkwrap) + cb(doesChildVersionMatch(child, devSpec, tree) || child.fromShrinkwrap, null, devSpec) + }) + }) } -function isDevDep (tree, name) { +function isDevDep (tree, name, cb) { var devDeps = tree.package.devDependencies || {} - var reqVer = devDeps[name] - if (reqVer == null) return - return npa(name + '@' + reqVer) + return devDeps[name] } -function isProdDep (tree, name) { +function isProdDep (tree, name, cb) { var deps = tree.package.dependencies || {} - var reqVer = deps[name] - if (reqVer == null) return false - return npa(name + '@' + reqVer) + return deps[name] } var registryTypes = { range: true, version: true } @@ -80,6 +82,21 @@ exports.recalculateMetadata = function (tree, log, next) { recalculateMetadata(tree, log, {}, next) } +function childDependencySpecifier (tree, name, spec, cb) { + if (!tree.resolved) tree.resolved = {} + if (!tree.resolved[name]) tree.resolved[name] = {} + if (tree.resolved[name][spec]) { + return process.nextTick(function () { + cb(null, tree.resolved[name][spec]) + }) + } + realizePackageSpecifier(name + '@' + spec, packageRelativePath(tree), function (er, req) { + if (er) return cb(er) + tree.resolved[name][spec] = req + cb(null, req) + }) +} + function recalculateMetadata (tree, log, seen, next) { validate('OOOF', arguments) if (seen[tree.path]) return next() @@ -87,7 +104,8 @@ function recalculateMetadata (tree, log, seen, next) { if (tree.parent == null) resetMetadata(tree) function markDeps (spec, done) { validate('SF', arguments) - realizePackageSpecifier(spec, packageRelativePath(tree), function (er, req) { + var matched = spec.match(/^(@?[^@]+)@(.*)$/) + childDependencySpecifier(tree, matched[1], matched[2], function (er, req) { if (er || !req.name) return done() var child = findRequirement(tree, req.name, req) if (child) { @@ -106,11 +124,26 @@ function recalculateMetadata (tree, log, seen, next) { function specs (deps) { return Object.keys(deps).map(function (depname) { return depname + '@' + deps[depname] }) } + + // Ensure dependencies and dev dependencies are marked as required var tomark = specs(tree.package.dependencies) if (!tree.parent && (npm.config.get('dev') || !npm.config.get('production'))) { tomark = union(tomark, specs(tree.package.devDependencies)) } + // Ensure any children ONLY from a shrinkwrap are also included + var childrenOnlyInShrinkwrap = tree.children.filter(function (child) { + return child.fromShrinkwrap && + !tree.package.dependencies[child.package.name] && + !tree.package.devDependencies[child.package.name] + }) + var tomarkOnlyInShrinkwrap = childrenOnlyInShrinkwrap.map(function (child) { + return child.package._spec + }) + tomark = union(tomark, tomarkOnlyInShrinkwrap) + + // Don't bother trying to recalc children of failed deps tree.children = tree.children.filter(function (child) { return !child.failed }) + chain([ [asyncMap, tomark, markDeps], [asyncMap, tree.children, function (child, done) { recalculateMetadata(child, log, seen, done) }] @@ -122,13 +155,15 @@ function recalculateMetadata (tree, log, seen, next) { }) } -function addRequiredDep (tree, child) { - if (!isDep(tree, child)) return false - var name = isProdDep(tree, moduleName(child)) ? flatNameFromTree(tree) : '#DEV:' + flatNameFromTree(tree) - replaceModuleName(child.package, '_requiredBy', name) - replaceModule(child, 'requiredBy', tree) - replaceModule(tree, 'requires', child) - return true +function addRequiredDep (tree, child, cb) { + isDep(tree, child, function (childIsDep, childIsProdDep, childIsDevDep) { + if (!childIsDep) return cb(false) + var name = childIsProdDep ? flatNameFromTree(tree) : '#DEV:' + flatNameFromTree(tree) + replaceModuleName(child.package, '_requiredBy', name) + replaceModule(child, 'requiredBy', tree) + replaceModule(tree, 'requires', child) + cb(true) + }) } exports._removeObsoleteDep = removeObsoleteDep @@ -207,10 +242,12 @@ exports.loadRequestedDeps = function (args, tree, saveToDependencies, log, next) // For things the user asked to install, that aren't a dependency (or // won't be when we're done), flag it as "depending" on the user // themselves, so we don't remove it as a dep that no longer exists - if (!addRequiredDep(tree, child)) { - replaceModuleName(child.package, '_requiredBy', '#USER') - } - depLoaded(null, child, tracker) + addRequiredDep(tree, child, function (childIsDep) { + if (!childIsDep) { + replaceModuleName(child.package, '_requiredBy', '#USER') + } + depLoaded(null, child, tracker) + }) })) }, andForEachChild(loadDeps, andFinishTracker(log, next))) } @@ -382,8 +419,7 @@ exports.loadExtraneous.andResolveDeps = function (tree, log, next) { function addDependency (name, versionSpec, tree, log, done) { validate('SSOOF', arguments) var next = andAddParentToErrors(tree, done) - var spec = name + '@' + versionSpec - realizePackageSpecifier(spec, packageRelativePath(tree), iferr(done, function (req) { + childDependencySpecifier(tree, name, versionSpec, iferr(done, function (req) { var child = findRequirement(tree, name, req) if (child) { resolveWithExistingModule(child, tree, log, iferr(next, function (child, log) { @@ -401,11 +437,10 @@ function addDependency (name, versionSpec, tree, log, done) { function resolveWithExistingModule (child, tree, log, next) { validate('OOOF', arguments) - addRequiredDep(tree, child) - - if (tree.parent && child.parent !== tree) updatePhantomChildren(tree.parent, child) - - next(null, child, log) + addRequiredDep(tree, child, function () { + if (tree.parent && child.parent !== tree) updatePhantomChildren(tree.parent, child) + next(null, child, log) + }) } var updatePhantomChildren = exports.updatePhantomChildren = function (current, child) { @@ -482,22 +517,23 @@ function resolveWithNewModule (pkg, tree, log, next) { var replaced = replaceModule(parent, 'children', child) if (replaced) removeObsoleteDep(replaced) - addRequiredDep(tree, child) - pkg._location = flatNameFromTree(child) + addRequiredDep(tree, child, function () { + pkg._location = flatNameFromTree(child) - if (tree.parent && parent !== tree) updatePhantomChildren(tree.parent, child) + if (tree.parent && parent !== tree) updatePhantomChildren(tree.parent, child) - if (pkg._bundled) { - inflateBundled(child, child.children) - } + if (pkg._bundled) { + inflateBundled(child, child.children) + } - if (pkg._shrinkwrap && pkg._shrinkwrap.dependencies) { - return inflateShrinkwrap(child, pkg._shrinkwrap.dependencies, function (er) { - next(er, child, log) - }) - } + if (pkg._shrinkwrap && pkg._shrinkwrap.dependencies) { + return inflateShrinkwrap(child, pkg._shrinkwrap.dependencies, function (er) { + next(er, child, log) + }) + } - next(null, child, log) + next(null, child, log) + }) })) })) } diff --git a/deps/npm/lib/install/inflate-shrinkwrap.js b/deps/npm/lib/install/inflate-shrinkwrap.js index ce22f4e4c5..b38181b9f1 100644 --- a/deps/npm/lib/install/inflate-shrinkwrap.js +++ b/deps/npm/lib/install/inflate-shrinkwrap.js @@ -3,7 +3,9 @@ var url = require('url') var asyncMap = require('slide').asyncMap var validate = require('aproba') var iferr = require('iferr') +var realizePackageSpecifier = require('realize-package-specifier') var fetchPackageMetadata = require('../fetch-package-metadata.js') +var annotateMetadata = require('../fetch-package-metadata.js').annotateMetadata var addShrinkwrap = require('../fetch-package-metadata.js').addShrinkwrap var addBundled = require('../fetch-package-metadata.js').addBundled var inflateBundled = require('./inflate-bundled.js') @@ -32,7 +34,11 @@ var inflateShrinkwrap = module.exports = function (tree, swdeps, finishInflating child.package.version === sw.version)) { if (!child.fromShrinkwrap) child.fromShrinkwrap = spec tree.children.push(child) - return next() + + return realizePackageSpecifier(spec, tree.path, iferr(next, function (requested) { + annotateMetadata(child.package, requested, spec, tree.path) + return inflateShrinkwrap(child, sw.dependencies || {}, next) + })) } fetchPackageMetadata(spec, tree.path, iferr(next, function (pkg) { pkg._from = sw.from || spec diff --git a/deps/npm/lib/ls.js b/deps/npm/lib/ls.js index 4a71c54e1b..d2fe14fb2f 100644 --- a/deps/npm/lib/ls.js +++ b/deps/npm/lib/ls.js @@ -62,7 +62,11 @@ var lsFromTree = ls.fromTree = function (dir, physicalTree, args, silent, cb) { args = args.map(function (a) { var p = npa(a) var name = p.name - var ver = semver.validRange(p.rawSpec) || '' + // When version spec is missing, we'll skip using it when filtering. + // Otherwise, `semver.validRange` would return '*', which won't + // match prerelease versions. + var ver = (p.rawSpec && + (semver.validRange(p.rawSpec) || '')) return [ name, ver, a ] }) } @@ -292,8 +296,11 @@ function filterFound (root, args) { var argName = args[ii][0] var argVersion = args[ii][1] var argRaw = args[ii][2] - if (depName === argName) { + if (depName === argName && argVersion) { found = semver.satisfies(dep.version, argVersion, true) + } else if (depName === argName) { + // If version is missing from arg, just do a name match. + found = true } else if (dep.path === argRaw) { found = true } diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js index 4d45165063..9d6cda386a 100644 --- a/deps/npm/lib/npm.js +++ b/deps/npm/lib/npm.js @@ -87,7 +87,7 @@ npm.command = c if (commandCache[a]) return commandCache[a] - var cmd = require(__dirname + '/' + a + '.js') + var cmd = require(path.join(__dirname, a + '.js')) commandCache[a] = function () { var args = Array.prototype.slice.call(arguments, 0) @@ -96,6 +96,14 @@ } if (args.length === 1) args.unshift([]) + // Options are prefixed by a hyphen-minus (-, \u2d). + // Other dash-type chars look similar but are invalid. + Array(args[0]).forEach(function (arg) { + if (/^[\u2010-\u2015\u2212\uFE58\uFE63\uFF0D]/.test(arg)) { + log.error('arg', 'Argument starts with non-ascii dash, this is probably invalid:', arg) + } + }) + npm.registry.version = npm.version if (!npm.registry.refer) { npm.registry.refer = [a].concat(args[0]).map(function (arg) { diff --git a/deps/npm/lib/unbuild.js b/deps/npm/lib/unbuild.js index 9bb8d7b665..f5efb1ee6d 100644 --- a/deps/npm/lib/unbuild.js +++ b/deps/npm/lib/unbuild.js @@ -59,7 +59,7 @@ function rmStuff (pkg, folder, cb) { // if it's global, and folder is in {prefix}/node_modules, // then bins are in {prefix}/bin // otherwise, then bins are in folder/../.bin - var parent = path.dirname(folder) + var parent = pkg.name[0] === '@' ? path.dirname(path.dirname(folder)) : path.dirname(folder) var gnm = npm.dir var top = gnm === parent diff --git a/deps/npm/lib/utils/completion/file-completion.js b/deps/npm/lib/utils/completion/file-completion.js index 78777a025e..e16b636a68 100644 --- a/deps/npm/lib/utils/completion/file-completion.js +++ b/deps/npm/lib/utils/completion/file-completion.js @@ -1,7 +1,6 @@ module.exports = fileCompletion var mkdir = require('mkdirp') -var path = require('path') var glob = require('glob') function fileCompletion (root, req, depth, cb) { @@ -18,8 +17,7 @@ function fileCompletion (root, req, depth, cb) { glob(pattern, opts, function (er, files) { if (er) return cb(er) return cb(null, (files || []).map(function (f) { - var tail = f.substr(root.length + 1).replace(/^\//, '') - return path.join(req, tail) + return f.substr(root.length + 1).replace(/^\/|\/$/g, '') })) }) }) diff --git a/deps/npm/lib/utils/error-handler.js b/deps/npm/lib/utils/error-handler.js index 91b180e1b3..6eac7e9577 100644 --- a/deps/npm/lib/utils/error-handler.js +++ b/deps/npm/lib/utils/error-handler.js @@ -78,9 +78,11 @@ function exit (code, noLog) { } }) rollbacks.length = 0 + } else if (code && !noLog) { + writeLogFile(reallyExit) + } else { + rm('npm-debug.log', reallyExit) } - else if (code && !noLog) writeLogFile(reallyExit) - else rm('npm-debug.log', reallyExit) function reallyExit (er) { if (er && !code) code = typeof er.errno === 'number' ? er.errno : 1 diff --git a/deps/npm/lib/utils/escape-arg.js b/deps/npm/lib/utils/escape-arg.js new file mode 100644 index 0000000000..d12ee5edf5 --- /dev/null +++ b/deps/npm/lib/utils/escape-arg.js @@ -0,0 +1,27 @@ +'use strict' +var path = require('path') +var isWindowsShell = require('./is-windows-shell.js') + +/* +Escape the name of an executable suitable for passing to the system shell. + +Windows is easy, wrap in double quotes and you're done, as there's no +facility to create files with quotes in their names. + +Unix-likes are a little more complicated, wrap in single quotes and escape +any single quotes in the filename. +*/ + +module.exports = escapify + +function escapify (str) { + if (isWindowsShell) { + return '"' + path.normalize(str) + '"' + } else { + if (/[^-_.~/\w]/.test(str)) { + return "'" + str.replace(/'/g, "'\"'\"'") + "'" + } else { + return str + } + } +} diff --git a/deps/npm/lib/utils/escape-exec-path.js b/deps/npm/lib/utils/escape-exec-path.js new file mode 100644 index 0000000000..bf94886efa --- /dev/null +++ b/deps/npm/lib/utils/escape-exec-path.js @@ -0,0 +1,30 @@ +'use strict' +var path = require('path') +var isWindowsShell = require('./is-windows-shell.js') + +/* +Escape the name of an executable suitable for passing to the system shell. + +Windows is easy, wrap in double quotes and you're done, as there's no +facility to create files with quotes in their names. + +Unix-likes are a little more complicated, wrap in single quotes and escape +any single quotes in the filename. +*/ + +module.exports = escapify + +function windowsQuotes (str) { + if (!/ /.test(str)) return str + return '"' + str + '"' +} + +function escapify (str) { + if (isWindowsShell) { + return path.normalize(str).split(/\\/).map(windowsQuotes).join('\\') + } else if (/[^-_.~/\w]/.test(str)) { + return "'" + str.replace(/'/g, "'\"'\"'") + "'" + } else { + return str + } +} diff --git a/deps/npm/lib/utils/git.js b/deps/npm/lib/utils/git.js index 2d9da1086e..dc021300ea 100644 --- a/deps/npm/lib/utils/git.js +++ b/deps/npm/lib/utils/git.js @@ -32,14 +32,10 @@ function chainableExec () { return [execGit].concat(args) } -function whichGit (cb) { - return which(git, cb) -} - function whichAndExec (args, options, cb) { assert.equal(typeof cb, 'function', 'no callback provided') // check for git - whichGit(function (err) { + which(git, function (err) { if (err) { err.code = 'ENOGIT' return cb(err) diff --git a/deps/npm/lib/utils/is-windows-bash.js b/deps/npm/lib/utils/is-windows-bash.js new file mode 100644 index 0000000000..bc4ac7db49 --- /dev/null +++ b/deps/npm/lib/utils/is-windows-bash.js @@ -0,0 +1,3 @@ +'use strict' +var isWindows = require('./is-windows.js') +module.exports = isWindows && /^MINGW(32|64)$/.test(process.env.MSYSTEM) diff --git a/deps/npm/lib/utils/is-windows-shell.js b/deps/npm/lib/utils/is-windows-shell.js new file mode 100644 index 0000000000..803bbaa49c --- /dev/null +++ b/deps/npm/lib/utils/is-windows-shell.js @@ -0,0 +1,4 @@ +'use strict' +var isWindows = require('./is-windows.js') +var isWindowsBash = require('./is-windows-bash.js') +module.exports = isWindows && !isWindowsBash diff --git a/deps/npm/lib/utils/is-windows.js b/deps/npm/lib/utils/is-windows.js new file mode 100644 index 0000000000..8a991d54f5 --- /dev/null +++ b/deps/npm/lib/utils/is-windows.js @@ -0,0 +1,2 @@ +'use strict' +module.exports = process.platform === 'win32' diff --git a/deps/npm/lib/utils/lifecycle.js b/deps/npm/lib/utils/lifecycle.js index b5893ff6a4..fd1a59b74c 100644 --- a/deps/npm/lib/utils/lifecycle.js +++ b/deps/npm/lib/utils/lifecycle.js @@ -293,8 +293,10 @@ function makeEnv (data, prefix, env) { prefix = prefix || 'npm_package_' if (!env) { env = {} - for (var i in process.env) if (!i.match(/^npm_/)) { - env[i] = process.env[i] + for (var i in process.env) { + if (!i.match(/^npm_/)) { + env[i] = process.env[i] + } } // npat asks for tap output @@ -311,31 +313,33 @@ function makeEnv (data, prefix, env) { ) } - for (i in data) if (i.charAt(0) !== '_') { - var envKey = (prefix + i).replace(/[^a-zA-Z0-9_]/g, '_') - if (i === 'readme') { - continue - } - if (data[i] && typeof data[i] === 'object') { - try { - // quick and dirty detection for cyclical structures - JSON.stringify(data[i]) - makeEnv(data[i], envKey + '_', env) - } catch (ex) { - // usually these are package objects. - // just get the path and basic details. - var d = data[i] - makeEnv( - { name: d.name, version: d.version, path: d.path }, - envKey + '_', - env - ) + for (i in data) { + if (i.charAt(0) !== '_') { + var envKey = (prefix + i).replace(/[^a-zA-Z0-9_]/g, '_') + if (i === 'readme') { + continue + } + if (data[i] && typeof data[i] === 'object') { + try { + // quick and dirty detection for cyclical structures + JSON.stringify(data[i]) + makeEnv(data[i], envKey + '_', env) + } catch (ex) { + // usually these are package objects. + // just get the path and basic details. + var d = data[i] + makeEnv( + { name: d.name, version: d.version, path: d.path }, + envKey + '_', + env + ) + } + } else { + env[envKey] = String(data[i]) + env[envKey] = env[envKey].indexOf('\n') !== -1 + ? JSON.stringify(env[envKey]) + : env[envKey] } - } else { - env[envKey] = String(data[i]) - env[envKey] = env[envKey].indexOf('\n') !== -1 - ? JSON.stringify(env[envKey]) - : env[envKey] } } diff --git a/deps/npm/lib/utils/link.js b/deps/npm/lib/utils/link.js index d0492e076f..605b77402c 100644 --- a/deps/npm/lib/utils/link.js +++ b/deps/npm/lib/utils/link.js @@ -55,19 +55,15 @@ function link (from, to, gently, abs, cb) { if (npm.config.get('force')) gently = false to = path.resolve(to) - var target = from = path.resolve(from) - if (!abs && process.platform !== 'win32') { - // junctions on windows must be absolute - target = path.relative(path.dirname(to), from) - // if there is no folder in common, then it will be much - // longer, and using a relative link is dumb. - if (target.length >= from.length) target = from - } + var toDir = path.dirname(to) + var absTarget = path.resolve(toDir, from) + var relativeTarget = path.relative(toDir, absTarget) + var target = abs ? absTarget : relativeTarget chain( [ - [ensureFromIsNotSource, from, to], - [fs, 'stat', from], + [ensureFromIsNotSource, absTarget, to], + [fs, 'stat', absTarget], [rm, to, gently], [mkdir, path.dirname(to)], [fs, 'symlink', target, to, 'junction'] diff --git a/deps/npm/lib/utils/module-name.js b/deps/npm/lib/utils/module-name.js index 7ca175487c..649dfac01b 100644 --- a/deps/npm/lib/utils/module-name.js +++ b/deps/npm/lib/utils/module-name.js @@ -11,7 +11,7 @@ function pathToPackageName (dir) { if (dir === '') return '' var name = path.relative(path.resolve(dir, '..'), dir) var scoped = path.relative(path.resolve(dir, '../..'), dir) - if (scoped[0] === '@') return scoped + if (scoped[0] === '@') return scoped.replace(/\\/g, '/') return name } |