Skip to content

Commit

Permalink
Merge branch 'develop' into release/12.x
Browse files Browse the repository at this point in the history
  • Loading branch information
shadowspawn committed Oct 7, 2023
2 parents 5aaca0d + 03dea00 commit 72e6f7a
Show file tree
Hide file tree
Showing 15 changed files with 110 additions and 58 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const javascriptSettings = {
const typescriptSettings = {
files: ['*.ts', '*.mts'],
parserOptions: {
project: './tsconfig.json'
project: './tsconfig.ts.json'
},
plugins: [
'@typescript-eslint'
Expand Down
6 changes: 3 additions & 3 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ add cheese type mozzarella
Options with an optional option-argument are not greedy and will ignore arguments starting with a dash.
So `id` behaves as a boolean option for `--id -5`, but you can use a combined form if needed like `--id=-5`.

For information about possible ambiguous cases, see [options taking varying arguments](./docs/options-taking-varying-arguments.md).
For information about possible ambiguous cases, see [options taking varying arguments](./docs/options-in-depth.md).

### Required option

Expand Down Expand Up @@ -379,7 +379,7 @@ Options: { number: [ '1', '2', '3' ], letter: true }
Remaining arguments: [ 'operand' ]
```

For information about possible ambiguous cases, see [options taking varying arguments](./docs/options-taking-varying-arguments.md).
For information about possible ambiguous cases, see [options taking varying arguments](./docs/options-in-depth.md).

### Version option

Expand Down Expand Up @@ -1131,7 +1131,7 @@ program
There is more information available about:

- [deprecated](./docs/deprecated.md) features still supported for backwards compatibility
- [options taking varying arguments](./docs/options-taking-varying-arguments.md)
- [options taking varying arguments](./docs/options-in-depth.md)
- [parsing life cycle and hooks](./docs/parsing-and-hooks.md)

## Support
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Options taking varying numbers of option-arguments
<!-- omit from toc -->
# Options in Depth

The README covers declaring and using options, and mostly parsing will work the way you and your users expect. This page covers some special cases
and subtle issues in depth.
Expand All @@ -8,8 +9,10 @@ and subtle issues in depth.
- [Alternative: Make `--` part of your syntax](#alternative-make-----part-of-your-syntax)
- [Alternative: Put options last](#alternative-put-options-last)
- [Alternative: Use options instead of command-arguments](#alternative-use-options-instead-of-command-arguments)
- [Combining short options, and options taking arguments](#combining-short-options-and-options-taking-arguments)
- [Combining short options as if boolean](#combining-short-options-as-if-boolean)
- [Combining short options, and options taking arguments](#combining-short-options-and-options-taking-arguments)
- [Combining short options as if boolean](#combining-short-options-as-if-boolean)

## Options taking varying numbers of option-arguments

Certain options take a varying number of arguments:

Expand All @@ -20,11 +23,11 @@ program
.option('--test [name...]') // 0 or more
```

This page uses examples with options taking 0 or 1 arguments, but the discussions also apply to variadic options taking more arguments.
This section uses examples with options taking 0 or 1 arguments, but the discussions also apply to variadic options taking more arguments.

For information about terms used in this document see: [terminology](./terminology.md)

## Parsing ambiguity
### Parsing ambiguity

There is a potential downside to be aware of. If a command has both
command-arguments and options with varying option-arguments, this introduces a parsing ambiguity which may affect the user of your program.
Expand Down Expand Up @@ -73,7 +76,7 @@ ingredient: cheese

If you want to avoid your users needing to learn when to use `--`, there are a few approaches you could take.

### Alternative: Make `--` part of your syntax
#### Alternative: Make `--` part of your syntax

Rather than trying to teach your users what `--` does, you could just make it part of your syntax.

Expand All @@ -98,7 +101,7 @@ technique: scrambled
ingredient: cheese
```

### Alternative: Put options last
#### Alternative: Put options last

Commander follows the GNU convention for parsing and allows options before or after the command-arguments, or intermingled.
So by putting the options last, the command-arguments do not get confused with the option-arguments.
Expand All @@ -120,7 +123,7 @@ technique: scrambled
ingredient: cheese
```

### Alternative: Use options instead of command-arguments
#### Alternative: Use options instead of command-arguments

This is a bit more radical, but completely avoids the parsing ambiguity!

Expand Down Expand Up @@ -178,7 +181,7 @@ halal servings: v

If you wish to use options taking varying arguments as boolean options, you need to specify them separately.

```
```console
$ collect -a -v -l
any servings: true
vegan servings: true
Expand All @@ -190,7 +193,7 @@ halal servings: true
Before Commander v5, combining a short option and the value was not supported, and combined short flags were always expanded.
So `-avl` expanded to `-a -v -l`.

If you want backwards compatible behaviour, or prefer combining short options as booleans to combining short option and value,
If you want backwards compatible behaviour, or prefer combining short options as booleans to combining short option and value,
you may change the behavior.

To modify the parsing of options taking an optional value:
Expand Down
2 changes: 0 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ const { CommanderError, InvalidArgumentError } = require('./lib/error.js');
const { Help } = require('./lib/help.js');
const { Option } = require('./lib/option.js');

// @ts-check

exports.program = new Command();

exports.createCommand = (name) => new Command(name);
Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const config = {
testEnvironment: 'node',
collectCoverage: true,
transform: {
'^.+\\.tsx?$': 'ts-jest'
'^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.ts.json' }]
},
testPathIgnorePatterns: [
'/node_modules/'
Expand Down
2 changes: 0 additions & 2 deletions lib/argument.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
const { InvalidArgumentError } = require('./error.js');

// @ts-check

class Argument {
/**
* Initialize a new command argument with the given name and description.
Expand Down
8 changes: 3 additions & 5 deletions lib/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ const { Help } = require('./help.js');
const { Option, splitOptionFlags, DualOptions } = require('./option.js');
const { suggestSimilar } = require('./suggestSimilar');

// @ts-check

class Command extends EventEmitter {
/**
* Initialize a new `Command`.
Expand Down Expand Up @@ -763,9 +761,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
if (this.options.length) {
throw new Error('call .storeOptionsAsProperties() before adding options');
}
if (Object.keys(this._optionValues).length) {
throw new Error('call .storeOptionsAsProperties() before setting option values');
}
// if (Object.keys(this._optionValues).length) {
// throw new Error('call .storeOptionsAsProperties() before setting option values');
// }
this._storeOptionsAsProperties = !!storeAsProperties;
return this;
}
Expand Down
2 changes: 0 additions & 2 deletions lib/error.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// @ts-check

/**
* CommanderError class
* @class
Expand Down
2 changes: 0 additions & 2 deletions lib/help.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ const { humanReadableArgName } = require('./argument.js');
* @typedef { import("./option.js").Option } Option
*/

// @ts-check

// Although this is a class, methods are static in style to allow override using subclass or just functions.
class Help {
constructor() {
Expand Down
2 changes: 0 additions & 2 deletions lib/option.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
const { InvalidArgumentError } = require('./error.js');

// @ts-check

class Option {
/**
* Initialize a new `Option` with the given `flags` and `description`.
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
"lint": "npm run lint:javascript && npm run lint:typescript",
"lint:javascript": "eslint index.js esm.mjs \"lib/*.js\" \"tests/**/*.js\"",
"lint:typescript": "eslint typings/*.ts tests/*.ts",
"test": "jest && npm run test-typings",
"test": "jest && npm run typecheck-ts",
"test-esm": "node ./tests/esm-imports-test.mjs",
"test-typings": "tsd",
"typescript-checkJS": "tsc --allowJS --checkJS index.js lib/*.js --noEmit",
"test-all": "npm run test && npm run lint && npm run typescript-checkJS && npm run test-esm"
"typecheck-ts": "tsd && tsc -p tsconfig.ts.json",
"typecheck-js": "tsc -p tsconfig.js.json",
"test-all": "npm run test && npm run lint && npm run typecheck-js && npm run test-esm"
},
"files": [
"index.js",
Expand Down
14 changes: 7 additions & 7 deletions tests/commander.configureCommand.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ test('when storeOptionsAsProperties() after adding option then throw', () => {
}).toThrow();
});

test('when storeOptionsAsProperties() after setting option value then throw', () => {
const program = new commander.Command();
program.setOptionValue('foo', 'bar');
expect(() => {
program.storeOptionsAsProperties();
}).toThrow();
});
// test('when storeOptionsAsProperties() after setting option value then throw', () => {
// const program = new commander.Command();
// program.setOptionValue('foo', 'bar');
// expect(() => {
// program.storeOptionsAsProperties();
// }).toThrow();
// });
13 changes: 13 additions & 0 deletions tsconfig.js.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{ /*
Simple override including just JavaScript files.
Used by npm run-script typecheck-js
*/
/* Visit https://aka.ms/tsconfig to read more about tsconfig configuration. */
"extends": "./tsconfig.json",
"include": [
/* All JavaScript targets from tsconfig.json include. */
"*.js",
"*.mjs",
"lib/**/*.js"
],
}
62 changes: 45 additions & 17 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,47 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"types": [
"node",
"jest"
],
"esModuleInterop": true, // Mainly so can test an import problem which only occurs with this option on!
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"include": ["**/*.ts"],
/*
TypeScript is being used to do type checking across both JavaScript and TypeScript files.
In particular, this picks up some problems in the JSDoc in the JavaScript files, and validates the code
is consistent with the JSDoc.
The settings here are used by VSCode.
See also tsconfig.js.json and tsconfig.ts.json.
*/
/* Visit https://aka.ms/tsconfig to read more about tsconfig configuration. */
"compilerOptions": {
"lib": ["es2021"],
"module": "node16",
"target": "es2021",

"allowJs": true,
"checkJs": true,

/* Strict by default, but dial it down to reduce churn in our JavaScript code. */
"strict": true,
"noImplicitAny": false,
"strictNullChecks": false,
"useUnknownInCatchVariables": false,

"types": [
"node",
"jest"
],
"noEmit": true, /* just type checking and not emitting transpiled files */
"skipLibCheck": false, /* we want to check our hand crafted definitions */
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true /* common TypeScript config */
},
"include": [
/* JavaScript. Should match includes in tsconfig.js.json. */
"*.js",
"*.mjs",
"lib/**/*.js",
/* TypeScript. Should match includes in tsconfig.ts.json. */
"**/*.ts",
"**/*.mts"
],
"exclude": [
"node_modules"
]
}
20 changes: 20 additions & 0 deletions tsconfig.ts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{ /*
Override to include just TypeScript files and use stricter settings than we do with JavaScript.
Used by:
- npm run-script typecheck-ts
- eslint
*/
/* Visit https://aka.ms/tsconfig to read more about tsconfig configuration. */
"extends": "./tsconfig.json",
"compilerOptions": {
/* Full strict is fine for the TypeScript files, so turn back on the checks we turned off for mixed-use. */
"noImplicitAny": true,
"strictNullChecks": true,
"useUnknownInCatchVariables": true,
},
"include": [
/* All TypeScript targets from tsconfig.json include. */
"**/*.ts",
"**/*.mts"
],
}

0 comments on commit 72e6f7a

Please sign in to comment.