Skip to content

Commit d03566b

Browse files
committed
Warn about obscured help option
1 parent 1bb30d7 commit d03566b

File tree

3 files changed

+43
-12
lines changed

3 files changed

+43
-12
lines changed

lib/command.js

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const { suggestSimilar } = require('./suggestSimilar');
1212

1313
// @ts-check
1414

15+
const PRODUCTION = process.env.NODE_ENV === 'production';
16+
1517
class Command extends EventEmitter {
1618
/**
1719
* Initialize a new `Command`.
@@ -521,6 +523,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
521523

522524
// register the option
523525
this.options.push(option);
526+
this._checkForObscuredHelpOption((matchingOptionFlags) => (
527+
`Help option '${this._helpOption.flags}' is obscured after adding option '${option.flags}'${matchingOptionFlags.length > 1
528+
? `
529+
- conflicts with options '${matchingOptionFlags.join("' and '")}'`
530+
: ''}`));
524531

525532
// handler for cli and env supplied values
526533
const handleOptionValue = (val, invalidValueMessage, valueSource) => {
@@ -1099,7 +1106,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
10991106
}
11001107

11011108
// Fallback to parsing the help flag to invoke the help.
1102-
return this._dispatchSubcommand(subcommandName, [], [this._helpLongFlag]);
1109+
return this._dispatchSubcommand(subcommandName, [], [this._helpOption.long]);
11031110
}
11041111

11051112
/**
@@ -2032,7 +2039,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
20322039
}
20332040
context.write(helpInformation);
20342041

2035-
this.emit(this._helpLongFlag); // deprecated
2042+
this.emit(this._helpOption.long); // deprecated
20362043
this.emit('afterHelp', context);
20372044
getCommandAndParents(this).forEach(command => command.emit('afterAllHelp', context));
20382045
}
@@ -2056,13 +2063,37 @@ Expecting one of '${allowedValues.join("', '")}'`);
20562063
this._helpFlags = flags = flags || this._helpFlags;
20572064
this._helpDescription = description = description || this._helpDescription;
20582065

2059-
const helpOption = this.createOption(flags, description);
2060-
this._helpShortFlag = helpOption.short;
2061-
this._helpLongFlag = helpOption.long;
2066+
this._helpOption = this.createOption(flags, description);
2067+
this._checkForObscuredHelpOption((matchingOptionFlags) => (
2068+
`Newly added help option '${this._helpOption.flags}' is obscured
2069+
- conflicts with ${matchingOptionFlags.length > 1 ? 'options' : 'option'} '${matchingOptionFlags.join("' and '")}'`));
20622070

20632071
return this;
20642072
}
20652073

2074+
/**
2075+
* @api private
2076+
*/
2077+
2078+
_checkForObscuredHelpOption(makeMessage) {
2079+
if (!PRODUCTION && this._hasHelpOption) {
2080+
const shortMatchingOption = this._helpOption.short &&
2081+
this._findOption(this._helpOption.short);
2082+
if (shortMatchingOption || !this._helpOption.short) {
2083+
const longMatchingOption = this._helpOption.long &&
2084+
this._findOption(this._helpOption.long);
2085+
if (longMatchingOption || !this._helpOption.long) {
2086+
const matchingOptionFlags = (
2087+
shortMatchingOption === longMatchingOption
2088+
? [shortMatchingOption]
2089+
: [shortMatchingOption, longMatchingOption]
2090+
).filter(option => option).map(option => option.flags);
2091+
console.warn(makeMessage(matchingOptionFlags));
2092+
}
2093+
}
2094+
}
2095+
}
2096+
20662097
/**
20672098
* Output help information and exit.
20682099
*
@@ -2123,7 +2154,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
21232154
*/
21242155

21252156
function outputHelpIfRequested(cmd, args) {
2126-
const helpOption = cmd._hasHelpOption && args.find(arg => arg === cmd._helpLongFlag || arg === cmd._helpShortFlag);
2157+
const helpOption = cmd._hasHelpOption && args.find(arg => arg === cmd._helpOption.long || arg === cmd._helpOption.short);
21272158
if (helpOption) {
21282159
cmd.outputHelp();
21292160
// (Do not have all displayed text available so only passing placeholder.)

lib/help.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ class Help {
7171
visibleOptions(cmd) {
7272
const visibleOptions = cmd.options.filter((option) => !option.hidden);
7373
// Implicit help
74-
const showShortHelpFlag = cmd._hasHelpOption && cmd._helpShortFlag && !cmd._findOption(cmd._helpShortFlag);
75-
const showLongHelpFlag = cmd._hasHelpOption && !cmd._findOption(cmd._helpLongFlag);
74+
const showShortHelpFlag = cmd._hasHelpOption && cmd._helpOption.short && !cmd._findOption(cmd._helpOption.short);
75+
const showLongHelpFlag = cmd._hasHelpOption && !cmd._findOption(cmd._helpOption.long);
7676
if (showShortHelpFlag || showLongHelpFlag) {
7777
let helpOption;
7878
if (!showShortHelpFlag) {
79-
helpOption = cmd.createOption(cmd._helpLongFlag, cmd._helpDescription);
79+
helpOption = cmd.createOption(cmd._helpOption.long, cmd._helpDescription);
8080
} else if (!showLongHelpFlag) {
81-
helpOption = cmd.createOption(cmd._helpShortFlag, cmd._helpDescription);
81+
helpOption = cmd.createOption(cmd._helpOption.short, cmd._helpDescription);
8282
} else {
8383
helpOption = cmd.createOption(cmd._helpFlags, cmd._helpDescription);
8484
}

tests/command.copySettings.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ describe('copyInheritedSettings property tests', () => {
4646
cmd.copyInheritedSettings(source);
4747
expect(cmd._helpFlags).toBe('-Z, --zz');
4848
expect(cmd._helpDescription).toBe('ddd');
49-
expect(cmd._helpShortFlag).toBe('-Z');
50-
expect(cmd._helpLongFlag).toBe('--zz');
49+
expect(cmd._helpOption.short).toBe('-Z');
50+
expect(cmd._helpOption.long).toBe('--zz');
5151
});
5252

5353
test('when copyInheritedSettings then copies addHelpCommand(name, description)', () => {

0 commit comments

Comments
 (0)