• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict'
2// remove a package.
3
4module.exports = uninstall
5
6const path = require('path')
7const validate = require('aproba')
8const readJson = require('read-package-json')
9const iferr = require('iferr')
10const npm = require('./npm.js')
11const Installer = require('./install.js').Installer
12const getSaveType = require('./install/save.js').getSaveType
13const removeDeps = require('./install/deps.js').removeDeps
14const log = require('npmlog')
15const usage = require('./utils/usage')
16
17uninstall.usage = usage(
18  'uninstall',
19  'npm uninstall [<@scope>/]<pkg>[@<version>]... [--save-prod|--save-dev|--save-optional] [--no-save]'
20)
21
22uninstall.completion = require('./utils/completion/installed-shallow.js')
23
24function uninstall (args, cb) {
25  validate('AF', arguments)
26  // the /path/to/node_modules/..
27  const dryrun = !!npm.config.get('dry-run')
28
29  if (args.length === 1 && args[0] === '.') args = []
30
31  const where = npm.config.get('global') || !args.length
32    ? path.resolve(npm.globalDir, '..')
33    : npm.prefix
34
35  args = args.filter(function (a) {
36    return path.resolve(a) !== where
37  })
38
39  if (args.length) {
40    new Uninstaller(where, dryrun, args).run(cb)
41  } else {
42    // remove this package from the global space, if it's installed there
43    readJson(path.resolve(npm.localPrefix, 'package.json'), function (er, pkg) {
44      if (er && er.code !== 'ENOENT' && er.code !== 'ENOTDIR') return cb(er)
45      if (er) return cb(uninstall.usage)
46      new Uninstaller(where, dryrun, [pkg.name]).run(cb)
47    })
48  }
49}
50
51class Uninstaller extends Installer {
52  constructor (where, dryrun, args) {
53    super(where, dryrun, args)
54    this.remove = []
55  }
56
57  loadArgMetadata (next) {
58    this.args = this.args.map(function (arg) { return {name: arg} })
59    next()
60  }
61
62  loadAllDepsIntoIdealTree (cb) {
63    validate('F', arguments)
64    this.remove = this.args
65    this.args = []
66    log.silly('uninstall', 'loadAllDepsIntoIdealTree')
67    const saveDeps = getSaveType()
68
69    super.loadAllDepsIntoIdealTree(iferr(cb, () => {
70      removeDeps(this.remove, this.idealTree, saveDeps, cb)
71    }))
72  }
73
74  // no top level lifecycles on rm
75  runPreinstallTopLevelLifecycles (cb) { cb() }
76  runPostinstallTopLevelLifecycles (cb) { cb() }
77}
78
79module.exports.Uninstaller = Uninstaller
80