diff options
Diffstat (limited to 'deps/npm/lib')
-rw-r--r-- | deps/npm/lib/fetch-package-metadata.js | 10 | ||||
-rw-r--r-- | deps/npm/lib/install/action/finalize.js | 37 | ||||
-rw-r--r-- | deps/npm/lib/install/deps.js | 24 | ||||
-rw-r--r-- | deps/npm/lib/install/diff-trees.js | 1 |
4 files changed, 56 insertions, 16 deletions
diff --git a/deps/npm/lib/fetch-package-metadata.js b/deps/npm/lib/fetch-package-metadata.js index 103ed2fc6a..9e62cacd91 100644 --- a/deps/npm/lib/fetch-package-metadata.js +++ b/deps/npm/lib/fetch-package-metadata.js @@ -15,6 +15,7 @@ var rimraf = require('rimraf') var clone = require('lodash.clonedeep') var validate = require('aproba') var unpipe = require('unpipe') +var normalizePackageData = require('normalize-package-data') var npm = require('./npm.js') var mapToRegistry = require('./utils/map-to-registry.js') @@ -68,6 +69,15 @@ module.exports = function fetchPackageMetadata (spec, where, tracker, done) { 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 + } } logAndFinish(er, pkg) } diff --git a/deps/npm/lib/install/action/finalize.js b/deps/npm/lib/install/action/finalize.js index 62e21cc47d..08e9c149c4 100644 --- a/deps/npm/lib/install/action/finalize.js +++ b/deps/npm/lib/install/action/finalize.js @@ -4,7 +4,23 @@ var rimraf = require('rimraf') var fs = require('graceful-fs') var mkdirp = require('mkdirp') var asyncMap = require('slide').asyncMap -var andIgnoreErrors = require('../and-ignore-errors.js') +var iferr = require('iferr') + +function getTree (pkg) { + while (pkg.parent) pkg = pkg.parent + return pkg +} + +function warn (pkg, code, msg) { + var tree = getTree(pkg) + var err = new Error(msg) + err.code = code + tree.warnings.push(err) +} + +function pathToShortname (modpath) { + return modpath.replace(/node_modules[/]/g, '').replace(/[/]/g, ' > ') +} module.exports = function (top, buildpath, pkg, log, next) { log.silly('finalize', pkg.path) @@ -59,15 +75,26 @@ module.exports = function (top, buildpath, pkg, log, next) { function moveModules (mkdirEr, files) { if (mkdirEr) return next(mkdirEr) asyncMap(files, function (file, done) { + // `from` wins over `to`, because if `from` was there it's because the + // module installer wanted it to be there. By contrast, `to` is just + // whatever was bundled in this module. And the intentions of npm's + // installer should always beat out random module contents. var from = path.join(delpath, 'node_modules', file) var to = path.join(pkg.path, 'node_modules', file) - // we ignore errors here, because they can legitimately happen, for instance, - // bundled modules will be in both node_modules folders - fs.rename(from, to, andIgnoreErrors(done)) + fs.stat(to, function (er, info) { + if (er) return fs.rename(from, to, done) + + var shortname = pathToShortname(path.relative(getTree(pkg).path, to)) + warn(pkg, 'EBUNDLEOVERRIDE', 'Replacing bundled ' + shortname + ' with new installed version') + rimraf(to, iferr(done, function () { + fs.rename(from, to, done) + })) + }) }, cleanup) } - function cleanup () { + function cleanup (moveEr) { + if (moveEr) return next(moveEr) rimraf(delpath, afterCleanup) } diff --git a/deps/npm/lib/install/deps.js b/deps/npm/lib/install/deps.js index d2486419fc..3afe8af012 100644 --- a/deps/npm/lib/install/deps.js +++ b/deps/npm/lib/install/deps.js @@ -38,11 +38,11 @@ function isDep (tree, child) { var name = moduleName(child) var requested = isProdDep(tree, name) var matches - if (requested) matches = doesChildVersionMatch(child, requested) + if (requested) matches = doesChildVersionMatch(child, requested, tree) if (matches) return matches requested = isDevDep(tree, name) if (!requested) return - return doesChildVersionMatch(child, requested) + return doesChildVersionMatch(child, requested, tree) } function isDevDep (tree, name) { @@ -61,10 +61,10 @@ function isProdDep (tree, name) { var registryTypes = { range: true, version: true } -function doesChildVersionMatch (child, requested) { +function doesChildVersionMatch (child, requested, requestor) { // we always consider deps provided by a shrinkwrap as "correct" or else // we'll subvert them if they're intentionally "invalid" - if (child.fromShrinkwrap) return true + if (child.parent === requestor && child.fromShrinkwrap) return true // ranges of * ALWAYS count as a match, because when downloading we allow // prereleases to match * if there are ONLY prereleases if (requested.spec === '*') return true @@ -515,13 +515,14 @@ function validateAllPeerDeps (tree, onInvalid, seen) { // Determine if a module requirement is already met by the tree at or above // our current location in the tree. -var findRequirement = exports.findRequirement = function (tree, name, requested) { - validate('OSO', arguments) +var findRequirement = exports.findRequirement = function (tree, name, requested, requestor) { + validate('OSO', [tree, name, requested]) + if (!requestor) requestor = tree var nameMatch = function (child) { return moduleName(child) === name && child.parent && !child.removed } var versionMatch = function (child) { - return doesChildVersionMatch(child, requested) + return doesChildVersionMatch(child, requested, requestor) } if (nameMatch(tree)) { // this *is* the module, but it doesn't match the version, so a @@ -538,7 +539,7 @@ var findRequirement = exports.findRequirement = function (tree, name, requested) return null } if (!tree.parent) return null - return findRequirement(tree.parent, name, requested) + return findRequirement(tree.parent, name, requested, requestor) } // Find the highest level in the tree that we can install this module in. @@ -554,10 +555,11 @@ var earliestInstallable = exports.earliestInstallable = function (requiredBy, tr // If any of the children of this tree have conflicting // binaries then we need to decline to install this package here. - var binaryMatches = tree.children.some(function (child) { + var binaryMatches = typeof pkg.bin === 'object' && tree.children.some(function (child) { if (child.removed) return false - return Object.keys(child.package.bin || {}).some(function (bin) { - return pkg.bin && pkg.bin[bin] + if (typeof child.package.bin !== 'object') return false + return Object.keys(child.package.bin).some(function (bin) { + return pkg.bin[bin] }) }) if (binaryMatches) return null diff --git a/deps/npm/lib/install/diff-trees.js b/deps/npm/lib/install/diff-trees.js index 9e9d6c4486..59567bf319 100644 --- a/deps/npm/lib/install/diff-trees.js +++ b/deps/npm/lib/install/diff-trees.js @@ -132,6 +132,7 @@ function diffTrees (oldTree, newTree) { requiredByAllLinked(pkg) if (pkg.fromBundle) { if (npm.config.get('rebuild-bundle')) differences.push(['rebuild', pkg]) + if (pkg.oldPkg) differences.push(['remove', pkg]) } else if (pkg.oldPkg) { if (!pkg.directlyRequested && pkgAreEquiv(pkg.oldPkg.package, pkg.package)) return if (!pkg.isInLink && (isLink(pkg.oldPkg) || isLink(pkg))) { |