* Add an option. * * @param {Option} option * @return {Command} `this` command for chaining
(option)
| 669 | * @return {Command} `this` command for chaining |
| 670 | */ |
| 671 | addOption(option) { |
| 672 | this._registerOption(option); |
| 673 | |
| 674 | const oname = option.name(); |
| 675 | const name = option.attributeName(); |
| 676 | |
| 677 | // store default value |
| 678 | if (option.defaultValue !== undefined) { |
| 679 | this.setOptionValueWithSource(name, option.defaultValue, 'default'); |
| 680 | } |
| 681 | |
| 682 | // handler for cli and env supplied values |
| 683 | const handleOptionValue = (val, invalidValueMessage, valueSource) => { |
| 684 | // val is null for optional option used without an optional-argument. |
| 685 | // val is undefined for boolean and negated option. |
| 686 | if (val == null && option.presetArg !== undefined) { |
| 687 | val = option.presetArg; |
| 688 | } |
| 689 | |
| 690 | // custom processing |
| 691 | const oldValue = this.getOptionValue(name); |
| 692 | if (val !== null && option.parseArg) { |
| 693 | val = this._callParseArg(option, val, oldValue, invalidValueMessage); |
| 694 | } else if (val !== null && option.variadic) { |
| 695 | val = option._collectValue(val, oldValue); |
| 696 | } |
| 697 | |
| 698 | // Fill-in appropriate missing values. Long winded but easy to follow. |
| 699 | if (val == null) { |
| 700 | if (option.negate) { |
| 701 | val = false; |
| 702 | } else if (option.isBoolean() || option.optional) { |
| 703 | val = true; |
| 704 | } else { |
| 705 | val = ''; // not normal, parseArg might have failed or be a mock function for testing |
| 706 | } |
| 707 | } |
| 708 | this.setOptionValueWithSource(name, val, valueSource); |
| 709 | }; |
| 710 | |
| 711 | this.on('option:' + oname, (val) => { |
| 712 | const invalidValueMessage = `error: option '${option.flags}' argument '${val}' is invalid.`; |
| 713 | handleOptionValue(val, invalidValueMessage, 'cli'); |
| 714 | }); |
| 715 | |
| 716 | if (option.envVar) { |
| 717 | this.on('optionEnv:' + oname, (val) => { |
| 718 | const invalidValueMessage = `error: option '${option.flags}' value '${val}' from env '${option.envVar}' is invalid.`; |
| 719 | handleOptionValue(val, invalidValueMessage, 'env'); |
| 720 | }); |
| 721 | } |
| 722 | |
| 723 | return this; |
| 724 | } |
| 725 | |
| 726 | /** |
| 727 | * Internal implementation shared by .option() and .requiredOption() |