UNPKG

8.65 kBJavaScriptView Raw
1
2module.exports = config
3
4config.usage = "npm config set <key> <value>"
5 + "\nnpm config get [<key>]"
6 + "\nnpm config delete <key>"
7 + "\nnpm config list"
8 + "\nnpm config edit"
9 + "\nnpm set <key> <value>"
10 + "\nnpm get [<key>]"
11
12var log = require("npmlog")
13 , npm = require("./npm.js")
14 , npmconf = require("./config/core.js")
15 , fs = require("graceful-fs")
16 , writeFileAtomic = require("write-file-atomic")
17 , types = npmconf.defs.types
18 , ini = require("ini")
19 , editor = require("editor")
20 , os = require("os")
21 , umask = require("./utils/umask")
22
23config.completion = function (opts, cb) {
24 var argv = opts.conf.argv.remain
25 if (argv[1] !== "config") argv.unshift("config")
26 if (argv.length === 2) {
27 var cmds = ["get", "set", "delete", "ls", "rm", "edit"]
28 if (opts.partialWord !== "l") cmds.push("list")
29 return cb(null, cmds)
30 }
31
32 var action = argv[2]
33 switch (action) {
34 case "set":
35 // todo: complete with valid values, if possible.
36 if (argv.length > 3) return cb(null, [])
37 // fallthrough
38 case "get":
39 case "delete":
40 case "rm":
41 return cb(null, Object.keys(types))
42 case "edit":
43 case "list": case "ls":
44 return cb(null, [])
45 default: return cb(null, [])
46 }
47}
48
49// npm config set key value
50// npm config get key
51// npm config list
52function config (args, cb) {
53 var action = args.shift()
54 switch (action) {
55 case "set": return set(args[0], args[1], cb)
56 case "get": return get(args[0], cb)
57 case "delete": case "rm": case "del": return del(args[0], cb)
58 case "list": case "ls": return list(cb)
59 case "edit": return edit(cb)
60 default: return unknown(action, cb)
61 }
62}
63
64function edit (cb) {
65 var e = npm.config.get("editor")
66 , which = npm.config.get("global") ? "global" : "user"
67 , f = npm.config.get(which + "config")
68 if (!e) return cb(new Error("No EDITOR config or environ set."))
69 npm.config.save(which, function (er) {
70 if (er) return cb(er)
71 fs.readFile(f, "utf8", function (er, data) {
72 if (er) data = ""
73 data = [ ";;;;"
74 , "; npm "+(npm.config.get("global") ?
75 "globalconfig" : "userconfig")+" file"
76 , "; this is a simple ini-formatted file"
77 , "; lines that start with semi-colons are comments."
78 , "; read `npm help config` for help on the various options"
79 , ";;;;"
80 , ""
81 , data
82 ].concat( [ ";;;;"
83 , "; all options with default values"
84 , ";;;;"
85 ]
86 )
87 .concat(Object.keys(npmconf.defaults).reduce(function (arr, key) {
88 var obj = {}
89 obj[key] = npmconf.defaults[key]
90 if (key === "logstream") return arr
91 return arr.concat(
92 ini.stringify(obj)
93 .replace(/\n$/m, "")
94 .replace(/^/g, "; ")
95 .replace(/\n/g, "\n; ")
96 .split("\n"))
97 }, []))
98 .concat([""])
99 .join(os.EOL)
100 writeFileAtomic
101 ( f
102 , data
103 , function (er) {
104 if (er) return cb(er)
105 editor(f, { editor: e }, cb)
106 }
107 )
108 })
109 })
110}
111
112function del (key, cb) {
113 if (!key) return cb(new Error("no key provided"))
114 var where = npm.config.get("global") ? "global" : "user"
115 npm.config.del(key, (where === 'user' && npm.config.get('registry', 'cli')) ? 'user-reg' : where)
116 npm.config.save(where, cb)
117}
118
119function set (key, val, cb) {
120 if (key === undefined) {
121 return unknown("", cb)
122 }
123 if (val === undefined) {
124 if (key.indexOf("=") !== -1) {
125 var k = key.split("=")
126 key = k.shift()
127 val = k.join("=")
128 } else {
129 val = ""
130 }
131 }
132 key = key.trim()
133 val = val.trim()
134 log.info("config", "set %j %j", key, val)
135 var where = npm.config.get("global") ? "global" : "user"
136 if (key.match(/umask/)) val = umask.fromString(val)
137 npm.config.set(key, val, where)
138 npm.config.save(where, cb)
139}
140
141function get (key, cb) {
142 if (!key) return list(cb)
143 if (!public(key)) {
144 return cb(new Error("---sekretz---"))
145 }
146 var val = npm.config.get(key)
147 if (key.match(/umask/)) val = umask.toString(val)
148 console.log(val)
149 cb()
150}
151
152function sort (a, b) {
153 return a > b ? 1 : -1
154}
155
156function public (k) {
157 return !(k.charAt(0) === "_" ||
158 k.indexOf(":_") !== -1 ||
159 types[k] !== types[k])
160}
161
162function getKeys (data) {
163 return Object.keys(data).filter(public).sort(sort)
164}
165
166function list (cb) {
167 var msg = ""
168 , long = npm.config.get("long")
169
170 var cli = npm.config.sources.cli.data
171 , cliKeys = getKeys(cli)
172 if (cliKeys.length) {
173 msg += "; cli configs\n"
174 cliKeys.forEach(function (k) {
175 if (cli[k] && typeof cli[k] === "object") return
176 if (k === "argv") return
177 msg += k + " = " + JSON.stringify(cli[k]) + "\n"
178 })
179 msg += "\n"
180 }
181
182 // env configs
183 var env = npm.config.sources.env.data
184 , envKeys = getKeys(env)
185 if (envKeys.length) {
186 msg += "; environment configs\n"
187 envKeys.forEach(function (k) {
188 if (env[k] !== npm.config.get(k)) {
189 if (!long) return
190 msg += "; " + k + " = " + JSON.stringify(env[k])
191 + " (overridden)\n"
192 } else msg += k + " = " + JSON.stringify(env[k]) + "\n"
193 })
194 msg += "\n"
195 }
196
197 // registry overrides
198 var uconf = npm.config.sources['user-reg'].data
199 , uconfKeys = getKeys(uconf)
200 if (uconfKeys.length) {
201 msg += "; userconfig.registry " + npm.config.get('registry') + "\n"
202 uconfKeys.forEach(function (k) {
203 var val = (k.charAt(0) === "_")
204 ? "---sekretz---"
205 : JSON.stringify(uconf[k])
206 if (uconf[k] !== npm.config.get(k)) {
207 if (!long) return
208 msg += "; " + k + " = " + val
209 + " (overridden)\n"
210 } else msg += k + " = " + val + "\n"
211 })
212 msg += "\n"
213 }
214
215 // user config file
216 var uconf = npm.config.sources.user.data
217 , uconfKeys = getKeys(uconf)
218 if (uconfKeys.length) {
219 msg += "; userconfig " + npm.config.get("userconfig") + "\n"
220 uconfKeys.forEach(function (k) {
221 var val = (k.charAt(0) === "_")
222 ? "---sekretz---"
223 : JSON.stringify(uconf[k])
224 if (uconf[k] !== npm.config.get(k)) {
225 if (!long) return
226 msg += "; " + k + " = " + val
227 + " (overridden)\n"
228 } else msg += k + " = " + val + "\n"
229 })
230 msg += "\n"
231 }
232
233 // global config file
234 var gconf = npm.config.sources.global.data
235 , gconfKeys = getKeys(gconf)
236 if (gconfKeys.length) {
237 msg += "; globalconfig " + npm.config.get("globalconfig") + "\n"
238 gconfKeys.forEach(function (k) {
239 var val = (k.charAt(0) === "_")
240 ? "---sekretz---"
241 : JSON.stringify(gconf[k])
242 if (gconf[k] !== npm.config.get(k)) {
243 if (!long) return
244 msg += "; " + k + " = " + val
245 + " (overridden)\n"
246 } else msg += k + " = " + val + "\n"
247 })
248 msg += "\n"
249 }
250
251 // builtin config file
252 var builtin = npm.config.sources.builtin || {}
253 if (builtin && builtin.data) {
254 var bconf = builtin.data
255 , bpath = builtin.path
256 , bconfKeys = getKeys(bconf)
257 if (bconfKeys.length) {
258 msg += "; builtin config " + bpath + "\n"
259 bconfKeys.forEach(function (k) {
260 var val = (k.charAt(0) === "_")
261 ? "---sekretz---"
262 : JSON.stringify(bconf[k])
263 if (bconf[k] !== npm.config.get(k)) {
264 if (!long) return
265 msg += "; " + k + " = " + val
266 + " (overridden)\n"
267 } else msg += k + " = " + val + "\n"
268 })
269 msg += "\n"
270 }
271 }
272
273 // only show defaults if --long
274 if (!long) {
275 msg += "; node bin location = " + process.execPath + "\n"
276 + "; cwd = " + process.cwd() + "\n"
277 + "; HOME = " + process.env.HOME + "\n"
278 + "; 'npm config ls -l' to show all defaults.\n"
279
280 console.log(msg)
281 return cb()
282 }
283
284 var defaults = npmconf.defaults
285 , defKeys = getKeys(defaults)
286 msg += "; default values\n"
287 defKeys.forEach(function (k) {
288 if (defaults[k] && typeof defaults[k] === "object") return
289 var val = JSON.stringify(defaults[k])
290 if (defaults[k] !== npm.config.get(k)) {
291 msg += "; " + k + " = " + val
292 + " (overridden)\n"
293 } else msg += k + " = " + val + "\n"
294 })
295 msg += "\n"
296
297 console.log(msg)
298 return cb()
299}
300
301function unknown (action, cb) {
302 cb("Usage:\n" + config.usage)
303}