• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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