Installer.prototype.loadAllDepsIntoIdealTree = function (cb) { validate('F', arguments) log.silly('install', 'loadAllDepsIntoIdealTree') var saveDeps = getSaveType(this.args) var cg = this.progress.loadAllDepsIntoIdealTree var installNewModules = !!this.args.length var steps = [] if (installNewModules) { steps.push([loadRequestedDeps, this.args, this.idealTree, saveDeps, cg.newGroup('loadRequestedDeps')]) } else { steps.push( [loadDeps, this.idealTree, cg.newGroup('loadDeps')]) if (this.dev) { steps.push( [loadDevDeps, this.idealTree, cg.newGroup('loadDevDeps')]) } } steps.push( [loadExtraneous.andResolveDeps, this.idealTree, cg.newGroup('loadExtraneous')]) chain(steps, cb) }
function run (pkg, wd, cmd, args, cb) { var cmds = [] if (!pkg.scripts) pkg.scripts = {} if (cmd === "restart") { cmds = ["prestop","stop","poststop" ,"restart" ,"prestart","start","poststart"] } else { cmds = [cmd] } if (!cmd.match(/^(pre|post)/)) { cmds = ["pre"+cmd].concat(cmds).concat("post"+cmd) } log.verbose("run-script", cmds) chain(cmds.map(function (c) { // pass cli arguments after -- to script. if (args.length && pkg.scripts[c]) { pkg.scripts[c] = pkg.scripts[c] + " " + args.join(" ") } // when running scripts explicitly, assume that they're trusted. return [lifecycle, pkg, c, wd, true] }), cb) }
chain(installSteps, function (installEr) { if (installEr) self.failing = true chain(postInstallSteps, function (postInstallEr) { if (self.idealTree) { self.idealTree.warnings.forEach(function (warning) { if (warning.code === 'EPACKAGEJSON' && self.global) return if (warning.code === 'ENOTDIR') return errorMessage(warning).summary.forEach(function (logline) { log.warn.apply(log, logline) }) }) } if (installEr && postInstallEr) { var msg = errorMessage(postInstallEr) msg.summary.forEach(function (logline) { log.warn.apply(log, logline) }) msg.detail.forEach(function (logline) { log.verbose.apply(log, logline) }) } cb(installEr || postInstallEr, self.getInstalledModules(), self.idealTree) }) })
exports = module.exports = function(source, opts, fn) { if (typeof opts === 'function') { fn = opts; opts = {}; } source = source || process.cwd(); opts = opts || {}; opts.ignore = opts.ignore || ['.git']; opts.type = opts.type || 'tgz'; opts.env = opts.env || {}; opts.log = opts.log || opts.logger || logger; opts.host = opts.host || envs('ANVIL_HOST', 'https://api.anvilworks.org'); opts.codon = opts.codon || envs('CODON_URL', 'https://s3-external-1.amazonaws.com/codon-buildpacks/buildpacks'); opts.request = request; // TODO init a superagent-defaults context chain([ [buildpack, opts.buildpack || '', Object.create(opts)], // initialize the buildpack [choose(source), source, first, Object.create(opts)] // compile the app using the buildpack ], function(err, res) { if (err) return fn(err); fn(null, res[1], res[2]); }); };
readDependencies(context, targetFolder, opt, function (er, data, wrap) { var deps = prepareForInstallMany(data, "dependencies", bundled, wrap, family) var depsTargetFolder = targetFolder var depsContext = { family:family, ancestors:context.ancestors, parent:target, explicit:false, wrap:wrap } var peerDeps = prepareForInstallMany(data, "peerDependencies", bundled, wrap, family) var pdTargetFolder = path.resolve(targetFolder, "..", "..") var pdContext = context var actions = [ [ installManyAndBuild, deps, depsTargetFolder, depsContext ] ] if (peerDeps.length > 0) { actions.push( [ installManyAndBuild, peerDeps, pdTargetFolder, pdContext ] ) } chain(actions, cb) })
Installer.prototype.run = function (cb) { validate('F', arguments) // FIXME: This is bad and I should feel bad. // lib/install needs to have some way of sharing _limited_ // state with the things it calls. Passing the object is too // much. The global config is WAY too much. =( =( // But not having this is gonna break linked modules in // subtle stupid ways, and refactoring all this code isn't // the right thing to do just yet. if (this.global) { var prevGlobal = npm.config.get('global') npm.config.set('global', true) var next = cb cb = function () { npm.config.set('global', prevGlobal) next.apply(null, arguments) } } var installSteps = [] var postInstallSteps = [] installSteps.push( [this.newTracker(log, 'loadCurrentTree', 4)], [this, this.loadCurrentTree], [this, this.finishTracker, 'loadCurrentTree'], [this.newTracker(log, 'loadIdealTree', 12)], [this, this.loadIdealTree], [this, this.finishTracker, 'loadIdealTree'], [this, this.debugTree, 'currentTree', 'currentTree'], [this, this.debugTree, 'idealTree', 'idealTree'], [this.newTracker(log, 'generateActionsToTake')], [this, this.generateActionsToTake], [this, this.finishTracker, 'generateActionsToTake'], [this, this.debugActions, 'diffTrees', 'differences'], [this, this.debugActions, 'decomposeActions', 'todo']) if (!this.dryrun) { installSteps.push( [this.newTracker(log, 'executeActions', 8)], [this, this.executeActions], [this, this.finishTracker, 'executeActions']) var node_modules = path.resolve(this.where, 'node_modules') var staging = path.resolve(node_modules, '.staging') postInstallSteps.push( [this.newTracker(log, 'rollbackFailedOptional', 1)], [this, this.rollbackFailedOptional, staging, this.todo], [this, this.finishTracker, 'rollbackFailedOptional'], [this, this.commit, staging, this.todo], [this.newTracker(log, 'runTopLevelLifecycles', 2)], [this, this.runTopLevelLifecycles], [this, this.finishTracker, 'runTopLevelLifecycles']) if (getSaveType(this.args)) { postInstallSteps.push( [this, this.saveToDependencies]) } } postInstallSteps.push( [this, this.printInstalled]) var self = this chain(installSteps, function (installEr) { if (installEr) self.failing = true chain(postInstallSteps, function (postInstallEr) { if (self.idealTree) { self.idealTree.warnings.forEach(function (warning) { if (warning.code === 'EPACKAGEJSON' && self.global) return if (warning.code === 'ENOTDIR') return log.warn(warning.code, warning.message) }) } if (installEr && postInstallEr) { log.warn('error', postInstallEr.message) log.verbose('error', postInstallEr.stack) } cb(installEr || postInstallEr, self.getInstalledModules(), self.idealTree) }) }) }
Installer.prototype.run = function (_cb) { validate('F', arguments) var cb = function (err) { saveMetrics(!err) return _cb.apply(this, arguments) } // FIXME: This is bad and I should feel bad. // lib/install needs to have some way of sharing _limited_ // state with the things it calls. Passing the object is too // much. The global config is WAY too much. =( =( // But not having this is gonna break linked modules in // subtle stupid ways, and refactoring all this code isn't // the right thing to do just yet. if (this.global) { var prevGlobal = npm.config.get('global') npm.config.set('global', true) var next = cb cb = function () { npm.config.set('global', prevGlobal) next.apply(null, arguments) } } var installSteps = [] var postInstallSteps = [] if (!this.dryrun) { installSteps.push( [this.newTracker(log, 'runTopLevelLifecycles', 2)], [this, this.runPreinstallTopLevelLifecycles]) } installSteps.push( [this.newTracker(log, 'loadCurrentTree', 4)], [this, this.loadCurrentTree], [this, this.finishTracker, 'loadCurrentTree'], [this.newTracker(log, 'loadIdealTree', 12)], [this, this.loadIdealTree], [this, this.finishTracker, 'loadIdealTree'], [this, this.debugTree, 'currentTree', 'currentTree'], [this, this.debugTree, 'idealTree', 'idealTree'], [this.newTracker(log, 'generateActionsToTake')], [this, this.generateActionsToTake], [this, this.finishTracker, 'generateActionsToTake'], [this, this.debugActions, 'diffTrees', 'differences'], [this, this.debugActions, 'decomposeActions', 'todo']) if (!this.dryrun) { installSteps.push( [this.newTracker(log, 'executeActions', 8)], [this, this.executeActions], [this, this.finishTracker, 'executeActions']) var node_modules = path.resolve(this.where, 'node_modules') var staging = path.resolve(node_modules, '.staging') postInstallSteps.push( [this.newTracker(log, 'rollbackFailedOptional', 1)], [this, this.rollbackFailedOptional, staging, this.todo], [this, this.finishTracker, 'rollbackFailedOptional'], [this, this.commit, staging, this.todo], [this, this.runPostinstallTopLevelLifecycles], [this, this.finishTracker, 'runTopLevelLifecycles'] ) if (getSaveType()) { postInstallSteps.push( // this is necessary as we don't fill in `dependencies` and `devDependencies` in deps loaded from shrinkwrap // until after we extract them [this, (next) => { computeMetadata(this.idealTree); next() }], [this, this.pruneIdealTree], [this, this.saveToDependencies]) } } postInstallSteps.push( [this, this.printWarnings], [this, this.printInstalled]) var self = this chain(installSteps, function (installEr) { if (installEr) self.failing = true chain(postInstallSteps, function (postInstallEr) { if (installEr && postInstallEr) { var msg = errorMessage(postInstallEr) msg.summary.forEach(function (logline) { log.warn.apply(log, logline) }) msg.detail.forEach(function (logline) { log.verbose.apply(log, logline) }) } cb(installEr || postInstallEr, self.getInstalledModules(), self.idealTree) }) }) }
'statement': _.partial(test1, insertData1, insertIntegerStatement), }; var testsArray = []; for(var iterKey in tests) { testsArray.push((function(key) { return function(cb) { init(function() { tests[key](function(err) { if (err) console.log("Test", key, "ERROR", err); else console.log("Test", key, "DONE"); cb(err); }); }); }; })(iterKey)); } slide.chain( testsArray, function(e) { if (e) return console.log(e); console.log("ALL TESTS DONE"); } );
function write (target, targetFolder, context, cb_) { var up = npm.config.get("unsafe-perm") , user = up ? null : npm.config.get("user") , group = up ? null : npm.config.get("group") , family = context.family function cb (er, data) { // cache.unpack returns the data object, and all we care about // is the list of installed packages from that last thing. if (!er) return cb_(er, data) if (false === npm.config.get("rollback")) return cb_(er) npm.commands.unbuild([targetFolder], function (er2) { if (er2) log.error(er2, "error rolling back "+target._id) return cb_(er, data) }) } var bundled = [] chain ( [ [ cache.unpack, target.name, target.version, targetFolder , null, null, user, group ] , [ fs, "writeFile" , path.resolve(targetFolder, "package.json") , JSON.stringify(target, null, 2) + "\n" ] , [ lifecycle, target, "preinstall", targetFolder ] , function (cb) { if (!target.bundleDependencies) return cb() var bd = path.resolve(targetFolder, "node_modules") fs.readdir(bd, function (er, b) { // nothing bundled, maybe if (er) return cb() bundled = b || [] cb() }) } ] // nest the chain so that we can throw away the results returned // up until this point, since we really don't care about it. , function X (er) { if (er) return cb(er) // before continuing to installing dependencies, check for a shrinkwrap. readDependencies(context, targetFolder, {}, function (er, data, wrap) { var deps = Object.keys(data.dependencies || {}) // don't install bundleDependencies, unless they're missing. if (data.bundleDependencies) { deps = deps.filter(function (d) { return data.bundleDependencies.indexOf(d) === -1 || bundled.indexOf(d) === -1 }) } var newcontext = { family: family , ancestors: context.ancestors , parent: target , explicit: false , wrap: wrap } installMany(deps.filter(function (d) { // prefer to not install things that are satisfied by // something in the "family" list, unless we're installing // from a shrinkwrap. return wrap || !semver.satisfies(family[d], data.dependencies[d]) }).map(function (d) { var t = data.dependencies[d] , parsed = url.parse(t.replace(/^git\+/, "git")) t = d + "@" + t return t }), targetFolder, newcontext, function (er, d) { log.verbose(targetFolder, "about to build") if (er) return cb(er) npm.commands.build( [targetFolder] , npm.config.get("global") , true , function (er) { return cb(er, d) }) }) }) }) }
Installer.prototype.run = function (cb) { validate('F', arguments) var installSteps = [] var postInstallSteps = [] installSteps.push( [this.newTracker(log, 'loadCurrentTree', 4)], [this, this.loadCurrentTree], [this, this.finishTracker, 'loadCurrentTree'], [this.newTracker(log, 'loadIdealTree', 12)], [this, this.loadIdealTree], [this, this.finishTracker, 'loadIdealTree'], [this, this.debugTree, 'currentTree', 'currentTree'], [this, this.debugTree, 'idealTree', 'idealTree'], [this.newTracker(log, 'generateActionsToTake')], [this, this.generateActionsToTake], [this, this.finishTracker, 'generateActionsToTake'], [this, this.debugActions, 'diffTrees', 'differences'], [this, this.debugActions, 'decomposeActions', 'todo']) if (!this.dryrun) { installSteps.push( [this.newTracker(log, 'executeActions', 8)], [this, this.executeActions], [this, this.finishTracker, 'executeActions']) var node_modules = path.resolve(this.where, 'node_modules') var staging = path.resolve(node_modules, '.staging') postInstallSteps.push( [this.newTracker(log, 'rollbackFailedOptional', 1)], [this, this.rollbackFailedOptional, staging, this.todo], [this, this.finishTracker, 'rollbackFailedOptional'], [this.newTracker(log, 'runTopLevelLifecycles', 2)], [this, this.runTopLevelLifecycles], [this, this.finishTracker, 'runTopLevelLifecycles']) if (getSaveType(this.args)) { postInstallSteps.push( [this, this.saveToDependencies]) } } postInstallSteps.push( [this, this.printInstalled]) var self = this chain(installSteps, function (installEr) { if (installEr) self.failing = true chain(postInstallSteps, function (postInstallEr) { if (self.idealTree) { self.idealTree.warnings.forEach(function (warning) { log.warn(warning.code, warning.message) }) } if (installEr && postInstallEr) { log.warn('error', postInstallEr.message) log.verbose('error', postInstallEr.stack) } cb(installEr || postInstallEr, self.idealTree) }) }) }
Runner.prototype.runFiles = function (files, dir, cb) { var self = this chain(files.map(function (f) { return function (cb) { var relDir = dir || path.dirname(f) , fileName = relDir === "." ? f : f.substr(relDir.length + 1) self.write(fileName) fs.lstat(f, function (er, st) { if (er) { self.write(assert.fail("failed to stat "+f, {error: er})) return cb() } var command = f , params = self.params.slice() if (typeof self.runner !== 'undefined') { command = self.runner params.push(fileName) } else if (path.extname(f) === ".js") { command = "node" params.push(fileName) } else if (path.extname(f) === ".coffee") { command = "coffee" params.push(fileName) } else if (path.extname(f) === ".tap") { command = "node" params = [path.join(__dirname, '..', 'bin', 'cat.js'), fileName] } if (st.isDirectory()) { return self.runDir(f, cb) } var env = {} for (var i in process.env) env[i] = process.env[i] env.TAP = 1 var cp = child_process.spawn(command, params, { env: env, cwd: relDir }) , out = "" , fullOutAndErr = "" //used for combined stdout (tap and other) + stderr, used for failed , nonTapOutAndErr = "" //filtered version of stdout + stderr, used for success , tc = new TapConsumer , childTests = [f] tc.on("data", function (c) { self.emit("result", c) self.write(c) }) // Workaround for isaacs/node-tap#109 and substack/tape#140 var lastLine = ''; var filter = split(function(line) { if (/\s+(expected|actual):$/.test(line)) { lastLine = line; } else { line = lastLine + line; lastLine = ''; return line + '\n'; } }); cp.stdout.pipe(filter).pipe(tc); filter.on("data", function (c) { out += c }); filter.on("data", function (c) { var lines = c.toString().split('\n'); var inYaml = false; var filtered = lines.reduce(function (accum, l) { //remove the yamlish details between --- and ... if (!inYaml) { if (/^\s{2}---\s*$/.test(l)) { inYaml = true; } else { //not in yaml, not a --- line, so keep it if not an excluded tap line if (l.length && !/^(\d+\.\.\d+|#\s+tests\s+\d+|#\s+pass\s+\d+|#\s+fail\s+\d+|TAP\s+version\s+\d+)\s*$/.test(l)) accum.push(l); } } else { //in yaml if (/^\s{2}\.\.\.\s*$/.test(l)) inYaml = false; } return accum; }, []); var nonTapAdd = filtered.filter(nonTapOutput); // only non-tap stdout if (nonTapAdd.length) nonTapAdd.push(''); nonTapOutAndErr += nonTapAdd.join('\n'); if (self.colorize) filtered = filtered.map(colorizeTapOutput); if (filtered.length) filtered.push(''); fullOutAndErr += filtered.join('\n'); // tap and non-tap output }); cp.stderr.on("data", function (c) { //all stderr is used regardless of file error status fullOutAndErr += c; nonTapOutAndErr += c; }); var killed = false; var killTimeout = setTimeout(function() { cp.kill(); killed = true; }, self.timeout); var TAP_OUT_RE = /^ok|^#|^not ok/; function nonTapOutput(line) { return !line.match(TAP_OUT_RE); } function colorizeTapOutput(line) { var x = line; return /^ok/.test(x) ? clc.green(x) : /^#/.test(x) ? clc.blue(x) : /^not ok/.test(x) ? clc.red(x) : x; } var calls = 0, exitCode = null; cp.on('close', function(code) { exitCode = code; if (++calls == 2) { done(exitCode); } }); filter.on('end', function() { if (++calls == 2) { done(exitCode); } }); function done(code) { clearTimeout(killTimeout); //childTests.forEach(function (c) { self.write(c) }) var res = { name: fileName , ok: !code } if (fullOutAndErr) res.fullOutAndErr = fullOutAndErr; if (nonTapOutAndErr) res.nonTapOutAndErr = nonTapOutAndErr; if (killed) { res.ok = false; // in v0.11.14, code == undefined here tc.results.ok = false; tc.results.list.push({ ok: false, name: 'Test file timed out: ' + fileName, found: true, wanted: false, file: fileName, line: 0 }); } res.command = [command].concat(params).map(JSON.stringify).join(" ") self.emit("result", res) self.emit("file", f, res, tc.results) self.write(res) self.write("\n") cb() } }) } }), cb) return self }
function gentlyRm (target, gently, base, cb) { if (!cb) { cb = base base = undefined } if (!cb) { cb = gently gently = false } log.silly( 'gentlyRm', target, 'is being', gently ? 'gently removed' : 'purged', base ? 'from base ' + base : '' ) // never rm the root, prefix, or bin dirs // // globals included because of `npm link` -- as far as the package // requesting the link is concerned, the linked package is always // installed globally var prefixes = [ npm.prefix, npm.globalPrefix, npm.dir, npm.root, npm.globalDir, npm.bin, npm.globalBin ] var targetPath = normalize(resolve(npm.prefix, target)) if (prefixes.indexOf(targetPath) !== -1) { log.verbose('gentlyRm', targetPath, "is part of npm and can't be removed") return cb(new Error('May not delete: ' + targetPath)) } var options = { log: log.silly.bind(log, 'vacuum-fs') } if (npm.config.get('force') || !gently) options.purge = true if (base) options.base = normalize(resolve(npm.prefix, base)) if (!gently) { log.verbose('gentlyRm', "don't care about contents; nuking", targetPath) return vacuum(targetPath, options, cb) } var parent = options.base = options.base || normalize(npm.prefix) // Do all the async work we'll need to do in order to tell if this is a // safe operation chain([ [isEverInside, parent, prefixes], [readLinkOrShim, targetPath], [isEverInside, targetPath, prefixes], [isEverInside, targetPath, [parent]] ], function (er, results) { if (er) { if (er.code === 'ENOENT') return cb() return cb(er) } var parentInfo = { path: parent, managed: results[0] } var targetInfo = { path: targetPath, symlink: results[1], managed: results[2], inParent: results[3] } isSafeToRm(parentInfo, targetInfo, iferr(cb, thenRemove)) function thenRemove (toRemove, removeBase) { if (!toRemove) return cb() if (removeBase) options.base = removeBase log.verbose('gentlyRm', options.purge ? 'Purging' : 'Vacuuming', toRemove, 'up to', options.base) return vacuum(toRemove, options, cb) } }) }
MultipartWriteS3Upload.prototype.finishUpload = function(cb) { chain([ !_.isEmpty(this.__chunks) && [this._queueChunksForUpload.bind(this)], [this._completeMultipartUpload.bind(this)] ], cb); };
function runFiles(self, files, dir, cb) { chain(files.map(function(f) { return function (cb) { if (self._bailedOut) return var relDir = dir || path.dirname(f) , fileName = relDir === "." ? f : f.substr(relDir.length + 1) self.write(fileName) fs.lstat(f, function(er, st) { if (er) { self.write(assert.fail("failed to stat " + f, {error: er})) return cb() } var cmd = f, args = [], env = {} if (path.extname(f) === ".js") { cmd = process.execPath if (self.options.gc) { args.push("--expose-gc") } if (self.options.debug) { args.push("--debug") setOptionsForDebug(self) } if (self.options["debug-brk"]) { args.push("--debug-brk") setOptionsForDebug(self) } if (self.options.strict) { args.push("--use-strict") } if (self.options.harmony) { args.push("--harmony") } args.push(fileName) } else if (path.extname(f) === ".coffee") { cmd = "coffee" args.push(fileName) } else { // Check if file is executable if ((st.mode & parseInt('0100', 8)) && process.getuid) { if (process.getuid() != st.uid) { return cb() } } else if ((st.mode & parseInt('0010', 8)) && process.getgid) { if (process.getgid() != st.gid) { return cb() } } else if ((st.mode & parseInt('0001', 8)) == 0) { return cb() } cmd = path.resolve(cmd) } if (st.isDirectory()) { return self.runDir(f, cb) } if (doCoverage && path.extname(f) === ".js") { var foriginal = fs.readFileSync(f, "utf8") , fcontents = self.coverHeader() + foriginal + self.coverFooter() , tmpBaseName = path.basename(f, path.extname(f)) + ".with-coverage." + process.pid + path.extname(f) , tmpFname = path.resolve(path.dirname(f), tmpBaseName) fs.writeFileSync(tmpFname, fcontents, "utf8") args.splice(-1, 1, tmpFname) } for (var i in process.env) { env[i] = process.env[i] } env.TAP = 1 var cp = child_process.spawn(cmd, args, { env: env, cwd: relDir }) , out = "" , err = "" , tc = new TapConsumer() , childTests = [f] var timeout = setTimeout(function () { if (!cp._ended) { cp._timedOut = true cp.kill() } }, self.options.timeout * 1000) tc.on("data", function(c) { self.emit("result", c) self.write(c) }) tc.on("bailout", function (message) { clearTimeout(timeout) console.log("# " + f.substr(process.cwd().length + 1)) process.stderr.write(err) process.stdout.write(out + "\n") self._bailedOut = true cp._ended = true cp.kill() }) cp.stdout.pipe(tc) cp.stdout.on("data", function (c) { out += c }) cp.stderr.on("data", function (c) { if (self.options.stderr) process.stderr.write(c) err += c }) cp.on("close", function (code, signal) { if (cp._ended) return cp._ended = true var ok = !cp._timedOut && code === 0 clearTimeout(timeout) //childTests.forEach(function (c) { self.write(c) }) var res = { name: path.dirname(f).replace(process.cwd() + "/", "") + "/" + fileName , ok: ok , exit: code } if (cp._timedOut) res.timedOut = cp._timedOut if (signal) res.signal = signal if (err) { res.stderr = err if (tc.results.ok && tc.results.tests === 0 && !self.options.stderr) { // perhaps a compilation error or something else failed. // no need if stderr is set, since it will have been // output already anyway. console.error(err) } } // tc.results.ok = tc.results.ok && ok tc.results.add(res) res.command = '"'+[cmd].concat(args).join(" ")+'"' self.emit("result", res) self.emit("file", f, res, tc.results) self.write(res) self.write("\n") if (doCoverage) { self.f2delete.push(tmpFname) } cb() }) }) } }), cb) return self }
function write (target, targetFolder, context, cb_) { var up = npm.config.get("unsafe-perm") , user = up ? null : npm.config.get("user") , group = up ? null : npm.config.get("group") , family = context.family function cb (er, data) { // cache.unpack returns the data object, and all we care about // is the list of installed packages from that last thing. if (!er) return cb_(er, data) if (npm.config.get("rollback") === false) return cb_(er) npm.rollbacks.push(targetFolder) cb_(er, data) } var bundled = [] log.silly("install write", "writing", target.name, target.version, "to", targetFolder) chain( [ [ cache.unpack, target.name, target.version, targetFolder, null, null, user, group ], function writePackageJSON (cb) { var jsonPath = path.resolve(targetFolder, 'package.json') log.verbose('write', 'writing to', jsonPath) writeFileAtomic(jsonPath, JSON.stringify(target, null, 2) + '\n', cb) }, [ lifecycle, target, "preinstall", targetFolder ], function collectBundled (cb) { if (!target.bundleDependencies) return cb() var bd = path.resolve(targetFolder, "node_modules") fs.readdir(bd, function (er, b) { // nothing bundled, maybe if (er) return cb() bundled = b || [] cb() }) } ] // nest the chain so that we can throw away the results returned // up until this point, since we really don't care about it. , function X (er) { if (er) return cb(er) // before continuing to installing dependencies, check for a shrinkwrap. var opt = { dev: npm.config.get("dev") } readDependencies(context, targetFolder, opt, function (er, data, wrap) { var deps = prepareForInstallMany(data, "dependencies", bundled, wrap, family) var depsTargetFolder = targetFolder var depsContext = { family: family , ancestors: context.ancestors , parent: target , explicit: false , wrap: wrap } var actions = [ [ installManyAndBuild, deps, depsTargetFolder, depsContext ] ] // FIXME: This is an accident waiting to happen! // // 1. If multiple children at the same level of the tree share a // peerDependency that's not in the parent's dependencies, because // the peerDeps don't get added to the family, they will keep // getting reinstalled (worked around by inflighting installOne). // 2. The installer can't safely build at the parent level because // that's already being done by the parent's installAndBuild. This // runs the risk of the peerDependency never getting built. // // The fix: Don't install peerDependencies; require them to be // included as explicit dependencies / devDependencies, and warn // or error when they're missing. See #5080 for more arguments in // favor of killing implicit peerDependency installs with fire. var peerDeps = prepareForInstallMany(data, "peerDependencies", bundled, wrap, family) peerDeps.forEach(function (pd) { warnPeers([ "The peer dependency "+pd+" included from "+data.name+" will no", "longer be automatically installed to fulfill the peerDependency ", "in npm 3+. Your application will need to depend on it explicitly." ], pd+","+data.name) }) // Package scopes cause an addditional tree level which needs to be // considered when resolving a peerDependency's target folder. var pdTargetFolder if (npa(target.name).scope) { pdTargetFolder = path.resolve(targetFolder, '../../..') } else { pdTargetFolder = path.resolve(targetFolder, '../..') } var pdContext = context if (peerDeps.length > 0) { actions.push( [ installMany, peerDeps, pdTargetFolder, pdContext ] ) } chain(actions, cb) }) }) }
function write (target, targetFolder, context, cb_) { var up = npm.config.get("unsafe-perm") , user = up ? null : npm.config.get("user") , group = up ? null : npm.config.get("group") , family = context.family function cb (er, data) { // cache.unpack returns the data object, and all we care about // is the list of installed packages from that last thing. if (!er) return cb_(er, data) if (false === npm.config.get("rollback")) return cb_(er) npm.commands.unbuild([targetFolder], true, function (er2) { if (er2) log.error("error rolling back", target._id, er2) return cb_(er, data) }) } var bundled = [] chain ( [ [ cache.unpack, target.name, target.version, targetFolder , null, null, user, group ] , [ fs, "writeFile" , path.resolve(targetFolder, "package.json") , JSON.stringify(target, null, 2) + "\n" ] , [ lifecycle, target, "preinstall", targetFolder ] , function (cb) { if (!target.bundleDependencies) return cb() var bd = path.resolve(targetFolder, "node_modules") fs.readdir(bd, function (er, b) { // nothing bundled, maybe if (er) return cb() bundled = b || [] cb() }) } ] // nest the chain so that we can throw away the results returned // up until this point, since we really don't care about it. , function X (er) { if (er) return cb(er) // before continuing to installing dependencies, check for a shrinkwrap. var opt = { dev: npm.config.get("dev") } readDependencies(context, targetFolder, opt, function (er, data, wrap) { var deps = prepareForInstallMany(data, "dependencies", bundled, wrap, family) var depsTargetFolder = targetFolder var depsContext = { family: family , ancestors: context.ancestors , parent: target , explicit: false , wrap: wrap } var peerDeps = prepareForInstallMany(data, "peerDependencies", bundled, wrap, family) var pdTargetFolder = path.resolve(targetFolder, "..", "..") var pdContext = context var actions = [ [ installManyAndBuild, deps, depsTargetFolder, depsContext ] ] if (peerDeps.length > 0) { actions.push( [ installMany, peerDeps, pdTargetFolder, pdContext ] ) } chain(actions, cb) }) }) }
function recalculateMetadata (tree, log, seen, next) { validate('OOOF', arguments) if (seen[tree.path]) return next() seen[tree.path] = true if (tree.parent == null) { resetMetadata(tree) tree.isTop = true } function markDeps (toMark, done) { var name = toMark.name var spec = toMark.spec var kind = toMark.kind childDependencySpecifier(tree, name, spec, function (er, req) { if (er || !req.name) return done() var child = findRequirement(tree, req.name, req) if (child) { resolveWithExistingModule(child, tree, log, andIgnoreErrors(done)) } else if (kind === 'dep') { tree.missingDeps[req.name] = req.rawSpec done() } else if (kind === 'dev') { tree.missingDevDeps[req.name] = req.rawSpec done() } else { done() } }) } function makeMarkable (deps, kind) { if (!deps) return [] return Object.keys(deps).map(function (depname) { return { name: depname, spec: deps[depname], kind: kind } }) } // Ensure dependencies and dev dependencies are marked as required var tomark = makeMarkable(tree.package.dependencies, 'dep') if (tree.isTop) tomark = union(tomark, makeMarkable(tree.package.devDependencies, 'dev')) // Ensure any children ONLY from a shrinkwrap are also included var childrenOnlyInShrinkwrap = tree.children.filter(function (child) { return child.fromShrinkwrap && !tree.package.dependencies[child.package.name] && !tree.package.devDependencies[child.package.name] }) var tomarkOnlyInShrinkwrap = childrenOnlyInShrinkwrap.map(function (child) { var name = child.package.name var matched = child.package._spec.match(/^@?[^@]+@(.*)$/) var spec = matched ? matched[1] : child.package._spec var kind = tree.package.dependencies[name] ? 'dep' : tree.package.devDependencies[name] ? 'dev' : 'dep' return { name: name, spec: spec, kind: kind } }) tomark = union(tomark, tomarkOnlyInShrinkwrap) // Don't bother trying to recalc children of failed deps tree.children = tree.children.filter(function (child) { return !child.failed }) chain([ [asyncMap, tomark, markDeps], [asyncMap, tree.children, function (child, done) { recalculateMetadata(child, log, seen, done) }] ], function () { tree.location = flatNameFromTree(tree) next(null, tree) }) }
}, function (er, pkgs) { if (er) return cb(er) chain(pkgs.map(function (pkg) { return function (cb) { submodule_(pkg, cb) }}), cb) })
asyncMap(args, function (pkg, done) { chain([ [checkSelf, idealTree, pkg, force], [isInstallable, pkg] ], done) }, next)