Skip to content

Commit

Permalink
Add optional summary for short form of subcommand description. (#1726)
Browse files Browse the repository at this point in the history
For backwards compatibility, the description is used for the subcommand listing if the summary is missing. So by default there is no change in existing programs.
  • Loading branch information
shadowspawn authored May 18, 2022
1 parent d660967 commit cc2db5b
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 26 deletions.
20 changes: 18 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Read this in other languages: English | [简体中文](./Readme_zh-CN.md)
- [Display help from code](#display-help-from-code)
- [.name](#name)
- [.usage](#usage)
- [.description and .summary](#description-and-summary)
- [.helpOption(flags, description)](#helpoptionflags-description)
- [.addHelpCommand()](#addhelpcommand)
- [More configuration](#more-configuration-2)
Expand Down Expand Up @@ -814,10 +815,11 @@ error: unknown option '--unknown'
(add --help for additional information)
```

You can also show suggestions after an error for an unknown command or option.
The default behaviour is to suggest correct spelling after an error for an unknown command or option. You
can disable this.

```js
program.showSuggestionAfterError();
program.showSuggestionAfterError(false);
```

```console
Expand Down Expand Up @@ -866,6 +868,20 @@ The help will start with:
Usage: my-command [global options] command
```

### .description and .summary

The description appears in the help for the command. You can optionally supply a shorter
summary to use when listed as a subcommand of the program.

```js
program
.command("duplicate")
.summary("make a copy")
.description(`Make a copy of the current project.
This may require additional disk space.
`);
```

### .helpOption(flags, description)

By default every command has a help option. You may change the default help flags and description. Pass false to disable the built-in help option.
Expand Down
15 changes: 14 additions & 1 deletion lib/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Command extends EventEmitter {
this._aliases = [];
this._combineFlagAndOptionalValue = true;
this._description = '';
this._summary = '';
this._argsDescription = undefined; // legacy
this._enablePositionalOptions = false;
this._passThroughOptions = false;
Expand Down Expand Up @@ -1767,7 +1768,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
}

/**
* Set the description to `str`.
* Set the description.
*
* @param {string} [str]
* @param {Object} [argsDescription]
Expand All @@ -1782,6 +1783,18 @@ Expecting one of '${allowedValues.join("', '")}'`);
return this;
}

/**
* Set the summary. Used when listed as subcommand of parent.
*
* @param {string} [str]
* @return {string|Command}
*/
summary(str) {
if (str === undefined) return this._summary;
this._summary = str;
return this;
}

/**
* Set an alias for the command.
*
Expand Down
5 changes: 3 additions & 2 deletions lib/help.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,15 +215,16 @@ class Help {
}

/**
* Get the command description to show in the list of subcommands.
* Get the subcommand summary to show in the list of subcommands.
* (Fallback to description for backwards compatiblity.)
*
* @param {Command} cmd
* @returns {string}
*/

subcommandDescription(cmd) {
// @ts-ignore: overloaded return type
return cmd.description();
return cmd.summary() || cmd.description();
}

/**
Expand Down
8 changes: 8 additions & 0 deletions tests/command.summary.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const commander = require('../');

test('when set summary then get summary', () => {
const program = new commander.Command();
const summary = 'abcdef';
program.summary(summary);
expect(program.summary()).toMatch(summary);
});
20 changes: 0 additions & 20 deletions tests/help.commandDescription.test.js

This file was deleted.

37 changes: 37 additions & 0 deletions tests/help.subcommandDescription.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const commander = require('../');

// These are tests of the Help class, not of the Command help.
// There is some overlap with the higher level Command tests (which predate Help).

describe('subcommandDescription', () => {
test('when program has no summary or description then empty string', () => {
const program = new commander.Command();
const helper = new commander.Help();
expect(helper.subcommandDescription(program)).toEqual('');
});

test('when program has summary then return summary', () => {
const summary = 'summary';
const program = new commander.Command();
program.summary(summary);
const helper = new commander.Help();
expect(helper.subcommandDescription(program)).toEqual(summary);
});

test('when program has description then return description', () => {
const description = 'description';
const program = new commander.Command();
program.description(description);
const helper = new commander.Help();
expect(helper.subcommandDescription(program)).toEqual(description);
});

test('when program has summary and description then return summary', () => {
const summary = 'summary';
const program = new commander.Command();
program.summary(summary);
program.description('description');
const helper = new commander.Help();
expect(helper.subcommandDescription(program)).toEqual(summary);
});
});
14 changes: 13 additions & 1 deletion typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ export class Help {

/** Get the command term to show in the list of subcommands. */
subcommandTerm(cmd: Command): string;
/** Get the command description to show in the list of subcommands. */
/** Get the command summary to show in the list of subcommands. */
subcommandDescription(cmd: Command): string;
/** Get the option term to show in the list of options. */
optionTerm(option: Option): string;
Expand Down Expand Up @@ -718,6 +718,18 @@ export class Command {
*/
description(): string;

/**
* Set the summary. Used when listed as subcommand of parent.
*
* @returns `this` command for chaining
*/

summary(str: string): this;
/**
* Get the summary.
*/
summary(): string;

/**
* Set an alias for the command.
*
Expand Down
4 changes: 4 additions & 0 deletions typings/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ expectType<commander.Command>(program.description('my description'));
expectType<string>(program.description());
expectType<commander.Command>(program.description('my description of command with arg foo', { foo: 'foo description' })); // deprecated

// summary
expectType<commander.Command>(program.summary('my summary'));
expectType<string>(program.summary());

// alias
expectType<commander.Command>(program.alias('my alias'));
expectType<string>(program.alias());
Expand Down

0 comments on commit cc2db5b

Please sign in to comment.