UNPKG

7.85 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3var david = require("../")
4 , clc = require("cli-color-tty")()
5 , Table = require("cli-table")
6 , fs = require("fs")
7 , npm = require("npm")
8 , argv = require("minimist")(process.argv.slice(2))
9 , xtend = require("xtend")
10 , cwd = process.cwd()
11 , packageFile = cwd + "/package.json"
12
13if (argv.usage || argv.help || argv.h) {
14 return console.log(fs.readFileSync(__dirname + "/usage.txt", "utf8"))
15}
16
17if (argv.version || argv.v) {
18 return console.log("v" + require("../package.json").version)
19}
20
21argv.update = argv._.indexOf("update") > -1 || argv._.indexOf("u") > -1
22
23/**
24 * Like printDeps, walk the list, but only print dependencies
25 * with warnings.
26 * @param {Object} deps
27 * @param {String} type
28 */
29function printWarnings (deps, type) {
30 if (!Object.keys(deps).length) return
31
32 var warnings = {
33 E404: {title: "Unregistered", list: []},
34 ESCM: {title: "SCM", list: []}
35 }
36
37 for (var name in deps) {
38 var dep = deps[name]
39
40 if (dep.warn) {
41 warnings[dep.warn.code].list.push([clc.magenta(name), clc.red(dep.warn.toString())])
42 }
43 }
44
45 Object.keys(warnings).forEach(function (warnType) {
46 var warnList = warnings[warnType].list
47
48 if (!warnList.length) return
49
50 var table = new Table({head: ["Name", "Message"], style: {head: ["reset"]}})
51
52 console.log(clc.underline(warnings[warnType].title + " " + (type ? type + "D" : "d") + "ependencies"))
53 console.log("")
54 warnList.forEach(function (row) { table.push(row) })
55 console.log(table.toString())
56 console.log("")
57 })
58}
59
60function printDeps (deps, type) {
61 if (!Object.keys(deps).length) return
62
63 var oneLine = ["npm install"]
64
65 if (type === "dev") {
66 oneLine.push("--save-dev")
67 } else if (type === "optional ") {
68 oneLine.push("--save-optional")
69 } else if (type === "global") {
70 oneLine.push("--global")
71 } else {
72 oneLine.push("--save")
73 }
74
75 if (type) {
76 console.log(clc.underline("%sDependencies"), type)
77 } else {
78 console.log(clc.underline("dependencies"))
79 }
80
81 var table = new Table({head: ["Name", "Package", "Latest"], style: {head: ["reset"]}})
82
83 for (var name in deps) {
84 var dep = deps[name]
85
86 if (dep.warn) {
87 continue
88 }
89
90 oneLine.push(name+"@"+dep[argv.unstable ? "latest" : "stable"])
91
92 table.push([
93 clc.magenta(name),
94 clc.red(dep.required),
95 clc.green(dep[argv.unstable ? "latest" : "stable"])
96 ])
97 }
98 console.log("")
99 console.log(table.toString())
100 console.log("")
101 console.log(oneLine.join(" "))
102 console.log("")
103
104 printWarnings(deps, type)
105}
106
107// Get a list of dependency filters
108var filterList = argv._.filter(function (v) {
109 return !(v === "update" || v === "u")
110})
111
112// Filter the passed deps (result from david) by the dependency names passed on the command line
113function filterDeps (deps) {
114 if (!filterList.length) return deps
115
116 return Object.keys(deps).reduce(function (filteredDeps, name) {
117 if (filterList.indexOf(name) !== -1) {
118 filteredDeps[name] = deps[name]
119 }
120 return filteredDeps
121 }, {})
122}
123
124// Get updated deps, devDeps and optionalDeps
125function getUpdatedDeps (pkg, cb) {
126 var opts = {
127 stable: !argv.unstable,
128 loose: true,
129 error: {
130 E404: argv.error404,
131 ESCM: argv.errorSCM
132 }
133 }
134
135 if (argv.registry) {
136 opts.npm = {registry: argv.registry}
137 }
138
139 david.getUpdatedDependencies(pkg, opts, function (er, deps) {
140 if (er) return cb(er)
141
142 david.getUpdatedDependencies(pkg, xtend(opts, {dev: true}), function (er, devDeps) {
143 if (er) return cb(er)
144
145 david.getUpdatedDependencies(pkg, xtend(opts, {optional: true}), function (er, optionalDeps) {
146 cb(er, filterDeps(deps), filterDeps(devDeps), filterDeps(optionalDeps))
147 })
148 })
149 })
150}
151
152/**
153 * Install the passed dependencies
154 *
155 * @param {Object} deps Dependencies to install (result from david)
156 * @param {Object} opts Install options
157 * @param {Boolean} [opts.global] Install globally
158 * @param {Boolean} [opts.save] Save installed dependencies to dependencies/devDependencies/optionalDependencies
159 * @param {Boolean} [opts.dev] Provided dependencies are dev dependencies
160 * @param {Boolean} [opts.optional] Provided dependencies are optional dependencies
161 * @param {String} [opts.registry] The npm registry URL to use
162 * @param {Function} cb Callback
163 */
164function installDeps (deps, opts, cb) {
165 opts = opts || {}
166
167 var depNames = Object.keys(deps)
168
169 // Nothing to install!
170 if (!depNames.length) {
171 return cb(null)
172 }
173
174 depNames = depNames.filter(function (depName) {
175 return !deps[depName].warn
176 })
177
178 npm.load({
179 registry: opts.registry,
180 global: opts.global
181 }, function (er) {
182 if (er) return cb(er)
183
184 if (opts.save) {
185 npm.config.set("save" + (opts.dev ? "-dev" : opts.optional ? "-optional" : ""), true)
186 }
187
188 var installArgs = depNames.map(function (depName) {
189 return depName + "@" + deps[depName][argv.unstable ? "latest" : "stable"]
190 })
191
192 npm.commands.install(installArgs, function (er) {
193 npm.config.set("save" + (opts.dev ? "-dev" : opts.optional ? "-optional" : ""), false)
194 cb(er)
195 })
196 })
197}
198
199if (argv.global) {
200 npm.load({registry: argv.registry, global: true}, function (er) {
201 if (er) {
202 console.error("Failed to load npm", er)
203 process.exit(1)
204 }
205
206 npm.commands.ls([], true, function (er, data) {
207 if (er) {
208 console.error("Failed to list global dependencies", er)
209 process.exit(1)
210 }
211
212 var pkg = {
213 name: "Global Dependencies",
214 dependencies: {}
215 }
216
217 for (var key in data.dependencies) {
218 pkg.dependencies[key] = data.dependencies[key].version
219 }
220
221 getUpdatedDeps(pkg, function (er, deps) {
222 if (er) {
223 console.error("Failed to get updated dependencies/devDependencies", er)
224 process.exit(1)
225 }
226
227 if (argv.update) {
228
229 installDeps(deps, {registry: argv.registry, global: true}, function (er) {
230 if (er) {
231 console.error("Failed to update global dependencies", er)
232 process.exit(1)
233 }
234
235 printWarnings(deps, "global")
236 })
237
238 } else {
239 printDeps(deps, "global")
240 }
241 })
242 })
243 })
244
245} else {
246 if (!fs.existsSync(packageFile)) {
247 console.error("package.json does not exist")
248 process.exit(1)
249 }
250
251 var pkg = require(cwd + "/package.json")
252
253 getUpdatedDeps(pkg, function (er, deps, devDeps, optionalDeps) {
254 if (er) {
255 console.error("Failed to get updated dependencies/devDependencies", er)
256 process.exit(1)
257 }
258
259 if (argv.update) {
260 var opts = {registry: argv.registry, save: true}
261
262 installDeps(deps, opts, function (er) {
263 if (er) {
264 console.error("Failed to update/save dependencies", er)
265 process.exit(1)
266 }
267
268 installDeps(devDeps, xtend(opts, {dev: true}), function (er) {
269 if (er) {
270 console.error("Failed to update/save devDependencies", er)
271 process.exit(1)
272 }
273
274 installDeps(optionalDeps, xtend(opts, {optional: true}), function (er) {
275 if (er) {
276 console.error("Failed to update/save optionalDependencies", er)
277 process.exit(1)
278 }
279
280 printWarnings(deps)
281 printWarnings(devDeps, "dev")
282 printWarnings(optionalDeps, "optional")
283 })
284 })
285 })
286
287 } else {
288 printDeps(deps)
289 printDeps(devDeps, "dev")
290 printDeps(optionalDeps, "optional")
291
292 if (Object.keys(deps).length || Object.keys(devDeps).length || Object.keys(optionalDeps).length) {
293 process.exit(1)
294 } else {
295 // Log feedback if all dependencies are up to date
296 console.log(clc.green("All dependencies up to date"))
297 }
298 }
299 })
300}