-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
/
Copy pathvalidateCLIOptions.ts
114 lines (103 loc) · 3.33 KB
/
validateCLIOptions.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {Config} from '@jest/types';
import chalk from 'chalk';
import camelcase from 'camelcase';
// eslint-disable-next-line import/no-extraneous-dependencies
import {Options} from 'yargs';
import {ValidationError, createDidYouMeanMessage, format} from './utils';
import {deprecationWarning} from './deprecated';
import defaultConfig from './defaultConfig';
import {DeprecatedOptions} from './types';
const BULLET: string = chalk.bold('\u25cf');
export const DOCUMENTATION_NOTE = ` ${chalk.bold('CLI Options Documentation:')}
https://jestjs.io/docs/en/cli.html
`;
const createCLIValidationError = (
unrecognizedOptions: Array<string>,
allowedOptions: Set<string>,
) => {
let title = `${BULLET} Unrecognized CLI Parameter`;
let message;
const comment =
` ${chalk.bold('CLI Options Documentation')}:\n` +
` https://jestjs.io/docs/en/cli.html\n`;
if (unrecognizedOptions.length === 1) {
const unrecognized = unrecognizedOptions[0];
const didYouMeanMessage = createDidYouMeanMessage(
unrecognized,
Array.from(allowedOptions),
);
message =
` Unrecognized option ${chalk.bold(format(unrecognized))}.` +
(didYouMeanMessage ? ` ${didYouMeanMessage}` : '');
} else {
title += 's';
message =
` Following options were not recognized:\n` +
` ${chalk.bold(format(unrecognizedOptions))}`;
}
return new ValidationError(title, message, comment);
};
const logDeprecatedOptions = (
deprecatedOptions: Array<string>,
deprecationEntries: DeprecatedOptions,
argv: Config.Argv,
) => {
deprecatedOptions.forEach(opt => {
deprecationWarning(argv, opt, deprecationEntries, {
...defaultConfig,
comment: DOCUMENTATION_NOTE,
});
});
};
export default function validateCLIOptions(
argv: Config.Argv,
options: {
deprecationEntries: DeprecatedOptions;
[s: string]: Options;
},
rawArgv: Array<string> = [],
) {
const yargsSpecialOptions = ['$0', '_', 'help', 'h'];
const deprecationEntries = options.deprecationEntries || {};
const allowedOptions = Object.keys(options).reduce(
(acc, option) =>
acc.add(option).add((options[option].alias as string) || option),
new Set(yargsSpecialOptions),
);
const unrecognizedOptions = Object.keys(argv).filter(
arg =>
!allowedOptions.has(camelcase(arg)) &&
(!rawArgv.length || rawArgv.includes(arg)),
[],
);
if (unrecognizedOptions.length) {
throw createCLIValidationError(unrecognizedOptions, allowedOptions);
}
const CLIDeprecations = Object.keys(deprecationEntries).reduce(
(acc, entry) => {
if (options[entry]) {
acc[entry] = deprecationEntries[entry];
const alias = options[entry].alias as string;
if (alias) {
acc[alias] = deprecationEntries[entry];
}
}
return acc;
},
{} as Record<string, Function>,
);
const deprecations = new Set(Object.keys(CLIDeprecations));
const deprecatedOptions = Object.keys(argv).filter(
arg => deprecations.has(arg) && argv[arg] != null,
);
if (deprecatedOptions.length) {
logDeprecatedOptions(deprecatedOptions, CLIDeprecations, argv);
}
return true;
}