Skip to content

Commit a27ff12

Browse files
weareoutmansindresorhus
andauthoredDec 25, 2020
Add allowUnknownFlags options (#169)
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
1 parent a0ce744 commit a27ff12

File tree

5 files changed

+78
-0
lines changed

5 files changed

+78
-0
lines changed
 

‎index.d.ts

+7
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,13 @@ declare namespace meow {
199199
@default true
200200
*/
201201
readonly hardRejection?: boolean;
202+
203+
/**
204+
Whether to allow unknown flags or not.
205+
206+
@default true
207+
*/
208+
readonly allowUnknownFlags?: boolean;
202209
}
203210

204211
type TypedFlag<Flag extends AnyFlag> =

‎index.js

+21
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ const reportMissingRequiredFlags = missingRequiredFlags => {
5454
}
5555
};
5656

57+
const reportUnknownFlags = unknownFlags => {
58+
console.error([
59+
`Unknown flag${unknownFlags.length > 1 ? 's' : ''}`,
60+
...unknownFlags
61+
].join('\n'));
62+
};
63+
5764
const buildParserFlags = ({flags, booleanDefault}) => {
5865
const parserFlags = {};
5966

@@ -110,6 +117,7 @@ const meow = (helpText, options) => {
110117
autoVersion: true,
111118
booleanDefault: false,
112119
hardRejection: true,
120+
allowUnknownFlags: true,
113121
...options
114122
};
115123

@@ -139,6 +147,11 @@ const meow = (helpText, options) => {
139147
parserOptions.configuration['populate--'] = true;
140148
}
141149

150+
if (!options.allowUnknownFlags) {
151+
// Collect unknown options in `argv._` to be checked later.
152+
parserOptions.configuration['unknown-options-as-args'] = true;
153+
}
154+
142155
const {pkg} = options;
143156
const argv = parseArguments(options.argv, parserOptions);
144157
let help = redent(trimNewlines((options.help || '').replace(/\t+\n*$/, '')), 2);
@@ -177,6 +190,14 @@ const meow = (helpText, options) => {
177190
const input = argv._;
178191
delete argv._;
179192

193+
if (!options.allowUnknownFlags) {
194+
const unknownFlags = input.filter(item => typeof item === 'string' && item.startsWith('-'));
195+
if (unknownFlags.length > 0) {
196+
reportUnknownFlags(unknownFlags);
197+
process.exit(2);
198+
}
199+
}
200+
180201
const flags = camelCaseKeys(argv, {exclude: ['--', /^\w$/]});
181202
const unnormalizedFlags = {...flags};
182203

‎readme.md

+7
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,13 @@ Default: `true`
314314
315315
Whether to use [`hard-rejection`](https://github.com/sindresorhus/hard-rejection) or not. Disabling this can be useful if you need to handle `process.on('unhandledRejection')` yourself.
316316
317+
#### allowUnknownFlags
318+
319+
Type `boolean`\
320+
Default: `true`
321+
322+
Whether to allow unknown flags or not.
323+
317324
## Promises
318325
319326
Meow will make unhandled rejected promises [fail hard](https://github.com/sindresorhus/hard-rejection) instead of the default silent fail. Meaning you don't have to manually `.catch()` promises used in your CLI.

‎test/allow-unkonwn-flags.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import path from 'path';
2+
import test from 'ava';
3+
import execa from 'execa';
4+
5+
const fixtureAllowUnknownFlags = path.join(__dirname, 'fixtures', 'fixture-allow-unknown-flags.js');
6+
7+
test('spawn CLI and test specifying unknown flags', async t => {
8+
const error = await t.throwsAsync(
9+
execa(fixtureAllowUnknownFlags, ['--foo', 'bar', '--unspecified-a', '--unspecified-b', 'input-is-allowed']),
10+
{
11+
message: /^Command failed with exit code 2/
12+
}
13+
);
14+
const {stderr} = error;
15+
t.regex(stderr, /Unknown flags/);
16+
t.regex(stderr, /--unspecified-a/);
17+
t.regex(stderr, /--unspecified-b/);
18+
t.notRegex(stderr, /input-is-allowed/);
19+
});
20+
21+
test('spawn CLI and test specifying known flags', async t => {
22+
const {stdout} = await execa(fixtureAllowUnknownFlags, ['--foo', 'bar']);
23+
t.is(stdout, 'bar');
24+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env node
2+
'use strict';
3+
const meow = require('../..');
4+
5+
const cli = meow({
6+
description: 'Custom description',
7+
help: `
8+
Usage
9+
foo <input>
10+
`,
11+
allowUnknownFlags: false,
12+
flags: {
13+
foo: {
14+
type: 'string'
15+
}
16+
}
17+
});
18+
19+
console.log(cli.flags.foo);

0 commit comments

Comments
 (0)
Please sign in to comment.