You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							155 lines
						
					
					
						
							3.8 KiB
						
					
					
				
			
		
		
	
	
							155 lines
						
					
					
						
							3.8 KiB
						
					
					
				'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()}`; | 
						|
    } | 
						|
};
 | 
						|
 |