1// prune extraneous packages. 2 3module.exports = prune 4module.exports.Pruner = Pruner 5 6prune.usage = 'npm prune [[<@scope>/]<pkg>...] [--production]' 7 8var npm = require('./npm.js') 9var log = require('npmlog') 10var util = require('util') 11var moduleName = require('./utils/module-name.js') 12var Installer = require('./install.js').Installer 13var isExtraneous = require('./install/is-extraneous.js') 14var isOnlyDev = require('./install/is-only-dev.js') 15var removeDeps = require('./install/deps.js').removeDeps 16var loadExtraneous = require('./install/deps.js').loadExtraneous 17var chain = require('slide').chain 18var computeMetadata = require('./install/deps.js').computeMetadata 19 20prune.completion = require('./utils/completion/installed-deep.js') 21 22function prune (args, cb) { 23 var dryrun = !!npm.config.get('dry-run') 24 new Pruner('.', dryrun, args).run(cb) 25} 26 27function Pruner (where, dryrun, args) { 28 Installer.call(this, where, dryrun, args) 29 this.autoPrune = true 30} 31util.inherits(Pruner, Installer) 32 33Pruner.prototype.loadAllDepsIntoIdealTree = function (cb) { 34 log.silly('uninstall', 'loadAllDepsIntoIdealTree') 35 36 var cg = this.progress['loadIdealTree:loadAllDepsIntoIdealTree'] 37 var steps = [] 38 39 computeMetadata(this.idealTree) 40 var self = this 41 var excludeDev = npm.config.get('production') || /^prod(uction)?$/.test(npm.config.get('only')) 42 function shouldPrune (child) { 43 if (isExtraneous(child)) return true 44 if (!excludeDev) return false 45 return isOnlyDev(child) 46 } 47 function getModuleName (child) { 48 // wrapping because moduleName doesn't like extra args and we're called 49 // from map. 50 return moduleName(child) 51 } 52 function matchesArg (name) { 53 return self.args.length === 0 || self.args.indexOf(name) !== -1 54 } 55 function nameObj (name) { 56 return {name: name} 57 } 58 var toPrune = this.idealTree.children.filter(shouldPrune).map(getModuleName).filter(matchesArg).map(nameObj) 59 60 steps.push( 61 [removeDeps, toPrune, this.idealTree, null], 62 [loadExtraneous, this.idealTree, cg.newGroup('loadExtraneous')]) 63 chain(steps, cb) 64} 65 66Pruner.prototype.runPreinstallTopLevelLifecycles = function (cb) { cb() } 67Pruner.prototype.runPostinstallTopLevelLifecycles = function (cb) { cb() } 68Pruner.prototype.saveToDependencies = function (cb) { cb() } 69