Back to Coffeescript

optparse.coffee

docs/v1/annotated-source/optparse.html

2.7.04.4 KB
Original Source

browser.coffeecake.coffeecoffee-script.coffeecommand.coffeegrammar.coffeehelpers.coffeeindex.coffeelexer.coffeenodes.coffeeoptparse.coffeeregister.coffeerepl.coffeerewriter.coffeescope.litcoffeesourcemap.litcoffee

optparse.coffee

{repeat} =require'./helpers'

A simple OptionParser class to parse option flags from the command-line. Use it like so:

parser = new OptionParser switches, helpBanner
options = parser.parse process.argv

The first non-option is considered to be the start of the file (and file option) list, and all subsequent arguments are left unparsed.

exports.OptionParser =class OptionParser

Initialize with a list of valid options, in the form:

[short-flag, long-flag, description]

Along with an optional banner for the usage help.

constructor:(rules, @banner) -\>@rules = buildRules rules

Parse the list of arguments, populating an options object with all of the specified options, and return it. Options after the first non-option argument are treated as arguments. options.arguments will be an array containing the remaining arguments. This is a simpler API than many option parsers that allow you to attach callback actions for every flag. Instead, you’re responsible for interpreting the options object.

parse:(args) -\>options = arguments: []
    skippingArgument =nooriginalArgs = args
    args = normalizeArguments argsforarg, iinargsifskippingArgument
        skippingArgument =nocontinueifargis'--'pos = originalArgs.indexOf'--'options.arguments = options.arguments.concat originalArgs[(pos +1)..]breakisOption = !!(arg.match(LONG_FLAG)orarg.match(SHORT_FLAG))

the CS option parser is a little odd; options after the first non-option argument are treated as non-option arguments themselves

seenNonOptionArg = options.arguments.length >0unlessseenNonOptionArg
        matchedRule [email protected]
            value =trueifrule.hasArgument
              skippingArgument =yesvalue = args[i +1]
            options[rule.name] =ifrule.isListthen(options[rule.name]or[]).concat valueelsevalue
            matchedRule =yesbreakthrownewError"unrecognized option: #{arg}"ifisOptionandnotmatchedRuleifseenNonOptionArgornotisOption
        options.arguments.push arg
    options

Return the help text for this OptionParser , listing and describing all of the valid options, for --help and such.

help:-\>lines = []
    lines.unshift"#{@banner}\n"if@bannerforrulein@rules
      spaces =15- rule.longFlag.length
      spaces =ifspaces >0thenrepeat' ', spaceselse''letPart =ifrule.shortFlagthenrule.shortFlag +', 'else' 'lines.push' '+ letPart + rule.longFlag + spaces + rule.description"\n#{ lines.join('\n') }\n"

Helpers

Regex matchers for option flags.

LONG_FLAG =/^(--\w[\w\-]\*)/SHORT_FLAG =/^(-\w)$/MULTI_FLAG =/^-(\w{2,})/OPTIONAL =/\[(\w+(\*?))\]/

Build and return the list of option rules. If the optional short-flag is unspecified, leave it out by padding with null.

buildRules = (rules) -\>fortupleinrules
    tuple.unshiftnulliftuple.length <3buildRule tuple...

Build a rule from a -o short flag, a --output [DIR] long flag, and the description of what the option does.

buildRule = (shortFlag, longFlag, description, options = {}) -\>match = longFlag.match(OPTIONAL)
  longFlag = longFlag.match(LONG_FLAG)[1]
  {
    name: longFlag.substr2shortFlag: shortFlag
    longFlag: longFlag
    description: description
    hasArgument: !!(matchandmatch[1])
    isList: !!(matchandmatch[2])
  }

Normalize arguments by expanding merged flags into multiple flags. This allows you to have -wl be the same as --watch --lint.

normalizeArguments = (args) -\>args = args[..]
  result = []forarginargsifmatch = arg.match MULTI_FLAG
      result.push'-'+ lforlinmatch[1].split''elseresult.push arg
  result