1 | #!/usr/bin/env node
|
2 |
|
3 | var 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 |
|
13 | if (argv.usage || argv.help || argv.h) {
|
14 | return console.log(fs.readFileSync(__dirname + "/usage.txt", "utf8"))
|
15 | }
|
16 |
|
17 | if (argv.version || argv.v) {
|
18 | return console.log("v" + require("../package.json").version)
|
19 | }
|
20 |
|
21 | argv.update = argv._.indexOf("update") > -1 || argv._.indexOf("u") > -1
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 | function 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 |
|
60 | function 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 |
|
108 | var filterList = argv._.filter(function (v) {
|
109 | return !(v === "update" || v === "u")
|
110 | })
|
111 |
|
112 |
|
113 | function 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 |
|
125 | function 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 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 | function installDeps (deps, opts, cb) {
|
165 | opts = opts || {}
|
166 |
|
167 | var depNames = Object.keys(deps)
|
168 |
|
169 |
|
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 |
|
199 | if (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 |
|
296 | console.log(clc.green("All dependencies up to date"))
|
297 | }
|
298 | }
|
299 | })
|
300 | }
|