Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / yargs / lib / usage.js
1 // this file handles outputting usage instructions,
2 // failures, etc. keeps logging in one place.
3 var cliui = require('cliui'),
4   decamelize = require('decamelize'),
5   wsize = require('window-size')
6
7 module.exports = function (yargs) {
8   var self = {}
9
10   // methods for ouputting/building failure message.
11   var fails = []
12   self.failFn = function (f) {
13     fails.push(f)
14   }
15
16   var failMessage = null
17   var showHelpOnFail = true
18   self.showHelpOnFail = function (enabled, message) {
19     if (typeof enabled === 'string') {
20       message = enabled
21       enabled = true
22     } else if (typeof enabled === 'undefined') {
23       enabled = true
24     }
25     failMessage = message
26     showHelpOnFail = enabled
27     return self
28   }
29
30   self.fail = function (msg) {
31     if (fails.length) {
32       fails.forEach(function (f) {
33         f(msg)
34       })
35     } else {
36       if (showHelpOnFail) yargs.showHelp('error')
37       if (msg) console.error(msg)
38       if (failMessage) {
39         if (msg) console.error('')
40         console.error(failMessage)
41       }
42       if (yargs.getExitProcess()) {
43         process.exit(1)
44       } else {
45         throw new Error(msg)
46       }
47     }
48   }
49
50   // methods for ouputting/building help (usage) message.
51   var usage
52   self.usage = function (msg) {
53     usage = msg
54   }
55
56   var examples = []
57   self.example = function (cmd, description) {
58     examples.push([cmd, description || ''])
59   }
60
61   var commands = []
62   self.command = function (cmd, description) {
63     commands.push([cmd, description || ''])
64   }
65   self.getCommands = function () {
66     return commands
67   }
68
69   var descriptions = {}
70   self.describe = function (key, desc) {
71     if (typeof key === 'object') {
72       Object.keys(key).forEach(function (k) {
73         self.describe(k, key[k])
74       })
75     } else {
76       descriptions[key] = desc
77     }
78   }
79   self.getDescriptions = function () {
80     return descriptions
81   }
82
83   var epilog
84   self.epilog = function (msg) {
85     epilog = msg
86   }
87
88   var wrap = windowWidth()
89   self.wrap = function (cols) {
90     wrap = cols
91   }
92
93   self.help = function () {
94     normalizeAliases()
95
96     var demanded = yargs.getDemanded(),
97       options = yargs.getOptions(),
98       keys = Object.keys(
99         Object.keys(descriptions)
100         .concat(Object.keys(demanded))
101         .concat(Object.keys(options.default))
102         .reduce(function (acc, key) {
103           if (key !== '_') acc[key] = true
104           return acc
105         }, {})
106       ),
107       ui = cliui({
108         width: wrap,
109         wrap: !!wrap
110       })
111
112     // the usage string.
113     if (usage) {
114       var u = usage.replace(/\$0/g, yargs.$0)
115       ui.div(u + '\n')
116     }
117
118     // your application's commands, i.e., non-option
119     // arguments populated in '_'.
120     if (commands.length) {
121       ui.div('Commands:')
122
123       commands.forEach(function (command) {
124         ui.div(
125           {text: command[0], padding: [0, 2, 0, 2], width: maxWidth(commands) + 4},
126           {text: command[1]}
127         )
128       })
129
130       ui.div()
131     }
132
133     // the options table.
134     var aliasKeys = (Object.keys(options.alias) || [])
135       .concat(Object.keys(yargs.parsed.newAliases) || [])
136
137     keys = keys.filter(function (key) {
138       return !yargs.parsed.newAliases[key] && aliasKeys.every(function (alias) {
139         return (options.alias[alias] || []).indexOf(key) === -1
140       })
141     })
142
143     var switches = keys.reduce(function (acc, key) {
144       acc[key] = [ key ].concat(options.alias[key] || [])
145       .map(function (sw) {
146         return (sw.length > 1 ? '--' : '-') + sw
147       })
148       .join(', ')
149
150       return acc
151     }, {})
152
153     if (keys.length) {
154       ui.div('Options:')
155
156       keys.forEach(function (key) {
157         var kswitch = switches[key]
158         var desc = descriptions[key] || ''
159         var type = null
160
161         if (~options.boolean.indexOf(key)) type = '[boolean]'
162         if (~options.count.indexOf(key)) type = '[count]'
163         if (~options.string.indexOf(key)) type = '[string]'
164         if (~options.normalize.indexOf(key)) type = '[string]'
165         if (~options.array.indexOf(key)) type = '[array]'
166
167         var extra = [
168             type,
169             demanded[key] ? '[required]' : null,
170             defaultString(options.default[key], options.defaultDescription[key])
171           ].filter(Boolean).join(' ')
172
173         ui.span(
174           {text: kswitch, padding: [0, 2, 0, 2], width: maxWidth(switches) + 4},
175           desc
176         )
177
178         if (extra) ui.div({text: extra, padding: [0, 0, 0, 2], align: 'right'})
179         else ui.div()
180       })
181
182       ui.div()
183     }
184
185     // describe some common use-cases for your application.
186     if (examples.length) {
187       ui.div('Examples:')
188
189       examples.forEach(function (example) {
190         example[0] = example[0].replace(/\$0/g, yargs.$0)
191       })
192
193       examples.forEach(function (example) {
194         ui.div(
195           {text: example[0], padding: [0, 2, 0, 2], width: maxWidth(examples) + 4},
196           example[1]
197         )
198       })
199
200       ui.div()
201     }
202
203     // the usage string.
204     if (epilog) {
205       var e = epilog.replace(/\$0/g, yargs.$0)
206       ui.div(e + '\n')
207     }
208
209     return ui.toString()
210   }
211
212   // return the maximum width of a string
213   // in the left-hand column of a table.
214   function maxWidth (table) {
215     var width = 0
216
217     // table might be of the form [leftColumn],
218     // or {key: leftColumn}}
219     if (!Array.isArray(table)) {
220       table = Object.keys(table).map(function (key) {
221         return [table[key]]
222       })
223     }
224
225     table.forEach(function (v) {
226       width = Math.max(v[0].length, width)
227     })
228
229     // if we've enabled 'wrap' we should limit
230     // the max-width of the left-column.
231     if (wrap) width = Math.min(width, parseInt(wrap * 0.5, 10))
232
233     return width
234   }
235
236   // make sure any options set for aliases,
237   // are copied to the keys being aliased.
238   function normalizeAliases () {
239     var options = yargs.getOptions(),
240     demanded = yargs.getDemanded()
241
242     ;(Object.keys(options.alias) || []).forEach(function (key) {
243       options.alias[key].forEach(function (alias) {
244         // copy descriptions.
245         if (descriptions[alias]) self.describe(key, descriptions[alias])
246         // copy demanded.
247         if (demanded[alias]) yargs.demand(key, demanded[alias].msg)
248
249         // type messages.
250         if (~options.boolean.indexOf(alias)) yargs.boolean(key)
251         if (~options.count.indexOf(alias)) yargs.count(key)
252         if (~options.string.indexOf(alias)) yargs.string(key)
253         if (~options.normalize.indexOf(alias)) yargs.normalize(key)
254         if (~options.array.indexOf(alias)) yargs.array(key)
255       })
256     })
257   }
258
259   self.showHelp = function (level) {
260     level = level || 'error'
261     console[level](self.help())
262   }
263
264   self.functionDescription = function (fn, defaultDescription) {
265     if (defaultDescription) {
266       return defaultDescription
267     }
268     var description = fn.name ? decamelize(fn.name, '-') : 'generated-value'
269     return ['(', description, ')'].join('')
270   }
271
272   // format the default-value-string displayed in
273   // the right-hand column.
274   function defaultString (value, defaultDescription) {
275     var string = '[default: '
276
277     if (value === undefined) return null
278
279     if (defaultDescription) {
280       string += defaultDescription
281     } else {
282       switch (typeof value) {
283         case 'string':
284           string += JSON.stringify(value)
285           break
286         case 'object':
287           string += JSON.stringify(value)
288           break
289         default:
290           string += value
291       }
292     }
293
294     return string + ']'
295   }
296
297   // guess the width of the console window, max-width 80.
298   function windowWidth () {
299     return wsize.width ? Math.min(80, wsize.width) : null
300   }
301
302   // logic for displaying application version.
303   var version = null
304   self.version = function (ver, opt, msg) {
305     version = ver
306   }
307
308   self.showVersion = function () {
309     if (typeof version === 'function') console.log(version())
310     else console.log(version)
311   }
312
313   return self
314 }