From ca2d593badfb8b5884d42d2e36a7ba6fa5a540df Mon Sep 17 00:00:00 2001 From: Nitin Kumar <46647141+snitin315@users.noreply.github.com> Date: Fri, 26 Jun 2020 18:22:51 +0530 Subject: [PATCH] feat: allow multiple types for --stats --- .../webpack-cli/__tests__/arg-parser.test.js | 29 ++++++++- packages/webpack-cli/lib/groups/HelpGroup.js | 5 +- packages/webpack-cli/lib/groups/StatsGroup.js | 2 +- packages/webpack-cli/lib/utils/arg-parser.js | 9 ++- packages/webpack-cli/lib/utils/cli-flags.js | 2 +- test/stats/stats.test.js | 62 +++++++------------ test/stats/webpack.config.js | 4 ++ 7 files changed, 68 insertions(+), 45 deletions(-) diff --git a/packages/webpack-cli/__tests__/arg-parser.test.js b/packages/webpack-cli/__tests__/arg-parser.test.js index 141e5190c30..b1b5946140f 100644 --- a/packages/webpack-cli/__tests__/arg-parser.test.js +++ b/packages/webpack-cli/__tests__/arg-parser.test.js @@ -43,6 +43,12 @@ const basicOptions = [ description: 'string flag', defaultValue: 'default-value', }, + { + name: 'multi-type', + usage: '--multi-type | --multi-type ', + type: [String, Boolean], + description: 'flag with multiple types', + }, { name: 'custom-type-flag', usage: '--custom-type-flag ', @@ -127,6 +133,26 @@ describe('arg-parser', () => { expect(warnMock.mock.calls.length).toEqual(0); }); + it('parses multi type flag as Boolean', () => { + const res = argParser(basicOptions, ['--multi-type'], true); + expect(res.unknownArgs.length).toEqual(0); + expect(res.opts).toEqual({ + multiType: true, + stringFlagWithDefault: 'default-value', + }); + expect(warnMock.mock.calls.length).toEqual(0); + }); + + it('parses multi type flag as String', () => { + const res = argParser(basicOptions, ['--multi-type', 'value'], true); + expect(res.unknownArgs.length).toEqual(0); + expect(res.opts).toEqual({ + multiType: 'value', + stringFlagWithDefault: 'default-value', + }); + expect(warnMock.mock.calls.length).toEqual(0); + }); + it('warns on usage of both flag and same negated flag, setting it to false', () => { const res = argParser(basicOptions, ['--specific-bool', '--no-specific-bool'], true); expect(res.unknownArgs.length).toEqual(0); @@ -225,11 +251,12 @@ describe('arg-parser', () => { }); it('parses webpack args', () => { - const res = argParser(core, ['--entry', 'test.js', '--hot', '-o', './dist/'], true); + const res = argParser(core, ['--entry', 'test.js', '--hot', '-o', './dist/', '--stats'], true); expect(res.unknownArgs.length).toEqual(0); expect(res.opts.entry).toEqual(['test.js']); expect(res.opts.hot).toBeTruthy(); expect(res.opts.output).toEqual('./dist/'); + expect(res.opts.stats).toEqual(true); expect(warnMock.mock.calls.length).toEqual(0); }); }); diff --git a/packages/webpack-cli/lib/groups/HelpGroup.js b/packages/webpack-cli/lib/groups/HelpGroup.js index 57668874587..ff0272a142d 100644 --- a/packages/webpack-cli/lib/groups/HelpGroup.js +++ b/packages/webpack-cli/lib/groups/HelpGroup.js @@ -109,7 +109,10 @@ class HelpGroup { }, { header: 'Options', - optionList: options.core, + optionList: options.core.map((e) => { + if (e.type.length > 1) e.type = e.type[0]; + return e; + }), }, ]); return { diff --git a/packages/webpack-cli/lib/groups/StatsGroup.js b/packages/webpack-cli/lib/groups/StatsGroup.js index 65427ec1094..efd7536afa5 100644 --- a/packages/webpack-cli/lib/groups/StatsGroup.js +++ b/packages/webpack-cli/lib/groups/StatsGroup.js @@ -5,7 +5,7 @@ const logger = require('../utils/logger'); */ class StatsGroup extends GroupHelper { static validOptions() { - return ['none', 'errors-only', 'minimal', 'normal', 'detailed', 'verbose', 'errors-warnings']; + return ['none', 'errors-only', 'minimal', 'normal', 'detailed', 'verbose', 'errors-warnings', true]; } constructor(options) { diff --git a/packages/webpack-cli/lib/utils/arg-parser.js b/packages/webpack-cli/lib/utils/arg-parser.js index a6832f2011a..726d97e6061 100644 --- a/packages/webpack-cli/lib/utils/arg-parser.js +++ b/packages/webpack-cli/lib/utils/arg-parser.js @@ -37,7 +37,7 @@ function argParser(options, args, argsOnly = false, name = '', helpFunction = un // Register options on the parser options.reduce((parserInstance, option) => { const flags = option.alias ? `-${option.alias}, --${option.name}` : `--${option.name}`; - const flagsWithType = option.type !== Boolean ? flags + ' ' : flags; + let flagsWithType = option.type !== Boolean ? flags + ' ' : flags; if (option.type === Boolean || option.type === String) { if (!option.multiple) { parserInstance.option(flagsWithType, option.description, option.defaultValue); @@ -47,7 +47,12 @@ function argParser(options, args, argsOnly = false, name = '', helpFunction = un } } else { // in this case the type is a parsing function - parserInstance.option(flagsWithType, option.description, option.type, option.defaultValue); + if (option.type.length > 1) { + flagsWithType = flags + ' [value]'; + parserInstance.option(flagsWithType, option.description, option.type[0], option.defaultValue); + } else { + parserInstance.option(flagsWithType, option.description, option.type, option.defaultValue); + } } return parserInstance; diff --git a/packages/webpack-cli/lib/utils/cli-flags.js b/packages/webpack-cli/lib/utils/cli-flags.js index 3a95ec1474a..27906e6f0ef 100644 --- a/packages/webpack-cli/lib/utils/cli-flags.js +++ b/packages/webpack-cli/lib/utils/cli-flags.js @@ -240,7 +240,7 @@ module.exports = { { name: 'stats', usage: '--stats ', - type: String, + type: [String, Boolean], group: DISPLAY_GROUP, description: 'It instructs webpack on how to treat the stats e.g. verbose', link: 'https://webpack.js.org/configuration/stats/#stats', diff --git a/test/stats/stats.test.js b/test/stats/stats.test.js index 6b9c060accd..1f44d65ca77 100644 --- a/test/stats/stats.test.js +++ b/test/stats/stats.test.js @@ -1,48 +1,32 @@ 'use strict'; // eslint-disable-next-line node/no-unpublished-require const { run } = require('../utils/test-utils'); +// eslint-disable-next-line node/no-extraneous-require +const { version } = require('webpack'); -describe('stats flag', () => { - it('should accept stats "none"', () => { - const { stderr, stdout } = run(__dirname, ['--stats', 'none']); - expect(stderr).toBeFalsy(); - expect(stdout).toBeFalsy(); - }); - - it('should accept stats "errors-only"', () => { - const { stderr, stdout } = run(__dirname, ['--stats', 'errors-only']); - expect(stderr).toBeFalsy(); - expect(stdout).toBeFalsy(); - }); +const presets = ['normal', 'detailed', 'errors-only', 'errors-warnings', 'minimal', 'verbose', 'none']; - it('should accept stats "errors-warnings"', () => { - const { stderr, stdout } = run(__dirname, ['--stats', 'errors-warnings']); - expect(stderr).toBeFalsy(); - expect(stdout).toBeFalsy(); - }); - - it('should accept stats "normal"', () => { - const { stderr, stdout } = run(__dirname, ['--stats', 'normal']); - expect(stderr).toBeFalsy(); - expect(stdout).toBeTruthy(); - }); - - it('should accept stats "verbose"', () => { - const { stderr, stdout } = run(__dirname, ['--stats', 'verbose']); - expect(stderr).toBeFalsy(); - expect(stdout).toBeTruthy(); - }); - - it('should accept stats "minimal"', () => { - const { stderr, stdout } = run(__dirname, ['--stats', 'minimal']); - expect(stderr).toBeFalsy(); - expect(stdout).toBeTruthy(); - }); - - it('should accept stats "detailed"', () => { - const { stderr, stdout } = run(__dirname, ['--stats', 'detailed']); +describe('stats flag', () => { + for (const preset of presets) { + it(`should accept --stats "${preset}"`, () => { + const { stderr, stdout } = run(__dirname, ['--stats', `${preset}`]); + expect(stderr).toBeFalsy(); + if (version.startsWith('5')) { + expect(stdout).toContain(`stats: { preset: '${preset}' }`); + } else { + expect(stdout).toContain(`stats: '${preset}'`); + } + }); + } + + it('should accept stats as boolean', () => { + const { stderr, stdout } = run(__dirname, ['--stats']); expect(stderr).toBeFalsy(); - expect(stdout).toBeTruthy(); + if (version.startsWith('5')) { + expect(stdout).toContain(`stats: {}`); + } else { + expect(stdout).toContain('stats: true'); + } }); it('should warn when --verbose & --stats are passed together', () => { diff --git a/test/stats/webpack.config.js b/test/stats/webpack.config.js index c9a16c00fb4..57f4d3c6648 100644 --- a/test/stats/webpack.config.js +++ b/test/stats/webpack.config.js @@ -1,4 +1,8 @@ +// eslint-disable-next-line node/no-unpublished-require +const WebpackCLITestPlugin = require('../utils/webpack-cli-test-plugin'); + module.exports = { mode: 'development', entry: './index.js', + plugins: [new WebpackCLITestPlugin()], };