From 487691abc8d817f5b3c1ab87743d7235ff15d956 Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Fri, 15 Jan 2021 17:17:54 +0300 Subject: [PATCH] feat: `configtest` validate default configuration (#2354) --- .eslintignore | 2 +- .prettierignore | 2 +- packages/configtest/src/index.ts | 27 ++++++++++++++++--- packages/webpack-cli/lib/webpack-cli.js | 4 +-- .../basic.config.js} | 0 .../{ => with-config-path}/error.config.js | 0 .../{ => with-config-path}/src/index.js | 0 .../syntax-error.config.js | 0 .../with-config-path.test.js} | 21 ++++++--------- .../webpack.config.json | 5 ++++ .../without-config-path.test.js | 16 +++++++++++ .../webpack.config.js | 5 ++++ .../without-config-path-error.test.js | 16 +++++++++++ .../webpack.config.js | 12 +++++++++ ...ut-config-path-multi-compiler-mode.test.js | 16 +++++++++++ ...thout-config-path-no-configuration.test.js | 13 +++++++++ .../without-config-path/webpack.config.js | 5 ++++ .../without-config-path.test.js | 16 +++++++++++ 18 files changed, 139 insertions(+), 21 deletions(-) rename test/configtest/{webpack.config.js => with-config-path/basic.config.js} (100%) rename test/configtest/{ => with-config-path}/error.config.js (100%) rename test/configtest/{ => with-config-path}/src/index.js (100%) rename test/configtest/{ => with-config-path}/syntax-error.config.js (100%) rename test/configtest/{configtest.test.js => with-config-path/with-config-path.test.js} (76%) create mode 100644 test/configtest/without-config-path-custom-extension/webpack.config.json create mode 100644 test/configtest/without-config-path-custom-extension/without-config-path.test.js create mode 100644 test/configtest/without-config-path-error/webpack.config.js create mode 100644 test/configtest/without-config-path-error/without-config-path-error.test.js create mode 100644 test/configtest/without-config-path-multi-compiler-mode/webpack.config.js create mode 100644 test/configtest/without-config-path-multi-compiler-mode/without-config-path-multi-compiler-mode.test.js create mode 100644 test/configtest/without-config-path-no-configuration/without-config-path-no-configuration.test.js create mode 100644 test/configtest/without-config-path/webpack.config.js create mode 100644 test/configtest/without-config-path/without-config-path.test.js diff --git a/.eslintignore b/.eslintignore index 97edf222a8a..acb5f4123c7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -10,4 +10,4 @@ test/typescript/webpack.config.ts test/config/error-commonjs/syntax-error.js test/config/error-mjs/syntax-error.mjs test/config/error-array/webpack.config.js -test/configtest/syntax-error.config.js +test/configtest/with-config-path/syntax-error.config.js diff --git a/.prettierignore b/.prettierignore index 86be5e4bc4f..c45e6482b38 100644 --- a/.prettierignore +++ b/.prettierignore @@ -10,4 +10,4 @@ test/config/error-mjs/syntax-error.mjs packages/webpack-cli/__tests__/test-assets/.yo-rc.json test/build-errors/stats.json packages/**/lib -test/configtest/syntax-error.config.js +test/configtest/with-config-path/syntax-error.config.js diff --git a/packages/configtest/src/index.ts b/packages/configtest/src/index.ts index 367404a0868..2a03fad1683 100644 --- a/packages/configtest/src/index.ts +++ b/packages/configtest/src/index.ts @@ -6,15 +6,34 @@ class ConfigTestCommand { await cli.makeCommand( { - name: 'configtest ', + name: 'configtest [config-path]', alias: 't', description: 'Tests webpack configuration against validation errors.', - usage: '', pkg: '@webpack-cli/configtest', }, [], - async (configPath: string): Promise => { - const config = await cli.resolveConfig({ config: [configPath] }); + async (configPath: string | undefined): Promise => { + const config = await cli.resolveConfig(configPath ? { config: [configPath] } : {}); + const configPaths = new Set(); + + if (Array.isArray(config.options)) { + config.options.forEach((options) => { + if (config.path.get(options)) { + configPaths.add(config.path.get(options)); + } + }); + } else { + if (config.path.get(config.options)) { + configPaths.add(config.path.get(config.options)); + } + } + + if (configPaths.size === 0) { + logger.error('No configuration found.'); + process.exit(2); + } + + logger.info(`Validate '${Array.from(configPaths).join(' ,')}'.`); try { // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/webpack-cli/lib/webpack-cli.js b/packages/webpack-cli/lib/webpack-cli.js index e3b1edb7ebe..e640f1ca053 100644 --- a/packages/webpack-cli/lib/webpack-cli.js +++ b/packages/webpack-cli/lib/webpack-cli.js @@ -277,7 +277,7 @@ class WebpackCLI { pkg: '@webpack-cli/migrate', }, { - name: 'configtest', + name: 'configtest [config-path]', alias: 't', pkg: '@webpack-cli/configtest', }, @@ -362,7 +362,7 @@ class WebpackCLI { } else { const builtInExternalCommandInfo = externalBuiltInCommandsInfo.find( (externalBuiltInCommandInfo) => - externalBuiltInCommandInfo.name === commandName || + getCommandName(externalBuiltInCommandInfo.name) === commandName || (typeof Array.isArray(externalBuiltInCommandInfo.alias) ? externalBuiltInCommandInfo.alias.includes(commandName) : externalBuiltInCommandInfo.alias === commandName), diff --git a/test/configtest/webpack.config.js b/test/configtest/with-config-path/basic.config.js similarity index 100% rename from test/configtest/webpack.config.js rename to test/configtest/with-config-path/basic.config.js diff --git a/test/configtest/error.config.js b/test/configtest/with-config-path/error.config.js similarity index 100% rename from test/configtest/error.config.js rename to test/configtest/with-config-path/error.config.js diff --git a/test/configtest/src/index.js b/test/configtest/with-config-path/src/index.js similarity index 100% rename from test/configtest/src/index.js rename to test/configtest/with-config-path/src/index.js diff --git a/test/configtest/syntax-error.config.js b/test/configtest/with-config-path/syntax-error.config.js similarity index 100% rename from test/configtest/syntax-error.config.js rename to test/configtest/with-config-path/syntax-error.config.js diff --git a/test/configtest/configtest.test.js b/test/configtest/with-config-path/with-config-path.test.js similarity index 76% rename from test/configtest/configtest.test.js rename to test/configtest/with-config-path/with-config-path.test.js index 8d88f8e62dc..2e4775868c0 100644 --- a/test/configtest/configtest.test.js +++ b/test/configtest/with-config-path/with-config-path.test.js @@ -1,13 +1,16 @@ 'use strict'; -const { run } = require('../utils/test-utils'); +const path = require('path'); -describe('basic info usage', () => { +const { run } = require('../../utils/test-utils'); + +describe("'configtest' command with the configuration path option", () => { it('should validate webpack config successfully', () => { - const { exitCode, stderr, stdout } = run(__dirname, ['configtest', './webpack.config.js'], false); + const { exitCode, stderr, stdout } = run(__dirname, ['configtest', './basic.config.js'], false); expect(exitCode).toBe(0); expect(stderr).toBeFalsy(); + expect(stdout).toContain(`Validate '${path.resolve(__dirname, 'basic.config.js')}'.`); expect(stdout).toContain('There are no validation errors in the given webpack configuration.'); }); @@ -17,7 +20,7 @@ describe('basic info usage', () => { expect(exitCode).toBe(2); expect(stderr).toContain('Invalid configuration object.'); expect(stderr).toContain('configuration.mode should be one of these:'); - expect(stdout).toBeFalsy(); + expect(stdout).toContain(`Validate '${path.resolve(__dirname, 'error.config.js')}'.`); }); it('should throw syntax error', () => { @@ -34,7 +37,7 @@ describe('basic info usage', () => { expect(exitCode).toBe(2); expect(stderr).toContain('Invalid configuration object.'); expect(stderr).toContain('configuration.mode should be one of these:'); - expect(stdout).toBeFalsy(); + expect(stdout).toContain(`Validate '${path.resolve(__dirname, 'error.config.js')}'.`); }); it('should throw error if configuration does not exist', () => { @@ -44,12 +47,4 @@ describe('basic info usage', () => { expect(stderr).toContain(`The specified config file doesn't exist`); expect(stdout).toBeFalsy(); }); - - it('should throw error if no configuration was provided', () => { - const { exitCode, stderr, stdout } = run(__dirname, ['configtest'], false); - - expect(exitCode).toBe(2); - expect(stderr).toContain(`error: missing required argument 'config-path'`); - expect(stdout).toBeFalsy(); - }); }); diff --git a/test/configtest/without-config-path-custom-extension/webpack.config.json b/test/configtest/without-config-path-custom-extension/webpack.config.json new file mode 100644 index 00000000000..821a4a55f7c --- /dev/null +++ b/test/configtest/without-config-path-custom-extension/webpack.config.json @@ -0,0 +1,5 @@ +{ + "mode": "development", + "target": "node", + "stats": "verbose" +} diff --git a/test/configtest/without-config-path-custom-extension/without-config-path.test.js b/test/configtest/without-config-path-custom-extension/without-config-path.test.js new file mode 100644 index 00000000000..f4c5218d134 --- /dev/null +++ b/test/configtest/without-config-path-custom-extension/without-config-path.test.js @@ -0,0 +1,16 @@ +'use strict'; + +const path = require('path'); + +const { run } = require('../../utils/test-utils'); + +describe("'configtest' command without the configuration path option", () => { + it.only('should validate default configuration', () => { + const { exitCode, stderr, stdout } = run(__dirname, ['configtest'], false); + + expect(exitCode).toBe(0); + expect(stderr).toBeFalsy(); + expect(stdout).toContain(`Validate '${path.resolve(__dirname, 'webpack.config.json')}'.`); + expect(stdout).toContain('There are no validation errors in the given webpack configuration.'); + }); +}); diff --git a/test/configtest/without-config-path-error/webpack.config.js b/test/configtest/without-config-path-error/webpack.config.js new file mode 100644 index 00000000000..5dbbd664f31 --- /dev/null +++ b/test/configtest/without-config-path-error/webpack.config.js @@ -0,0 +1,5 @@ +module.exports = { + mode: 'invalid', + target: 'node', + stats: 'verbose', +}; diff --git a/test/configtest/without-config-path-error/without-config-path-error.test.js b/test/configtest/without-config-path-error/without-config-path-error.test.js new file mode 100644 index 00000000000..1ddb9c1a3d4 --- /dev/null +++ b/test/configtest/without-config-path-error/without-config-path-error.test.js @@ -0,0 +1,16 @@ +'use strict'; + +const path = require('path'); + +const { run } = require('../../utils/test-utils'); + +describe("'configtest' command without the configuration path option", () => { + it.only('should validate default configuration', () => { + const { exitCode, stderr, stdout } = run(__dirname, ['configtest'], false); + + expect(exitCode).toBe(2); + expect(stderr).toContain('Invalid configuration object.'); + expect(stderr).toContain('configuration.mode should be one of these:'); + expect(stdout).toContain(`Validate '${path.resolve(__dirname, 'webpack.config.js')}'.`); + }); +}); diff --git a/test/configtest/without-config-path-multi-compiler-mode/webpack.config.js b/test/configtest/without-config-path-multi-compiler-mode/webpack.config.js new file mode 100644 index 00000000000..e198b8625cb --- /dev/null +++ b/test/configtest/without-config-path-multi-compiler-mode/webpack.config.js @@ -0,0 +1,12 @@ +module.exports = [ + { + mode: 'development', + target: 'node', + stats: 'verbose', + }, + { + mode: 'development', + target: 'node', + stats: 'verbose', + }, +]; diff --git a/test/configtest/without-config-path-multi-compiler-mode/without-config-path-multi-compiler-mode.test.js b/test/configtest/without-config-path-multi-compiler-mode/without-config-path-multi-compiler-mode.test.js new file mode 100644 index 00000000000..9a96a77506a --- /dev/null +++ b/test/configtest/without-config-path-multi-compiler-mode/without-config-path-multi-compiler-mode.test.js @@ -0,0 +1,16 @@ +'use strict'; + +const path = require('path'); + +const { run } = require('../../utils/test-utils'); + +describe("'configtest' command without the configuration path option", () => { + it.only('should validate default configuration', () => { + const { exitCode, stderr, stdout } = run(__dirname, ['configtest'], false); + + expect(exitCode).toBe(0); + expect(stderr).toBeFalsy(); + expect(stdout).toContain(`Validate '${path.resolve(__dirname, 'webpack.config.js')}'.`); + expect(stdout).toContain('There are no validation errors in the given webpack configuration.'); + }); +}); diff --git a/test/configtest/without-config-path-no-configuration/without-config-path-no-configuration.test.js b/test/configtest/without-config-path-no-configuration/without-config-path-no-configuration.test.js new file mode 100644 index 00000000000..167da4490fe --- /dev/null +++ b/test/configtest/without-config-path-no-configuration/without-config-path-no-configuration.test.js @@ -0,0 +1,13 @@ +'use strict'; + +const { run } = require('../../utils/test-utils'); + +describe("'configtest' command without the configuration path option", () => { + it.only('should validate default configuration', () => { + const { exitCode, stderr, stdout } = run(__dirname, ['configtest'], false); + + expect(exitCode).toBe(2); + expect(stderr).toContain('No configuration found.'); + expect(stdout).toBeFalsy(); + }); +}); diff --git a/test/configtest/without-config-path/webpack.config.js b/test/configtest/without-config-path/webpack.config.js new file mode 100644 index 00000000000..bdaebdb6f26 --- /dev/null +++ b/test/configtest/without-config-path/webpack.config.js @@ -0,0 +1,5 @@ +module.exports = { + mode: 'development', + target: 'node', + stats: 'verbose', +}; diff --git a/test/configtest/without-config-path/without-config-path.test.js b/test/configtest/without-config-path/without-config-path.test.js new file mode 100644 index 00000000000..9a96a77506a --- /dev/null +++ b/test/configtest/without-config-path/without-config-path.test.js @@ -0,0 +1,16 @@ +'use strict'; + +const path = require('path'); + +const { run } = require('../../utils/test-utils'); + +describe("'configtest' command without the configuration path option", () => { + it.only('should validate default configuration', () => { + const { exitCode, stderr, stdout } = run(__dirname, ['configtest'], false); + + expect(exitCode).toBe(0); + expect(stderr).toBeFalsy(); + expect(stdout).toContain(`Validate '${path.resolve(__dirname, 'webpack.config.js')}'.`); + expect(stdout).toContain('There are no validation errors in the given webpack configuration.'); + }); +});