1 |
|
2 |
|
3 |
|
4 | module.exports = uninstall
|
5 |
|
6 | uninstall.usage = "npm uninstall <name>[@<version> [<name>[@<version>] ...]"
|
7 | + "\nnpm rm <name>[@<version> [<name>[@<version>] ...]"
|
8 |
|
9 | uninstall.completion = require("./utils/completion/installed-shallow.js")
|
10 |
|
11 | var fs = require("graceful-fs")
|
12 | , writeFileAtomic = require("write-file-atomic")
|
13 | , log = require("npmlog")
|
14 | , readJson = require("read-package-json")
|
15 | , path = require("path")
|
16 | , npm = require("./npm.js")
|
17 | , asyncMap = require("slide").asyncMap
|
18 |
|
19 | function uninstall (args, cb) {
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | var nm = npm.dir
|
27 | if (args.length === 1 && args[0] === ".") args = []
|
28 | if (args.length) return uninstall_(args, nm, cb)
|
29 |
|
30 |
|
31 | if (npm.config.get("global")) return cb(uninstall.usage)
|
32 | readJson(path.resolve(npm.prefix, "package.json"), function (er, pkg) {
|
33 | if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
|
34 | if (er) return cb(uninstall.usage)
|
35 | uninstall_( [pkg.name]
|
36 | , npm.dir
|
37 | , cb )
|
38 | })
|
39 |
|
40 | }
|
41 |
|
42 | function uninstall_ (args, nm, cb) {
|
43 |
|
44 |
|
45 | var s = npm.config.get('save')
|
46 | , d = npm.config.get('save-dev')
|
47 | , o = npm.config.get('save-optional')
|
48 | if (s || d || o) {
|
49 | cb = saver(args, nm, cb)
|
50 | }
|
51 |
|
52 | asyncMap(args, function (arg, cb) {
|
53 |
|
54 | var p = path.join(path.resolve(nm), path.join("/", arg))
|
55 | if (path.resolve(p) === nm) {
|
56 | log.warn("uninstall", "invalid argument: %j", arg)
|
57 | return cb(null, [])
|
58 | }
|
59 | fs.lstat(p, function (er) {
|
60 | if (er) {
|
61 | log.warn("uninstall", "not installed in %s: %j", nm, arg)
|
62 | return cb(null, [])
|
63 | }
|
64 | cb(null, p)
|
65 | })
|
66 | }, function (er, folders) {
|
67 | if (er) return cb(er)
|
68 | asyncMap(folders, npm.commands.unbuild, cb)
|
69 | })
|
70 | }
|
71 |
|
72 | function saver (args, nm, cb_) {
|
73 | return cb
|
74 | function cb (er, data) {
|
75 | var s = npm.config.get('save')
|
76 | , d = npm.config.get('save-dev')
|
77 | , o = npm.config.get('save-optional')
|
78 | if (er || !(s || d || o)) return cb_(er, data)
|
79 | var pj = path.resolve(nm, '..', 'package.json')
|
80 |
|
81 |
|
82 | fs.readFile(pj, 'utf8', function (er, json) {
|
83 | var pkg
|
84 | try {
|
85 | pkg = JSON.parse(json)
|
86 | } catch (_) {}
|
87 | if (!pkg) return cb_(null, data)
|
88 |
|
89 | var bundle
|
90 | if (npm.config.get('save-bundle')) {
|
91 | bundle = pkg.bundleDependencies || pkg.bundledDependencies
|
92 | if (!Array.isArray(bundle)) bundle = undefined
|
93 | }
|
94 |
|
95 | var changed = false
|
96 | args.forEach(function (a) {
|
97 | ; [ [s, 'dependencies']
|
98 | , [o, 'optionalDependencies']
|
99 | , [d, 'devDependencies'] ].forEach(function (f) {
|
100 | var flag = f[0]
|
101 | , field = f[1]
|
102 | if (!flag || !pkg[field] || !pkg[field].hasOwnProperty(a)) return
|
103 | changed = true
|
104 |
|
105 | if (bundle) {
|
106 | var i = bundle.indexOf(a)
|
107 | if (i !== -1) bundle.splice(i, 1)
|
108 | }
|
109 |
|
110 | delete pkg[field][a]
|
111 | })
|
112 | })
|
113 | if (!changed) return cb_(null, data)
|
114 |
|
115 | if (bundle) {
|
116 | delete pkg.bundledDependencies
|
117 | if (bundle.length) {
|
118 | pkg.bundleDependencies = bundle
|
119 | } else {
|
120 | delete pkg.bundleDependencies
|
121 | }
|
122 | }
|
123 |
|
124 | writeFileAtomic(pj, JSON.stringify(pkg, null, 2) + "\n", function (er) {
|
125 | return cb_(er, data)
|
126 | })
|
127 | })
|
128 | }
|
129 | }
|