"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/yargs/lib/usage.js" (8 Mar 2017, 10522 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // this file handles outputting usage instructions,
    2 // failures, etc. keeps logging in one place.
    3 var cliui = require('cliui')
    4 var decamelize = require('decamelize')
    5 var stringWidth = require('string-width')
    6 var wsize = require('window-size')
    7 
    8 module.exports = function (yargs, y18n) {
    9   var __ = y18n.__
   10   var self = {}
   11 
   12   // methods for ouputting/building failure message.
   13   var fails = []
   14   self.failFn = function (f) {
   15     fails.push(f)
   16   }
   17 
   18   var failMessage = null
   19   var showHelpOnFail = true
   20   self.showHelpOnFail = function (enabled, message) {
   21     if (typeof enabled === 'string') {
   22       message = enabled
   23       enabled = true
   24     } else if (typeof enabled === 'undefined') {
   25       enabled = true
   26     }
   27     failMessage = message
   28     showHelpOnFail = enabled
   29     return self
   30   }
   31 
   32   var failureOutput = false
   33   self.fail = function (msg) {
   34     if (fails.length) {
   35       fails.forEach(function (f) {
   36         f(msg)
   37       })
   38     } else {
   39       // don't output failure message more than once
   40       if (!failureOutput) {
   41         failureOutput = true
   42         if (showHelpOnFail) yargs.showHelp('error')
   43         if (msg) console.error(msg)
   44         if (failMessage) {
   45           if (msg) console.error('')
   46           console.error(failMessage)
   47         }
   48       }
   49       if (yargs.getExitProcess()) {
   50         process.exit(1)
   51       } else {
   52         throw new Error(msg)
   53       }
   54     }
   55   }
   56 
   57   // methods for ouputting/building help (usage) message.
   58   var usage
   59   self.usage = function (msg) {
   60     usage = msg
   61   }
   62 
   63   var examples = []
   64   self.example = function (cmd, description) {
   65     examples.push([cmd, description || ''])
   66   }
   67 
   68   var commands = []
   69   self.command = function (cmd, description) {
   70     commands.push([cmd, description || ''])
   71   }
   72   self.getCommands = function () {
   73     return commands
   74   }
   75 
   76   var descriptions = {}
   77   self.describe = function (key, desc) {
   78     if (typeof key === 'object') {
   79       Object.keys(key).forEach(function (k) {
   80         self.describe(k, key[k])
   81       })
   82     } else {
   83       descriptions[key] = desc
   84     }
   85   }
   86   self.getDescriptions = function () {
   87     return descriptions
   88   }
   89 
   90   var epilog
   91   self.epilog = function (msg) {
   92     epilog = msg
   93   }
   94 
   95   var wrap = windowWidth()
   96   self.wrap = function (cols) {
   97     wrap = cols
   98   }
   99 
  100   var deferY18nLookupPrefix = '__yargsString__:'
  101   self.deferY18nLookup = function (str) {
  102     return deferY18nLookupPrefix + str
  103   }
  104 
  105   var defaultGroup = 'Options:'
  106   self.help = function () {
  107     normalizeAliases()
  108 
  109     var demanded = yargs.getDemanded()
  110     var groups = yargs.getGroups()
  111     var options = yargs.getOptions()
  112     var keys = Object.keys(
  113       Object.keys(descriptions)
  114       .concat(Object.keys(demanded))
  115       .concat(Object.keys(options.default))
  116       .reduce(function (acc, key) {
  117         if (key !== '_') acc[key] = true
  118         return acc
  119       }, {})
  120     )
  121     var ui = cliui({
  122       width: wrap,
  123       wrap: !!wrap
  124     })
  125 
  126     // the usage string.
  127     if (usage) {
  128       var u = usage.replace(/\$0/g, yargs.$0)
  129       ui.div(u + '\n')
  130     }
  131 
  132     // your application's commands, i.e., non-option
  133     // arguments populated in '_'.
  134     if (commands.length) {
  135       ui.div(__('Commands:'))
  136 
  137       commands.forEach(function (command) {
  138         ui.div(
  139           {text: command[0], padding: [0, 2, 0, 2], width: maxWidth(commands) + 4},
  140           {text: command[1]}
  141         )
  142       })
  143 
  144       ui.div()
  145     }
  146 
  147     // perform some cleanup on the keys array, making it
  148     // only include top-level keys not their aliases.
  149     var aliasKeys = (Object.keys(options.alias) || [])
  150       .concat(Object.keys(yargs.parsed.newAliases) || [])
  151 
  152     keys = keys.filter(function (key) {
  153       return !yargs.parsed.newAliases[key] && aliasKeys.every(function (alias) {
  154         return (options.alias[alias] || []).indexOf(key) === -1
  155       })
  156     })
  157 
  158     // populate 'Options:' group with any keys that have not
  159     // explicitly had a group set.
  160     if (!groups[defaultGroup]) groups[defaultGroup] = []
  161     addUngroupedKeys(keys, options.alias, groups)
  162 
  163     // display 'Options:' table along with any custom tables:
  164     Object.keys(groups).forEach(function (groupName) {
  165       if (!groups[groupName].length) return
  166 
  167       ui.div(__(groupName))
  168 
  169       // if we've grouped the key 'f', but 'f' aliases 'foobar',
  170       // normalizedKeys should contain only 'foobar'.
  171       var normalizedKeys = groups[groupName].map(function (key) {
  172         if (~aliasKeys.indexOf(key)) return key
  173         for (var i = 0, aliasKey; (aliasKey = aliasKeys[i]) !== undefined; i++) {
  174           if (~(options.alias[aliasKey] || []).indexOf(key)) return aliasKey
  175         }
  176         return key
  177       })
  178 
  179       // actually generate the switches string --foo, -f, --bar.
  180       var switches = normalizedKeys.reduce(function (acc, key) {
  181         acc[key] = [ key ].concat(options.alias[key] || [])
  182           .map(function (sw) {
  183             return (sw.length > 1 ? '--' : '-') + sw
  184           })
  185           .join(', ')
  186 
  187         return acc
  188       }, {})
  189 
  190       normalizedKeys.forEach(function (key) {
  191         var kswitch = switches[key]
  192         var desc = descriptions[key] || ''
  193         var type = null
  194 
  195         if (~desc.lastIndexOf(deferY18nLookupPrefix)) desc = __(desc.substring(deferY18nLookupPrefix.length))
  196 
  197         if (~options.boolean.indexOf(key)) type = '[' + __('boolean') + ']'
  198         if (~options.count.indexOf(key)) type = '[' + __('count') + ']'
  199         if (~options.string.indexOf(key)) type = '[' + __('string') + ']'
  200         if (~options.normalize.indexOf(key)) type = '[' + __('string') + ']'
  201         if (~options.array.indexOf(key)) type = '[' + __('array') + ']'
  202 
  203         var extra = [
  204           type,
  205           demanded[key] ? '[' + __('required') + ']' : null,
  206           options.choices && options.choices[key] ? '[' + __('choices:') + ' ' +
  207             self.stringifiedValues(options.choices[key]) + ']' : null,
  208           defaultString(options.default[key], options.defaultDescription[key])
  209         ].filter(Boolean).join(' ')
  210 
  211         ui.span(
  212           {text: kswitch, padding: [0, 2, 0, 2], width: maxWidth(switches) + 4},
  213           desc
  214         )
  215 
  216         if (extra) ui.div({text: extra, padding: [0, 0, 0, 2], align: 'right'})
  217         else ui.div()
  218       })
  219 
  220       ui.div()
  221     })
  222 
  223     // describe some common use-cases for your application.
  224     if (examples.length) {
  225       ui.div(__('Examples:'))
  226 
  227       examples.forEach(function (example) {
  228         example[0] = example[0].replace(/\$0/g, yargs.$0)
  229       })
  230 
  231       examples.forEach(function (example) {
  232         ui.div(
  233           {text: example[0], padding: [0, 2, 0, 2], width: maxWidth(examples) + 4},
  234           example[1]
  235         )
  236       })
  237 
  238       ui.div()
  239     }
  240 
  241     // the usage string.
  242     if (epilog) {
  243       var e = epilog.replace(/\$0/g, yargs.$0)
  244       ui.div(e + '\n')
  245     }
  246 
  247     return ui.toString()
  248   }
  249 
  250   // return the maximum width of a string
  251   // in the left-hand column of a table.
  252   function maxWidth (table) {
  253     var width = 0
  254 
  255     // table might be of the form [leftColumn],
  256     // or {key: leftColumn}}
  257     if (!Array.isArray(table)) {
  258       table = Object.keys(table).map(function (key) {
  259         return [table[key]]
  260       })
  261     }
  262 
  263     table.forEach(function (v) {
  264       width = Math.max(stringWidth(v[0]), width)
  265     })
  266 
  267     // if we've enabled 'wrap' we should limit
  268     // the max-width of the left-column.
  269     if (wrap) width = Math.min(width, parseInt(wrap * 0.5, 10))
  270 
  271     return width
  272   }
  273 
  274   // make sure any options set for aliases,
  275   // are copied to the keys being aliased.
  276   function normalizeAliases () {
  277     var demanded = yargs.getDemanded()
  278     var options = yargs.getOptions()
  279 
  280     ;(Object.keys(options.alias) || []).forEach(function (key) {
  281       options.alias[key].forEach(function (alias) {
  282         // copy descriptions.
  283         if (descriptions[alias]) self.describe(key, descriptions[alias])
  284         // copy demanded.
  285         if (demanded[alias]) yargs.demand(key, demanded[alias].msg)
  286         // type messages.
  287         if (~options.boolean.indexOf(alias)) yargs.boolean(key)
  288         if (~options.count.indexOf(alias)) yargs.count(key)
  289         if (~options.string.indexOf(alias)) yargs.string(key)
  290         if (~options.normalize.indexOf(alias)) yargs.normalize(key)
  291         if (~options.array.indexOf(alias)) yargs.array(key)
  292       })
  293     })
  294   }
  295 
  296   // given a set of keys, place any keys that are
  297   // ungrouped under the 'Options:' grouping.
  298   function addUngroupedKeys (keys, aliases, groups) {
  299     var groupedKeys = []
  300     var toCheck = null
  301     Object.keys(groups).forEach(function (group) {
  302       groupedKeys = groupedKeys.concat(groups[group])
  303     })
  304 
  305     keys.forEach(function (key) {
  306       toCheck = [key].concat(aliases[key])
  307       if (!toCheck.some(function (k) {
  308         return groupedKeys.indexOf(k) !== -1
  309       })) {
  310         groups[defaultGroup].push(key)
  311       }
  312     })
  313     return groupedKeys
  314   }
  315 
  316   self.showHelp = function (level) {
  317     level = level || 'error'
  318     console[level](self.help())
  319   }
  320 
  321   self.functionDescription = function (fn) {
  322     var description = fn.name ? decamelize(fn.name, '-') : __('generated-value')
  323     return ['(', description, ')'].join('')
  324   }
  325 
  326   self.stringifiedValues = function (values, separator) {
  327     var string = ''
  328     var sep = separator || ', '
  329     var array = [].concat(values)
  330 
  331     if (!values || !array.length) return string
  332 
  333     array.forEach(function (value) {
  334       if (string.length) string += sep
  335       string += JSON.stringify(value)
  336     })
  337 
  338     return string
  339   }
  340 
  341   // format the default-value-string displayed in
  342   // the right-hand column.
  343   function defaultString (value, defaultDescription) {
  344     var string = '[' + __('default:') + ' '
  345 
  346     if (value === undefined && !defaultDescription) return null
  347 
  348     if (defaultDescription) {
  349       string += defaultDescription
  350     } else {
  351       switch (typeof value) {
  352         case 'string':
  353           string += JSON.stringify(value)
  354           break
  355         case 'object':
  356           string += JSON.stringify(value)
  357           break
  358         default:
  359           string += value
  360       }
  361     }
  362 
  363     return string + ']'
  364   }
  365 
  366   // guess the width of the console window, max-width 80.
  367   function windowWidth () {
  368     return wsize.width ? Math.min(80, wsize.width) : null
  369   }
  370 
  371   // logic for displaying application version.
  372   var version = null
  373   self.version = function (ver, opt, msg) {
  374     version = ver
  375   }
  376 
  377   self.showVersion = function () {
  378     if (typeof version === 'function') console.log(version())
  379     else console.log(version)
  380   }
  381 
  382   return self
  383 }