Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional summary for short form of subcommand description. #1726

Merged
merged 2 commits into from May 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 18 additions & 2 deletions Readme.md
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
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
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
@@ -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
@@ -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
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
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