Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRebecca Turner <me@re-becca.org>2015-08-14 09:49:54 +0300
committerRebecca Turner <me@re-becca.org>2015-08-21 22:30:51 +0300
commitd395a6b8767853eede6ad4502266ac99504f51a8 (patch)
treefb8342416ab11abb720750fcada1b57104da4d26 /lib
parentd119ea67804e4bd2ea00025bd1d779cf7ec8ca18 (diff)
diff-trees: Make install order more consistent for directly dependencies
The install order is determined by: 1) The location of the thing to be installed relative to the root module. 2) Dependency order, such that a -> b -> c will install modules as: c, b, a 1 is deterministic, regardless of what's being installed. But 2 can change the order of things higher in the dep tree. Eg, b, or a might get sorted earlier if c requires them. This mostly doesn't matter, but it does mean that if you have two modules with conflicting bins, they _can_ get installed in different orders. This changes sorts all of the top level modules to be LAST, in location order (1), and then sorts all the rest per (2). This ensures that top level modules have a deterministic install order. (Non top level modules can't have bin conflicts as that's treated the same as a version conflict and the conflicting module would be hoisted.) PR-URL: https://github.com/npm/npm/pull/9274 Fixes: #8995
Diffstat (limited to 'lib')
-rw-r--r--lib/install/diff-trees.js32
1 files changed, 26 insertions, 6 deletions
diff --git a/lib/install/diff-trees.js b/lib/install/diff-trees.js
index e52d950bf..768bcde55 100644
--- a/lib/install/diff-trees.js
+++ b/lib/install/diff-trees.js
@@ -59,6 +59,12 @@ function requiredByAllLinked (node) {
return node.requiredBy.filter(isLink).length === node.requiredBy.length
}
+function isNotReqByTop (req) {
+ return req !== '/' && // '/' is the top level itself
+ req !== '#USER' && // #USER
+ req !== '#EXTRANEOUS'
+}
+
var sortActions = module.exports.sortActions = function (differences) {
var actions = {}
differences.forEach(function (action) {
@@ -68,22 +74,36 @@ var sortActions = module.exports.sortActions = function (differences) {
var sorted = []
var added = {}
- Object.keys(actions).sort(sortByLocation).forEach(function (location) {
+
+ var sortedlocs = Object.keys(actions).sort(sortByLocation)
+
+ // Do top level deps first, this stops the sorting by required order from
+ // unsorting these deps.
+ var toplocs = sortedlocs.filter(function (location) {
+ var mod = actions[location][1]
+ if (!mod.package._requiredBy) return true
+ // If the module is required by ANY non-top level package
+ // then we don't want to include this.
+ return !mod.package._requiredBy.some(isNotReqByTop)
+ })
+
+ toplocs.concat(sortedlocs).forEach(function (location) {
sortByDeps(actions[location])
})
function sortByLocation (aa, bb) {
- return aa.length - bb.length || bb.localeCompare(aa)
+ return bb.localeCompare(aa)
}
function sortByDeps (action) {
- var cmd = action[1]
- if (added[cmd.package._location]) return
- added[cmd.package._location] = action
- cmd.package._requiredBy.forEach(function (location) {
+ var mod = action[1]
+ if (added[mod.package._location]) return
+ added[mod.package._location] = action
+ mod.package._requiredBy.sort().forEach(function (location) {
if (actions[location]) sortByDeps(actions[location])
})
sorted.unshift(action)
}
+
return sorted
}