| 'use strict'; |
| |
| const |
| Q = require('q'), |
| |
| CoaParam = require('./coaparam'), |
| chalk = require('chalk'); |
| |
| /** |
| * Option |
| * |
| * Named entity. Options may have short and long keys for use from command line. |
| * |
| * @namespace |
| * @class Opt |
| * @extends CoaParam |
| */ |
| module.exports = class Opt extends CoaParam { |
| /** |
| * @constructs |
| * @param {COA.Cmd} cmd - parent command |
| */ |
| constructor(cmd) { |
| super(cmd); |
| |
| this._short = null; |
| this._long = null; |
| this._flag = false; |
| this._only = false; |
| this._cmd._opts.push(this); |
| } |
| |
| /** |
| * Set a short key for option to be used with one hyphen from command line. |
| * |
| * @param {String} short - short name |
| * @returns {COA.Opt} - this instance (for chainability) |
| */ |
| short(short) { |
| this._short = short; |
| this._cmd._optsByKey[`-${short}`] = this; |
| return this; |
| } |
| |
| /** |
| * Set a short key for option to be used with double hyphens from command line. |
| * |
| * @param {String} long - long name |
| * @returns {COA.Opt} - this instance (for chainability) |
| */ |
| long(long) { |
| this._long = long; |
| this._cmd._optsByKey[`--${long}`] = this; |
| return this; |
| } |
| |
| /** |
| * Make an option boolean, i.e. option without value. |
| * |
| * @returns {COA.Opt} - this instance (for chainability) |
| */ |
| flag() { |
| this._flag = true; |
| return this; |
| } |
| |
| /** |
| * Makes an option to act as a command, |
| * i.e. program will exit just after option action. |
| * |
| * @returns {COA.Opt} - this instance (for chainability) |
| */ |
| only() { |
| this._only = true; |
| return this; |
| } |
| |
| /** |
| * Add action for current option command. |
| * This action is performed if the current option |
| * is present in parsed options (with any value). |
| * |
| * @param {Function} act - action function, |
| * invoked in the context of command instance |
| * and has the parameters: |
| * - {Object} opts - parsed options |
| * - {Array} args - parsed arguments |
| * - {Object} res - actions result accumulator |
| * It can return rejected promise by Cmd.reject (in case of error) |
| * or any other value treated as result. |
| * @returns {COA.Opt} - this instance (for chainability) |
| */ |
| act(act) { |
| // Need function here for arguments |
| const opt = this; |
| this._cmd.act(function(opts) { |
| if(!opts.hasOwnProperty(opt._name)) return; |
| |
| const res = act.apply(this, arguments); |
| if(!opt._only) return res; |
| |
| return Q.when(res, out => this.reject({ |
| toString : () => out.toString(), |
| exitCode : 0 |
| })); |
| }); |
| |
| return this; |
| } |
| |
| _saveVal(opts, val) { |
| this._val && (val = this._val(val)); |
| |
| const name = this._name; |
| this._arr |
| ? (opts[name] || (opts[name] = [])).push(val) |
| : (opts[name] = val); |
| |
| return val; |
| } |
| |
| _parse(argv, opts) { |
| return this._saveVal(opts, this._flag ? true : argv.shift()); |
| } |
| |
| _checkParsed(opts) { |
| return !opts.hasOwnProperty(this._name); |
| } |
| |
| _usage() { |
| const res = [], |
| nameStr = this._name.toUpperCase(); |
| |
| if(this._short) { |
| res.push('-', chalk.greenBright(this._short)); |
| this._flag || res.push(' ' + nameStr); |
| res.push(', '); |
| } |
| |
| if(this._long) { |
| res.push('--', chalk.green(this._long)); |
| this._flag || res.push('=' + nameStr); |
| } |
| |
| res.push(' : ', this._title); |
| |
| this._req && res.push(' ', chalk.redBright('(required)')); |
| |
| return res.join(''); |
| } |
| |
| _requiredText() { |
| return `Missing required option:\n ${this._usage()}`; |
| } |
| }; |