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

feat: show multiple suggestions on unknown options #2349

Merged
merged 1 commit into from Jan 13, 2021
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
21 changes: 0 additions & 21 deletions packages/webpack-cli/lib/utils/cli-flags.js
Expand Up @@ -23,30 +23,26 @@ const builtInFlags = [
// For configs
{
name: 'config',
usage: '--config <path-to-config> | --config <path-to-config> --config <path-to-config>',
alias: 'c',
type: String,
multiple: true,
description: 'Provide path to a webpack configuration file e.g. ./webpack.config.js.',
},
{
name: 'config-name',
usage: '--config-name <name-of-config> | --config-name <name-of-config> --config-name <name-of-config>',
type: String,
multiple: true,
description: 'Name of the configuration to use.',
},
{
name: 'merge',
usage: '--config <first-config> --config <second-config> --merge',
alias: 'm',
type: Boolean,
description: "Merge two or more configurations using 'webpack-merge'.",
},
// Complex configs
{
name: 'env',
usage: '--env <variable> | --env <variable> --env <variable=value>',
type: (value, previous = {}) => {
// This ensures we're only splitting by the first `=`
const [allKeys, val] = value.split(/=(.+)/, 2);
Expand Down Expand Up @@ -79,7 +75,6 @@ const builtInFlags = [
// Adding more plugins
{
name: 'hot',
usage: '--hot',
alias: 'h',
type: Boolean,
negative: true,
Expand All @@ -88,28 +83,24 @@ const builtInFlags = [
},
{
name: 'analyze',
usage: '--analyze',
type: Boolean,
multiple: false,
description: 'It invokes webpack-bundle-analyzer plugin to get bundle information.',
},
{
name: 'progress',
usage: '--progress | --progress profile',
type: [Boolean, String],
description: 'Print compilation progress during build.',
},
{
name: 'prefetch',
usage: '--prefetch <request>',
type: String,
description: 'Prefetch this request.',
},

// Output options
{
name: 'json',
usage: '--json | --json <path-to-stats-file>',
type: [String, Boolean],
alias: 'j',
description: 'Prints result as JSON or store it in a file.',
Expand All @@ -118,29 +109,25 @@ const builtInFlags = [
// For webpack@4
{
name: 'entry',
usage: '--entry <path-to-entry-file> | --entry <path> --entry <path>',
type: String,
multiple: true,
description: 'The entry point(s) of your application e.g. ./src/main.js.',
},
{
name: 'output-path',
usage: '--output-path <path-to-output-directory>',
alias: 'o',
type: String,
description: 'Output location of the file generated by webpack e.g. ./dist/.',
},
{
name: 'target',
usage: '--target <value> | --target <value> --target <value>',
alias: 't',
type: String,
multiple: cli !== undefined,
description: 'Sets the build target e.g. node.',
},
{
name: 'devtool',
usage: '--devtool <value>',
type: String,
negative: true,
alias: 'd',
Expand All @@ -149,27 +136,23 @@ const builtInFlags = [
},
{
name: 'mode',
usage: '--mode <development | production | none>',
type: String,
description: 'Defines the mode to pass to webpack.',
},
{
name: 'name',
usage: '--name',
type: String,
description: 'Name of the configuration. Used when loading multiple configurations.',
},
{
name: 'stats',
usage: '--stats | --stats <value>',
type: [String, Boolean],
negative: true,
description: 'It instructs webpack on how to treat the stats e.g. verbose.',
negatedDescription: 'Disable stats output.',
},
{
name: 'watch',
usage: '--watch',
type: Boolean,
negative: true,
alias: 'w',
Expand All @@ -178,7 +161,6 @@ const builtInFlags = [
},
{
name: 'watch-options-stdin',
usage: '--watch-options-stdin',
type: Boolean,
negative: true,
description: 'Stop watching when stdin stream has ended.',
Expand All @@ -192,14 +174,11 @@ const coreFlags = cli
? Object.entries(cli.getArguments()).map(([flag, meta]) => {
if (meta.simpleType === 'string') {
meta.type = String;
meta.usage = `--${flag} <value>`;
} else if (meta.simpleType === 'number') {
meta.type = Number;
meta.usage = `--${flag} <value>`;
} else {
meta.type = Boolean;
meta.negative = !flag.endsWith('-reset');
meta.usage = `--${flag}`;
}

const inBuiltIn = builtInFlags.find((builtInFlag) => builtInFlag.name === flag);
Expand Down
12 changes: 6 additions & 6 deletions packages/webpack-cli/lib/webpack-cli.js
Expand Up @@ -316,7 +316,7 @@ class WebpackCLI {
const loadCommandByName = async (commandName, allowToInstall = false) => {
if (commandName === bundleCommandOptions.name || commandName === bundleCommandOptions.alias) {
// Make `bundle|b [options]` command
this.makeCommand(bundleCommandOptions, this.getBuiltInOptions(), async (program) => {
await this.makeCommand(bundleCommandOptions, this.getBuiltInOptions(), async (program) => {
const options = program.opts();

if (program.args.length > 0) {
Expand Down Expand Up @@ -430,11 +430,11 @@ class WebpackCLI {
process.exit(2);
}

const found = command.options.find((option) => distance(name, option.long.slice(2)) < 3);

if (found) {
logger.error(`Did you mean '--${found.name()}'?`);
}
command.options.forEach((option) => {
if (distance(name, option.long.slice(2)) < 3) {
logger.error(`Did you mean '--${option.name()}'?`);
}
});
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions test/unknown/unknown.test.js
Expand Up @@ -144,6 +144,21 @@ describe('unknown behaviour', () => {
expect(stdout).toBeFalsy();
});

it('should log an error if an unknown flag is passed and suggests the closest match to an unknown flag #3', () => {
const { exitCode, stderr, stdout } = run(__dirname, ['--output-library-auxiliary-comment-commnjs']);

expect(exitCode).toBe(2);
expect(stderr).toContain("unknown option '--output-library-auxiliary-comment-commnjs'");

if (isWebpack5) {
expect(stderr).toContain("Did you mean '--output-library-auxiliary-comment-commonjs'?");
expect(stderr).toContain("Did you mean '--output-library-auxiliary-comment-commonjs2'?");
}

expect(stderr).toContain("Run 'webpack --help' to see available commands and options");
expect(stdout).toBeFalsy();
});

it('should log an error if an unknown flag is passed and suggests the closest match to an unknown flag using "bundle" command', () => {
const { exitCode, stderr, stdout } = run(__dirname, ['bundle', '--entyr', './a.js']);

Expand Down