prune.js 2.2 KB

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