44f3d36f4ea98351e1b8dc91c3726d74b3717459
[platform/upstream/nodejs.git] / deps / npm / lib / config.js
1
2 module.exports = config
3
4 config.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
12 var ini = require("./utils/ini.js")
13   , log = require("npmlog")
14   , npm = require("./npm.js")
15   , exec = require("./utils/exec.js")
16   , fs = require("graceful-fs")
17   , dc
18   , output = require("./utils/output.js")
19   , types = require("./utils/config-defs.js").types
20
21 config.completion = function (opts, cb) {
22   var argv = opts.conf.argv.remain
23   if (argv[1] !== "config") argv.unshift("config")
24   if (argv.length === 2) {
25     var cmds = ["get", "set", "delete", "ls", "rm", "edit"]
26     if (opts.partialWord !== "l") cmds.push("list")
27     return cb(null, cmds)
28   }
29
30   var action = argv[2]
31   switch (action) {
32     case "set":
33       // todo: complete with valid values, if possible.
34       if (argv.length > 3) return cb(null, [])
35       // fallthrough
36     case "get":
37     case "delete":
38     case "rm":
39       return cb(null, Object.keys(types))
40     case "edit":
41     case "list": case "ls":
42       return cb(null, [])
43     default: return cb(null, [])
44   }
45 }
46
47 // npm config set key value
48 // npm config get key
49 // npm config list
50 function config (args, cb) {
51   var action = args.shift()
52   switch (action) {
53     case "set": return set(args[0], args[1], cb)
54     case "get": return get(args[0], cb)
55     case "delete": case "rm": case "del": return del(args[0], cb)
56     case "list": case "ls": return list(cb)
57     case "edit": return edit(cb)
58     default: return unknown(action, cb)
59   }
60 }
61
62 function edit (cb) {
63   var e = ini.get("editor")
64     , which = ini.get("global") ? "global" : "user"
65     , f = ini.get(which + "config")
66     , eol = process.platform === "win32" ? "\r\n" : "\n"
67   if (!e) return cb(new Error("No EDITOR config or environ set."))
68   ini.save(which, function (er) {
69     if (er) return cb(er)
70     fs.readFile(f, "utf8", function (er, data) {
71       if (er) data = ""
72       dc = dc || require("./utils/config-defs.js").defaults
73       data = [ ";;;;"
74              , "; npm "+(ini.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(dc).map(function (k) {
88                 return "; " + k + " = " + ini.unParseField(dc[k],k)
89               }))
90               .concat([""])
91               .join(eol)
92       fs.writeFile
93         ( f
94         , data
95         , "utf8"
96         , function (er) {
97             if (er) return cb(er)
98             exec(e, [f], function (er) {
99               if (er) return cb(er)
100               ini.resolveConfigs(function (er) {
101                 if (er) return cb(er)
102                 ini.save(which, cb)
103               })
104             })
105           }
106         )
107     })
108   })
109 }
110
111 function del (key, cb) {
112   if (!key) return cb(new Error("no key provided"))
113   ini.del(key)
114   ini.save(ini.get("global") ? "global" : "user", cb)
115 }
116
117 function set (key, val, cb) {
118   if (key === undefined) {
119     return unknown("", cb)
120   }
121   if (val === undefined) {
122     if (key.indexOf("=") !== -1) {
123       var k = key.split("=")
124       key = k.shift()
125       val = k.join("=")
126     } else {
127       val = ""
128     }
129   }
130   key = key.trim()
131   val = val.trim()
132   log.info("config", "set %j %j", key, val)
133   var where = ini.get("global") ? "global" : "user"
134   ini.set(key, val, where)
135   ini.save(where, cb)
136 }
137
138 function get (key, cb) {
139   if (!key) return list(cb)
140   if (key.charAt(0) === "_") {
141     return cb(new Error("---sekretz---"))
142   }
143   output.write(npm.config.get(key), cb)
144 }
145
146 function sort (a, b) {
147   return a > b ? 1 : -1
148 }
149
150 function reverse (a, b) {
151   return a > b ? -1 : 1
152 }
153
154 function list (cb) {
155   var msg = ""
156     , long = npm.config.get("long")
157
158   // cli configs.
159   // show any that aren't secret
160   var cli = ini.configList.list[ini.TRANS.cli]
161     , eol = process.platform === "win32" ? "\r\n" : "\n"
162     , cliKeys = Object.keys(cli).filter(function (k) {
163         return !(k.charAt(0) === "_" || types[k] !== types[k])
164       }).sort(function (a, b) {
165         return a > b ? 1 : -1
166       })
167   if (cliKeys.length) {
168     msg += "; cli configs" + eol
169     cliKeys.forEach(function (k) {
170       if (k === "argv") return
171       msg += k + " = " + JSON.stringify(cli[k]) + eol
172     })
173     msg += eol
174   }
175
176   // env configs
177   var env = ini.configList.list[ini.TRANS.env]
178     , envKeys = Object.keys(env).filter(function (k) {
179         return !(k.charAt(0) === "_" || types[k] !== types[k])
180       }).sort(function (a, b) {
181         return a > b ? 1 : -1
182       })
183   if (envKeys.length) {
184     msg += "; environment configs" + eol
185     envKeys.forEach(function (k) {
186       if (env[k] !== ini.get(k)) {
187         if (!long) return
188         msg += "; " + k + " = " + JSON.stringify(env[k])
189             + " (overridden)" + eol
190       } else msg += k + " = " + JSON.stringify(env[k]) + eol
191     })
192     msg += eol
193   }
194
195   // user config file
196   var uconf = ini.configList.list[ini.TRANS.user]
197     , uconfKeys = Object.keys(uconf).filter(function (k) {
198         return types[k] === types[k]
199       }).sort(function (a, b) {
200         return a > b ? 1 : -1
201       })
202   if (uconfKeys.length) {
203     msg += "; userconfig " + ini.get("userconfig") + eol
204     uconfKeys.forEach(function (k) {
205       var val = (k.charAt(0) === "_")
206               ? "---sekretz---"
207               : JSON.stringify(uconf[k])
208       if (uconf[k] !== ini.get(k)) {
209         if (!long) return
210         msg += "; " + k + " = " + val
211             + " (overridden)" + eol
212       } else msg += k + " = " + val + eol
213     })
214     msg += eol
215   }
216
217   // global config file
218   var gconf = ini.configList.list[ini.TRANS.global]
219     , gconfKeys = Object.keys(gconf).filter(function (k) {
220         return types[k] === types[k]
221       }).sort(function (a, b) {
222         return a > b ? 1 : -1
223       })
224   if (gconfKeys.length) {
225     msg += "; globalconfig " + ini.get("globalconfig") + eol
226     gconfKeys.forEach(function (k) {
227       var val = (k.charAt(0) === "_")
228               ? "---sekretz---"
229               : JSON.stringify(gconf[k])
230       if (gconf[k] !== ini.get(k)) {
231         if (!long) return
232         msg += "; " + k + " = " + val
233             + " (overridden)" + eol
234       } else msg += k + " = " + val + eol
235     })
236     msg += eol
237   }
238
239   // builtin config file
240   var bconf = ini.configList.list[ini.TRANS.builtin]
241     , bconfKeys = Object.keys(bconf).filter(function (k) {
242         return types[k] === types[k]
243       }).sort(function (a, b) {
244         return a > b ? 1 : -1
245       })
246   if (bconfKeys.length) {
247     var path = require("path")
248     msg += "; builtin config " + path.resolve(__dirname, "../npmrc") + eol
249     bconfKeys.forEach(function (k) {
250       var val = (k.charAt(0) === "_")
251               ? "---sekretz---"
252               : JSON.stringify(bconf[k])
253       if (bconf[k] !== ini.get(k)) {
254         if (!long) return
255         msg += "; " + k + " = " + val
256             + " (overridden)" + eol
257       } else msg += k + " = " + val + eol
258     })
259     msg += eol
260   }
261
262   // only show defaults if --long
263   if (!long) {
264     msg += "; node install prefix = " + process.installPrefix + eol
265          + "; node bin location = " + process.execPath + eol
266          + "; cwd = " + process.cwd() + eol
267          + "; HOME = " + process.env.HOME + eol
268          + "; 'npm config ls -l' to show all defaults." + eol
269
270     return output.write(msg, cb)
271   }
272
273   var defaults = ini.defaultConfig
274     , defKeys = Object.keys(defaults)
275   msg += "; default values" + eol
276   defKeys.forEach(function (k) {
277     var val = JSON.stringify(defaults[k])
278     if (defaults[k] !== ini.get(k)) {
279       if (!long) return
280       msg += "; " + k + " = " + val
281           + " (overridden)" + eol
282     } else msg += k + " = " + val + eol
283   })
284   msg += eol
285
286   return output.write(msg, cb)
287 }
288
289 function unknown (action, cb) {
290   cb("Usage:\n" + config.usage)
291 }