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
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/read-installed/read-installed.js')
-rw-r--r--node_modules/read-installed/read-installed.js147
1 files changed, 84 insertions, 63 deletions
diff --git a/node_modules/read-installed/read-installed.js b/node_modules/read-installed/read-installed.js
index 3574e6c2f..713d2633c 100644
--- a/node_modules/read-installed/read-installed.js
+++ b/node_modules/read-installed/read-installed.js
@@ -101,6 +101,8 @@ var url = require("url")
var util = require("util")
var extend = require("util-extend")
+var debug = require("debuglog")("read-installed")
+
module.exports = readInstalled
function readInstalled (folder, opts, cb) {
@@ -120,23 +122,26 @@ function readInstalled (folder, opts, cb) {
opts.log = function () {}
opts.dev = !!opts.dev
+ opts.realpathSeen = {}
+ opts.findUnmetSeen = []
+
readInstalled_(folder, null, null, null, 0, opts, function (er, obj) {
if (er) return cb(er)
// now obj has all the installed things, where they're installed
// figure out the inheritance links, now that the object is built.
resolveInheritance(obj, opts)
- markExtraneous(obj)
+ unmarkExtraneous(obj, opts)
cb(null, obj)
})
}
-var rpSeen = {}
function readInstalled_ (folder, parent, name, reqver, depth, opts, cb) {
var installed
, obj
, real
, link
+ , realpathSeen = opts.realpathSeen
fs.readdir(path.resolve(folder, "node_modules"), function (er, i) {
// error indicates that nothing is installed here
@@ -161,7 +166,7 @@ function readInstalled_ (folder, parent, name, reqver, depth, opts, cb) {
return next(er)
}
fs.realpath(folder, function (er, rp) {
- //console.error("realpath(%j) = %j", folder, rp)
+ debug("realpath(%j) = %j", folder, rp)
real = rp
if (st.isSymbolicLink()) link = rp
next(er)
@@ -176,10 +181,10 @@ function readInstalled_ (folder, parent, name, reqver, depth, opts, cb) {
errState = er
return cb(null, [])
}
- //console.error('next', installed, obj && typeof obj, name, real)
+ debug('next', installed, obj && typeof obj, name, real)
if (!installed || !obj || !real || called) return
called = true
- if (rpSeen[real]) return cb(null, rpSeen[real])
+ if (realpathSeen[real]) return cb(null, realpathSeen[real])
if (obj === true) {
obj = {dependencies:{}, path:folder}
installed.forEach(function (i) { obj.dependencies[i] = "*" })
@@ -188,6 +193,9 @@ function readInstalled_ (folder, parent, name, reqver, depth, opts, cb) {
obj.realName = name || obj.name
obj.dependencies = obj.dependencies || {}
+ // At this point, figure out what dependencies we NEED to get met
+ obj._dependencies = copy(obj.dependencies)
+
// "foo":"http://blah" and "foo":"latest" are always presumed valid
if (reqver
&& semver.validRange(reqver, true)
@@ -195,21 +203,17 @@ function readInstalled_ (folder, parent, name, reqver, depth, opts, cb) {
obj.invalid = true
}
- if (parent) {
- var deps = parent.dependencies || {}
- var inDeps = name in deps
- var devDeps = parent.devDependencies || {}
- var inDev = opts.dev && (name in devDeps)
- if (!inDeps && !inDev) {
- obj.extraneous = true
- }
- }
+ // Mark as extraneous at this point.
+ // This will be un-marked in unmarkExtraneous, where we mark as
+ // not-extraneous everything that is required in some way from
+ // the root object.
+ obj.extraneous = true
obj.path = obj.path || folder
obj.realPath = real
obj.link = link
if (parent && !obj.link) obj.parent = parent
- rpSeen[real] = obj
+ realpathSeen[real] = obj
obj.depth = depth
//if (depth >= opts.depth) return cb(null, obj)
asyncMap(installed, function (pkg, cb) {
@@ -259,50 +263,45 @@ function resolveInheritance (obj, opts) {
findUnmet(obj.dependencies[dep], opts)
})
Object.keys(obj.dependencies).forEach(function (dep) {
- resolveInheritance(obj.dependencies[dep], opts)
+ if (typeof obj.dependencies[dep] === "object") {
+ resolveInheritance(obj.dependencies[dep], opts)
+ } else {
+ debug("unmet dep! %s %s@%s", obj.name, dep, obj.dependencies[dep])
+ }
})
findUnmet(obj, opts)
}
// find unmet deps by walking up the tree object.
// No I/O
-var fuSeen = []
function findUnmet (obj, opts) {
- if (fuSeen.indexOf(obj) !== -1) return
- fuSeen.push(obj)
- //console.error("find unmet", obj.name, obj.parent && obj.parent.name)
+ var findUnmetSeen = opts.findUnmetSeen
+ if (findUnmetSeen.indexOf(obj) !== -1) return
+ findUnmetSeen.push(obj)
+ debug("find unmet parent=%s obj=", obj.parent && obj.parent.name, obj.name || obj)
var deps = obj.dependencies = obj.dependencies || {}
- //console.error(deps)
+ debug(deps)
Object.keys(deps)
.filter(function (d) { return typeof deps[d] === "string" })
.forEach(function (d) {
- //console.error("find unmet", obj.name, d, deps[d])
- var r = obj.parent
- , found = null
- while (r && !found && typeof deps[d] === "string") {
- // if r is a valid choice, then use that.
- found = r.dependencies[d]
- if (!found && r.realName === d) found = r
-
- if (!found) {
- r = r.link ? null : r.parent
- continue
- }
- // "foo":"http://blah" and "foo":"latest" are always presumed valid
- if ( typeof deps[d] === "string"
- && semver.validRange(deps[d], true)
- && !semver.satisfies(found.version, deps[d], true)) {
- // the bad thing will happen
- opts.log("unmet dependency", obj.path + " requires "+d+"@'"+deps[d]
- +"' but will load\n"
- +found.path+",\nwhich is version "+found.version
- )
- found.invalid = true
- }
+ var found = findDep(obj, d)
+ debug("finding dep %j", d, found && found.name || found)
+ // "foo":"http://blah" and "foo":"latest" are always presumed valid
+ if (typeof deps[d] === "string" &&
+ semver.validRange(deps[d], true) &&
+ found &&
+ !semver.satisfies(found.version, deps[d], true)) {
+ // the bad thing will happen
+ opts.log( "unmet dependency"
+ , obj.path + " requires "+d+"@'"+deps[d]
+ + "' but will load\n"
+ + found.path+",\nwhich is version "+found.version )
+ found.invalid = true
+ }
+ if (found) {
deps[d] = found
}
-
})
var peerDeps = obj.peerDependencies = obj.peerDependencies || {}
@@ -329,34 +328,56 @@ function findUnmet (obj, opts) {
obj.dependencies[d] = peerDeps[d]
} else if (!semver.satisfies(dependency.version, peerDeps[d], true)) {
dependency.peerInvalid = true
- } else {
- dependency.extraneous = dependency.extraneous || false
}
})
return obj
}
-function recursivelyMarkExtraneous (obj, extraneous) {
- // stop recursion if we're not changing anything
- if (obj.extraneous === extraneous) return
+function unmarkExtraneous (obj, opts) {
+ // Mark all non-required deps as extraneous.
+ // start from the root object and mark as non-extraneous all modules
+ // that haven't been previously flagged as extraneous then propagate
+ // to all their dependencies
+
+ obj.extraneous = false
+ var deps = obj._dependencies
+ if (opts.dev && obj.devDependencies) {
+ Object.keys(obj.devDependencies).forEach(function (k) {
+ deps[k] = obj.devDependencies[k]
+ })
+ }
- obj.extraneous = extraneous
- var deps = obj.dependencies = obj.dependencies || {}
- Object.keys(deps).forEach(function(d){
- recursivelyMarkExtraneous(deps[d], extraneous)
- });
+ if (obj.peerDependencies) {
+ Object.keys(obj.peerDependencies).forEach(function (k) {
+ deps[k] = obj.peerDependencies[k]
+ })
+ }
+
+ Object.keys(deps).forEach(function (d) {
+ var dep = findDep(obj, d)
+ if (dep && dep.extraneous) {
+ unmarkExtraneous(dep, opts)
+ }
+ })
}
-function markExtraneous (obj) {
- // start from the root object and mark as non-extraneous all modules that haven't been previously flagged as
- // extraneous then propagate to all their dependencies
- var deps = obj.dependencies = obj.dependencies || {}
- Object.keys(deps).forEach(function(d){
- if (!deps[d].extraneous){
- recursivelyMarkExtraneous(deps[d], false);
+// Find the one that will actually be loaded by require()
+// so we can make sure it's valid etc.
+function findDep (obj, d) {
+ var r = obj
+ , found = null
+ while (r && !found) {
+ // if r is a valid choice, then use that.
+ // kinda weird if a pkg depends on itself, but after the first
+ // iteration of this loop, it indicates a dep cycle.
+ if (typeof r.dependencies[d] === "object") {
+ found = r.dependencies[d]
}
- });
+ if (!found && r.realName === d) found = r
+ r = r.link ? null : r.parent
+ }
+ return found
}
function copy (obj) {