summaryrefslogtreecommitdiff
path: root/deps/npm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/lib')
-rw-r--r--deps/npm/lib/fetch-package-metadata.js10
-rw-r--r--deps/npm/lib/install/action/finalize.js37
-rw-r--r--deps/npm/lib/install/deps.js24
-rw-r--r--deps/npm/lib/install/diff-trees.js1
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))) {