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

Rework default program name, and searching for subcommands #1571

Merged
merged 23 commits into from Aug 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
297224d
Simplify how default program name found. Just use args.
shadowspawn Jul 17, 2021
995afa6
Rework search for executable files
shadowspawn Jul 17, 2021
5136f8b
Adjust error messaging, still WIP
shadowspawn Jul 18, 2021
f3e8f47
Add executableDir and use searching for subcommands
shadowspawn Jul 18, 2021
2431626
Wording improvements
shadowspawn Jul 18, 2021
12aebd9
Add TypeScript for nameFromFilename
shadowspawn Jul 18, 2021
278053b
Add new tests for name (and nameFromFilename)
shadowspawn Jul 18, 2021
635c23e
Add TypeScript for executableDir
shadowspawn Jul 18, 2021
6620757
Start tests for subcommand search
shadowspawn Jul 18, 2021
9128aa3
Comment-out unused routine for lint, WIP
shadowspawn Jul 18, 2021
fe764fd
Refactor tests and skip launchable executable tests on Windows
shadowspawn Jul 18, 2021
2328564
Add notes on further tests
shadowspawn Jul 18, 2021
aa0ede4
Filling out mock executable tests
shadowspawn Jul 24, 2021
a46828d
Expand tests
shadowspawn Jul 26, 2021
597e894
Remove debugging and ToDo
shadowspawn Jul 26, 2021
ae39f4f
Relative and absolute test for executableDir
shadowspawn Jul 26, 2021
eab72f5
Avoid memory leak warning
shadowspawn Jul 26, 2021
48838f5
Fix relative search test
shadowspawn Jul 31, 2021
107f1f5
Separate and expand .name section in README.
shadowspawn Aug 1, 2021
3b38d2f
Add .name to multiple subcommand example
shadowspawn Aug 1, 2021
353248f
Update description of executable search.
shadowspawn Aug 1, 2021
f0c55b8
Merge branch 'develop' into feature/discovering-context
shadowspawn Aug 2, 2021
d10f87e
Add coverage of naming subcommands.
shadowspawn Aug 4, 2021
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
37 changes: 26 additions & 11 deletions Readme.md
Expand Up @@ -32,7 +32,8 @@ Read this in other languages: English | [简体中文](./Readme_zh-CN.md)
- [Custom help](#custom-help)
- [Display help after errors](#display-help-after-errors)
- [Display help from code](#display-help-from-code)
- [.usage and .name](#usage-and-name)
- [.name](#name)
- [.usage](#usage)
- [.helpOption(flags, description)](#helpoptionflags-description)
- [.addHelpCommand()](#addhelpcommand)
- [More configuration](#more-configuration-2)
Expand Down Expand Up @@ -66,15 +67,13 @@ This is used in the examples in this README for brevity.

```js
const { program } = require('commander');
program.version('0.0.1');
```

For larger programs which may use commander in multiple ways, including unit testing, it is better to create a local Command object to use.

```js
const { Command } = require('commander');
const program = new Command();
program.version('0.0.1');
```

For named imports in ECMAScript modules, import from `commander/esm.mjs`.
Expand All @@ -93,7 +92,6 @@ import { Command } from 'commander';
const program = new Command();
```


## Options

Options are defined with the `.option()` method, also serving as documentation for the options. Each option can have a short flag (single character) and a long name, separated by a comma or space or vertical bar ('|').
Expand Down Expand Up @@ -550,15 +548,17 @@ pass more arguments than declared, but you can make this an error with `.allowEx
### Stand-alone executable (sub)commands

When `.command()` is invoked with a description argument, this tells Commander that you're going to use stand-alone executables for subcommands.
Commander will search the executables in the directory of the entry script (like `./examples/pm`) with the name `program-subcommand`, like `pm-install`, `pm-search`.
You can specify a custom name with the `executableFile` configuration option.
Commander will search the files in the directory of the entry script for a file with the name combination `command-subcommand`, like `pm-install` or `pm-search` in the example below. The search includes trying common file extensions, like `.js`.
You may specify a custom name (and path) with the `executableFile` configuration option.
You may specify a custom search directory for subcommands with `.executableDir()`.

You handle the options for an executable (sub)command in the executable, and don't declare them at the top-level.

Example file: [pm](./examples/pm)

```js
program
.name('pm')
.version('0.1.0')
.command('install [name]', 'install one or more packages')
.command('search [query]', 'search with optional query')
Expand Down Expand Up @@ -696,10 +696,25 @@ error: unknown option '--unknown'

`.helpInformation()`: get the built-in command help information as a string for processing or displaying yourself.

### .usage and .name
### .name

These allow you to customise the usage description in the first line of the help. The name is otherwise
deduced from the (full) program arguments. Given:
The command name appears in the help, and is also used for locating stand-alone executable subcommands.

You may specify the program name using `.name()` or in the Command constructor. For the program, Commander will
fallback to using the script name from the full arguments passed into `.parse()`. However, the script name varies
depending on how your program is launched so you may wish to specify it explicitly.

```js
program.name('pizza');
const pm = new Command('pm');
```

Subcommands get a name when specified using `.command()`. If you create the subcommand yourself to use with `.addCommand()`,
then set the name using `.name()` or in the Command constructor.

### .usage

This allows you to customise the usage description in the first line of the help. Given:

```js
program
Expand All @@ -715,7 +730,7 @@ Usage: my-command [global options] command

### .helpOption(flags, description)

By default every command has a help option. Override the default help flags and description. Pass false to disable the built-in help option.
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.

```js
program
Expand Down Expand Up @@ -903,7 +918,6 @@ You can modify this behaviour for custom applications. In addition, you can modi

Example file: [configure-output.js](./examples/configure-output.js)


```js
function errorColor(str) {
// Add ANSI escape codes to display text in red.
Expand Down Expand Up @@ -960,6 +974,7 @@ const { Command } = require('commander');
const program = new Command();

program
.name('deploy')
.version('0.0.1')
.option('-c, --config <path>', 'set config path', './deploy.conf');

Expand Down
7 changes: 4 additions & 3 deletions Readme_zh-CN.md
Expand Up @@ -65,15 +65,13 @@ npm install commander

```js
const { program } = require('commander');
program.version('0.0.1');
```

如果程序较为复杂,用户需要以多种方式来使用 Commander,如单元测试等。创建本地`Command`对象是一种更好的方式:

```js
const { Command } = require('commander');
const program = new Command();
program.version('0.0.1');
```

要在 ECMAScript 模块中使用命名导入,可从`commander/esm.mjs`中导入。
Expand Down Expand Up @@ -270,6 +268,7 @@ $ collect --letter -n 1 -n 2 3 -- operand
Options: { number: [ '1', '2', '3' ], letter: true }
Remaining arguments: [ 'operand' ]
```

关于可能有歧义的用例,请见[可变参数的选项](./docs/zh-CN/%E5%8F%AF%E5%8F%98%E5%8F%82%E6%95%B0%E7%9A%84%E9%80%89%E9%A1%B9.md)。

### 版本选项
Expand Down Expand Up @@ -534,6 +533,7 @@ Commander 将会尝试在入口脚本(例如`./examples/pm`)的目录中搜

```js
program
.name('pm')
.version('0.1.0')
.command('install [name]', 'install one or more packages')
.command('search [query]', 'search with optional query')
Expand Down Expand Up @@ -708,6 +708,7 @@ program.addHelpCommand('assist [command]', 'show assistance');
内建帮助信息通过`Help`类进行格式化。如有需要,可以使用`.configureHelp()`来更改其数据属性和方法,或使用`.createHelp()`来创建子类,从而配置`Help`类的行为。

数据属性包括:

- `helpWidth`:指明帮助信息的宽度。可在单元测试中使用。
- `sortSubcommands`:以字母序排列子命令
- `sortOptions`:以字母序排列选项
Expand Down Expand Up @@ -862,7 +863,6 @@ Commander 默认用作命令行应用,其输出写入 stdout 和 stderr。

示例代码:[configure-output.js](./examples/configure-output.js)


```js
function errorColor(str) {
// 添加 ANSI 转义字符,以将文本输出为红色
Expand Down Expand Up @@ -919,6 +919,7 @@ const { Command } = require('commander');
const program = new Command();

program
.name('deploy')
.version('0.0.1')
.option('-c, --config <path>', 'set config path', './deploy.conf');

Expand Down
1 change: 1 addition & 0 deletions examples/deploy
Expand Up @@ -5,6 +5,7 @@ const { Command } = require('../'); // include commander in git clone of command
const program = new Command();

program
.name('deploy')
.version('0.0.1')
.option('-c, --config <path>', 'set config path', './deploy.conf');

Expand Down
1 change: 1 addition & 0 deletions examples/pm
Expand Up @@ -5,6 +5,7 @@ const { Command } = require('../'); // include commander in git clone of command
const program = new Command();

program
.name('pm')
.version('0.0.1')
.description('Fake package manager')
.command('install [name]', 'install one or more packages').alias('i')
Expand Down
2 changes: 1 addition & 1 deletion examples/pm-install
Expand Up @@ -17,7 +17,7 @@ if (!pkgs.length) {
}

console.log();
if (program.force) console.log(' force: install');
if (program.opts().force) console.log(' force: install');
pkgs.forEach(function(pkg) {
console.log(' install : %s', pkg);
});
Expand Down