@@ -71,10 +71,9 @@ class Command extends EventEmitter {
71
71
this . _helpDescription = 'display help for command' ;
72
72
this . _helpShortFlag = '-h' ;
73
73
this . _helpLongFlag = '--help' ;
74
- this . _addImplicitHelpCommand = undefined ; // Deliberately undefined, not decided whether true or false
75
- this . _helpCommandName = 'help' ;
76
- this . _helpCommandnameAndArgs = 'help [command]' ;
77
- this . _helpCommandDescription = 'display help for command' ;
74
+ this . _addImplicitHelpCommand = undefined ; // undecided whether true or false yet, not inherited
75
+ /** @type {Command } */
76
+ this . _helpCommand = undefined ; // lazy initialised, inherited
78
77
this . _helpConfiguration = { } ;
79
78
}
80
79
@@ -93,9 +92,7 @@ class Command extends EventEmitter {
93
92
this . _helpDescription = sourceCommand . _helpDescription ;
94
93
this . _helpShortFlag = sourceCommand . _helpShortFlag ;
95
94
this . _helpLongFlag = sourceCommand . _helpLongFlag ;
96
- this . _helpCommandName = sourceCommand . _helpCommandName ;
97
- this . _helpCommandnameAndArgs = sourceCommand . _helpCommandnameAndArgs ;
98
- this . _helpCommandDescription = sourceCommand . _helpCommandDescription ;
95
+ this . _helpCommand = sourceCommand . _helpCommand ;
99
96
this . _helpConfiguration = sourceCommand . _helpConfiguration ;
100
97
this . _exitCallback = sourceCommand . _exitCallback ;
101
98
this . _storeOptionsAsProperties = sourceCommand . _storeOptionsAsProperties ;
@@ -369,39 +366,76 @@ class Command extends EventEmitter {
369
366
}
370
367
371
368
/**
372
- * Override default decision whether to add implicit help command.
369
+ * Customise or override default help command. By default a help command is automatically added if your command has subcommands .
373
370
*
374
- * addHelpCommand() // force on
375
- * addHelpCommand(false); // force off
376
- * addHelpCommand('help [cmd]', 'display help for [cmd]'); // force on with custom details
371
+ * program.helpCommand('help [cmd]');
372
+ * program.helpCommand('help [cmd]', 'show help');
373
+ * program.helpCommand(false); // suppress default help command
374
+ * program.helpCommand(true); // add help command even if no subcommands
377
375
*
376
+ * @param {string|boolean } enableOrNameAndArgs - enable with custom name and/or arguments, or boolean to override whether added
377
+ * @param {string } [description] - custom description
378
378
* @return {Command } `this` command for chaining
379
379
*/
380
380
381
- addHelpCommand ( enableOrNameAndArgs , description ) {
382
- if ( enableOrNameAndArgs === false ) {
383
- this . _addImplicitHelpCommand = false ;
384
- } else {
385
- this . _addImplicitHelpCommand = true ;
386
- if ( typeof enableOrNameAndArgs === 'string' ) {
387
- this . _helpCommandName = enableOrNameAndArgs . split ( ' ' ) [ 0 ] ;
388
- this . _helpCommandnameAndArgs = enableOrNameAndArgs ;
389
- }
390
- this . _helpCommandDescription = description || this . _helpCommandDescription ;
381
+ helpCommand ( enableOrNameAndArgs , description ) {
382
+ if ( typeof enableOrNameAndArgs === 'boolean' ) {
383
+ this . _addImplicitHelpCommand = enableOrNameAndArgs ;
384
+ return this ;
391
385
}
386
+
387
+ enableOrNameAndArgs = enableOrNameAndArgs ?? 'help [command]' ;
388
+ const [ , helpName , helpArgs ] = enableOrNameAndArgs . match ( / ( [ ^ ] + ) * ( .* ) / ) ;
389
+ const helpDescription = description ?? 'display help for command' ;
390
+
391
+ const helpCommand = this . createCommand ( helpName ) ;
392
+ helpCommand . helpOption ( false ) ;
393
+ if ( helpArgs ) helpCommand . arguments ( helpArgs ) ;
394
+ if ( helpDescription ) helpCommand . description ( helpDescription ) ;
395
+
396
+ this . _addImplicitHelpCommand = true ;
397
+ this . _helpCommand = helpCommand ;
398
+
392
399
return this ;
393
400
}
394
401
395
402
/**
396
- * @return {boolean }
397
- * @package internal use only
403
+ * Add prepared custom help command.
404
+ *
405
+ * @param {(Command|string|boolean) } helpCommand - custom help command, or deprecated enableOrNameAndArgs as for `.helpCommand()`
406
+ * @param {string } [deprecatedDescription] - deprecated custom description used with custom name only
407
+ * @return {Command } `this` command for chaining
398
408
*/
409
+ addHelpCommand ( helpCommand , deprecatedDescription ) {
410
+ // If not passed an object, call through to helpCommand for backwards compatibility,
411
+ // as addHelpCommand was originally used like helpCommand is now.
412
+ if ( typeof helpCommand !== 'object' ) {
413
+ this . helpCommand ( helpCommand , deprecatedDescription ) ;
414
+ return this ;
415
+ }
416
+
417
+ this . _addImplicitHelpCommand = true ;
418
+ this . _helpCommand = helpCommand ;
419
+ return this ;
420
+ }
399
421
400
- _hasImplicitHelpCommand ( ) {
401
- if ( this . _addImplicitHelpCommand === undefined ) {
402
- return this . commands . length && ! this . _actionHandler && ! this . _findCommand ( 'help' ) ;
422
+ /**
423
+ * Lazy create help command.
424
+ *
425
+ * @return {(Command|null) }
426
+ * @package
427
+ */
428
+ _getHelpCommand ( ) {
429
+ const hasImplicitHelpCommand = this . _addImplicitHelpCommand ??
430
+ ( this . commands . length && ! this . _actionHandler && ! this . _findCommand ( 'help' ) ) ;
431
+
432
+ if ( hasImplicitHelpCommand ) {
433
+ if ( this . _helpCommand === undefined ) {
434
+ this . helpCommand ( undefined , undefined ) ; // use default name and description
435
+ }
436
+ return this . _helpCommand ;
403
437
}
404
- return this . _addImplicitHelpCommand ;
438
+ return null ;
405
439
}
406
440
407
441
/**
@@ -1315,7 +1349,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1315
1349
if ( operands && this . _findCommand ( operands [ 0 ] ) ) {
1316
1350
return this . _dispatchSubcommand ( operands [ 0 ] , operands . slice ( 1 ) , unknown ) ;
1317
1351
}
1318
- if ( this . _hasImplicitHelpCommand ( ) && operands [ 0 ] === this . _helpCommandName ) {
1352
+ if ( this . _getHelpCommand ( ) && operands [ 0 ] === this . _getHelpCommand ( ) . name ( ) ) {
1319
1353
return this . _dispatchHelpCommand ( operands [ 1 ] ) ;
1320
1354
}
1321
1355
if ( this . _defaultCommandName ) {
@@ -1572,7 +1606,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1572
1606
operands . push ( arg ) ;
1573
1607
if ( args . length > 0 ) unknown . push ( ...args ) ;
1574
1608
break ;
1575
- } else if ( arg === this . _helpCommandName && this . _hasImplicitHelpCommand ( ) ) {
1609
+ } else if ( this . _getHelpCommand ( ) && arg === this . _getHelpCommand ( ) . name ( ) ) {
1576
1610
operands . push ( arg ) ;
1577
1611
if ( args . length > 0 ) operands . push ( ...args ) ;
1578
1612
break ;
0 commit comments