From 0a25c17ebe875b1d81cb2e7b5d705d5d683a4855 Mon Sep 17 00:00:00 2001 From: Vladimir Alaev Date: Wed, 14 Nov 2012 19:28:01 +0200 Subject: [PATCH] Install shrink-wrapped package dependencies recursively (reference --- lib/install.js | 62 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/lib/install.js b/lib/install.js index ecb5d0d7..04d14c81 100644 --- a/lib/install.js +++ b/lib/install.js @@ -479,7 +479,7 @@ function installMany (what, where, context, cb) { // what is a list of things. // resolve each one. asyncMap( what - , targetResolver(where, context, d) + , targetResolver(where, context, d, wrap) , function (er, targets) { if (er) return cb(er) @@ -499,24 +499,56 @@ function installMany (what, where, context, cb) { }) asyncMap(targets, function (target, cb) { log.info("installOne", target._id) - var newWrap = wrap ? wrap[target.name].dependencies || {} : null - var newContext = { family: newPrev + + var newWrap = (wrap && wrap[target.name])? wrap[target.name].dependencies || {} : null + , newContext = { family: newPrev , ancestors: newAnc , parent: parent , explicit: false , wrap: newWrap } - installOne(target, where, newContext, cb) + + // if the package already installed and has the version equal to the shrinkwrap + // call installMany for the package deps + if (target.depsOnly && target.depsOnly[where]) { + + var newWhere = path.join(where, 'node_modules', target.name) + + readDependencies(newContext, where, opt, function(er, data, wrap) { + var deps = Object.keys(data.dependencies || {}) + + var newContext = { family: newPrev + , ancestors: newAnc + , parent: parent + , explicit: false + , wrap: wrap } + + installMany(deps.map(function(d) { + return d + "@" + data.dependencies[d] + }), newWhere, newContext, function(er, d) { + + log.verbose("about to build", newWhere) + if (er) return cb(er) + npm.commands.build([newWhere] + , npm.config.get("global") + , true + , function(er) { + return cb(er, d) + }) + }) + }) + } + else installOne(target, where, newContext, cb) }, cb) }) }) } -function targetResolver (where, context, deps) { +function targetResolver (where, context, deps, wrap) { var alreadyInstalledManually = context.explicit ? [] : null , nm = path.resolve(where, "node_modules") , parent = context.parent - , wrap = context.wrap - + , wrap = context.wrap || wrap + if (!context.explicit) fs.readdir(nm, function (er, inst) { if (er) return alreadyInstalledManually = [] asyncMap(inst, function (pkg, cb) { @@ -550,8 +582,20 @@ function targetResolver (where, context, deps) { // now we know what's been installed here manually, // or tampered with in some way that npm doesn't want to overwrite. if (alreadyInstalledManually.indexOf(what.split("@").shift()) !== -1) { - log.verbose("already installed", "skipping %s %s", what, where) - return cb(null, []) + if (!wrap) { + log.verbose("already installed", "skipping %s %s", what, where) + return cb(null, []) + } + + var name = what.split(/@/).shift() + + return cache.read(name, wrap[name].version, false, function(er, data) { + // depsOnly will tell later that the package is ok but we should to check its deps + data.depsOnly = data.depsOnly || {} + data.depsOnly[where] = true; + data._from = what + return cb(er, data) + }) } // check for a version installed higher in the tree.