| /* |
| * Jake JavaScript build tool |
| * Copyright 2112 Matthew Eernisse (mde@fleegix.org) |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| var parseargs = {}; |
| |
| /** |
| * @constructor |
| * Parses a list of command-line args into a key/value object of |
| * options and an array of positional commands. |
| * @ param {Array} opts A list of options in the following format: |
| * [{full: 'foo', abbr: 'f'}, {full: 'bar', abbr: 'b'}]] |
| */ |
| parseargs.Parser = function (opts) { |
| // A key/value object of matching options parsed out of the args |
| this.opts = {}; |
| this.taskNames = null; |
| this.envVars = null; |
| |
| // Data structures used for parsing |
| this.reg = []; |
| this.shortOpts = {}; |
| this.longOpts = {}; |
| |
| var item; |
| for (var i = 0, ii = opts.length; i < ii; i++) { |
| item = opts[i]; |
| this.shortOpts[item.abbr] = item; |
| this.longOpts[item.full] = item; |
| } |
| this.reg = opts; |
| }; |
| |
| parseargs.Parser.prototype = new function () { |
| |
| var _trueOrNextVal = function (argParts, args) { |
| if (argParts[1]) { |
| return argParts[1]; |
| } |
| else { |
| return (!args[0] || (args[0].indexOf('-') == 0)) ? |
| true : args.shift(); |
| } |
| }; |
| |
| /** |
| * Parses an array of arguments into options and positional commands |
| * @param {Array} args The command-line args to parse |
| */ |
| this.parse = function (args) { |
| var cmds = [] |
| , cmd |
| , envVars = {} |
| , opts = {} |
| , arg |
| , argItem |
| , argParts |
| , cmdItems |
| , taskNames = [] |
| , preempt; |
| |
| while (args.length) { |
| arg = args.shift(); |
| |
| if (arg.indexOf('-') == 0) { |
| arg = arg.replace(/^--/, '').replace(/^-/, ''); |
| argParts = arg.split('='); |
| argItem = this.longOpts[argParts[0]] || this.shortOpts[argParts[0]]; |
| if (argItem) { |
| // First-encountered preemptive opt takes precedence -- no further opts |
| // or possibility of ambiguity, so just look for a value, or set to |
| // true and then bail |
| if (argItem.preempts) { |
| opts[argItem.full] = _trueOrNextVal(argParts, args); |
| preempt = true; |
| break; |
| } |
| // If the opt requires a value, see if we can get a value from the |
| // next arg, or infer true from no-arg -- if it's followed by another |
| // opt, throw an error |
| if (argItem.expectValue) { |
| opts[argItem.full] = _trueOrNextVal(argParts, args); |
| if (!opts[argItem.full]) { |
| throw new Error(argItem.full + ' option expects a value.'); |
| } |
| } |
| else { |
| opts[argItem.full] = true; |
| } |
| } |
| } |
| else { |
| cmds.unshift(arg); |
| } |
| } |
| |
| if (!preempt) { |
| // Parse out any env-vars and task-name |
| while (!!(cmd = cmds.pop())) { |
| cmdItems = cmd.split('='); |
| if (cmdItems.length > 1) { |
| envVars[cmdItems[0]] = cmdItems[1]; |
| } |
| else { |
| taskNames.push(cmd); |
| } |
| } |
| |
| } |
| |
| return { |
| opts: opts |
| , envVars: envVars |
| , taskNames: taskNames |
| }; |
| }; |
| |
| }; |
| |
| module.exports = parseargs; |